import { DatePipe } from '@angular/common';
import { Component, inject, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { ApiService, BookingDoc, BookingInfo, CancelQuote, QcInspection, StaffTask } from '../../core/api.service';
import { LangService } from '../../core/lang.service';

@Component({
  selector: 'app-booking-detail',
  standalone: true,
  imports: [FormsModule, DatePipe],
  template: `
    @if (info(); as b) {
      <div class="head fade-in">
        <div>
          <h1>{{ lang.t('booking') }} {{ b.booking.booking_no }}</h1>
          <p class="muted">
            {{ b.booking.event_date }} · {{ lang.money(b.booking.total) }}
            @if (b.booking.reschedule_count) { · <span class="muted">{{ lang.t('reschedule_booking') }} ×{{ b.booking.reschedule_count }}</span> }
          </p>
        </div>
        <span class="badge {{ statusBadge(b.booking.status) }}">{{ lang.t('st_' + b.booking.status) }}</span>
      </div>

      <!-- Lifecycle actions -->
      <div class="actions fade-in">
        @if (b.booking.status === 'tentative') {
          <button class="btn btn--gold" [disabled]="busy()" (click)="confirm(b.booking.id)">
            {{ busy() ? lang.t('processing') : lang.t('confirm_booking') }}
          </button>
        }
        @if (b.booking.status === 'confirmed') {
          <button class="btn btn--gold" [disabled]="busy()" (click)="contract(b.booking.id)">{{ lang.t('contract_booking') }}</button>
        }
        @if (b.booking.status === 'contracted') {
          <button class="btn btn--gold" [disabled]="busy()" (click)="complete(b.booking.id)">{{ lang.t('complete_booking') }}</button>
        }
        @if (canModify(b.booking.status)) {
          <button class="btn btn--ghost" (click)="openReschedule()">{{ lang.t('reschedule_booking') }}</button>
          <button class="btn btn--danger" (click)="openCancel()">{{ lang.t('cancel_booking') }}</button>
        }
        @if (b.booking.status === 'cancelled' && b.booking.refund_amount) {
          <span class="muted">{{ lang.t('refund_amount') }}: {{ lang.money(b.booking.refund_amount) }} · {{ lang.t('penalty_amount') }}: {{ lang.money(b.booking.penalty_amount || 0) }}</span>
        }
      </div>

      <div class="grid">
        <!-- Invoice / payments -->
        <div class="card card-pad fade-in">
          <h3>{{ lang.t('invoice') }}</h3>
          @if (b.booking.status === 'tentative') {
            <p class="muted">{{ lang.t('confirm_to_invoice') }}</p>
          } @else {
            <div class="kv"><span class="muted">{{ lang.t('invoice_no') }}</span><span>{{ b.invoice.invoice_no || '—' }}</span></div>
            <div class="kv"><span class="muted">{{ lang.t('total') }}</span><span>{{ lang.money(b.invoice.total) }}</span></div>
            <div class="kv"><span class="muted">{{ lang.t('paid') }}</span><span class="ok">{{ lang.money(b.invoice.paid) }}</span></div>
            <div class="kv"><span class="muted">{{ lang.t('due') }}</span><span class="due">{{ lang.money(b.invoice.due) }}</span></div>
            <div class="kv"><span class="muted">{{ lang.t('payment_status') }}</span><span class="badge {{ payBadge(b.invoice.status) }}">{{ b.invoice.status }}</span></div>

            @if (b.invoice.due > 0 && b.booking.status !== 'cancelled') {
              <h4 class="rp">{{ lang.t('record_payment') }}</h4>
              <div class="pay">
                <input type="number" min="1" [(ngModel)]="amount" [placeholder]="b.invoice.due" />
                <select [(ngModel)]="method">
                  <option value="cash">{{ lang.t('m_cash') }}</option>
                  <option value="bank_transfer">{{ lang.t('m_bank') }}</option>
                  <option value="card">{{ lang.t('m_card') }}</option>
                </select>
                <button class="btn btn--sm" [disabled]="busy() || !amount" (click)="pay(b.booking.id)">{{ lang.t('add_payment') }}</button>
              </div>
            }
          }
        </div>

        <!-- Payment schedule -->
        @if (b.schedule?.length) {
          <div class="card card-pad fade-in">
            <h3>{{ lang.t('payment_schedule') }}
              @if (b.deposit_met === false) { <span class="badge badge--new">{{ lang.t('deposit') }} ⌛</span> }
            </h3>
            @for (s of b.schedule; track s.id) {
              <div class="sched" [class.is-paid]="s.status === 'paid'">
                <div class="s-main">
                  <span class="s-label">{{ s.label }}</span>
                  <small class="muted">{{ s.due_date }} · {{ s.percent }}%</small>
                </div>
                <div class="s-amt">
                  <span>{{ lang.money(s.amount) }}</span>
                  <span class="badge {{ schedBadge(s.status) }}">{{ lang.t('ps_' + s.status) }}</span>
                </div>
              </div>
            }
          </div>
        }

        <!-- Documents -->
        @if (b.booking.status !== 'tentative') {
          <div class="card card-pad fade-in">
            <h3>{{ lang.t('documents') }}</h3>
            <div class="docgen">
              @for (dt of docTypes; track dt) {
                <button class="btn btn--ghost btn--sm" [disabled]="busy()" (click)="genDoc(dt)">+ {{ lang.t('doc_' + dt) }}</button>
              }
            </div>
            @if (docs().length) {
              @for (d of docs(); track d.id) {
                <div class="docrow">
                  <div>
                    <span class="t-title">{{ lang.t('doc_' + d.type) }}</span>
                    <small class="muted">v{{ d.version }}@if (d.accepted_at) { · <span class="ok">{{ lang.t('accepted') }}</span> }</small>
                  </div>
                  <span class="doc-langs">
                    <button class="btn btn--ghost btn--sm" (click)="openDoc(d, 'en')">EN</button>
                    <button class="btn btn--ghost btn--sm" (click)="openDoc(d, 'ar')">ع</button>
                  </span>
                </div>
              }
            } @else {
              <p class="muted">{{ lang.t('no_documents') }}</p>
            }
          </div>
        }

        <!-- Quality control -->
        @if (b.booking.status === 'confirmed' || b.booking.status === 'contracted' || b.booking.status === 'completed') {
          <div class="card card-pad fade-in">
            <h3>{{ lang.t('qc') }}
              @if (qc(); as q) { @if (q.status !== 'open') { <span class="badge {{ q.status === 'passed' ? 'badge--won' : 'badge--lost' }}">{{ lang.t('qc_' + q.status) }} · {{ q.score }}%</span> } }
            </h3>
            @if (qc(); as q) {
              @for (it of q.items; track $index) {
                <div class="qc-item">
                  <span class="qc-label">{{ lang.lang() === 'ar' && it.label_ar ? it.label_ar : it.label }}</span>
                  <div class="qc-opts">
                    @for (s of qcStates; track s) {
                      <button class="qc-opt {{ it.status === s ? 'on ' + s : '' }}" (click)="it.status = s">{{ lang.t('qc_' + s) }}</button>
                    }
                  </div>
                </div>
                @if (it.status === 'fail') {
                  <div class="qc-fail">
                    <select [(ngModel)]="it.reason_code">
                      <option [ngValue]="null">{{ lang.t('qc_reason') }}…</option>
                      @for (r of qcReasons(); track r.code) { <option [value]="r.code">{{ lang.lang() === 'ar' ? r.ar : r.en }}</option> }
                    </select>
                    <input [(ngModel)]="it.note" [placeholder]="lang.t('note_optional')" />
                  </div>
                }
              }
              <div class="qc-actions">
                <button class="btn btn--gold btn--sm" [disabled]="busy()" (click)="submitQc(q)">{{ lang.t('save_inspection') }}</button>
                @if (!recording()) {
                  <button class="btn btn--ghost btn--sm" (click)="startVoice(q)">🎙 {{ lang.t('record_voice') }}</button>
                } @else {
                  <button class="btn btn--danger btn--sm" (click)="stopVoice()">⏹ {{ lang.t('stop') }}</button>
                }
              </div>
              @if (q.events?.length) {
                <div class="qc-trail">
                  @for (e of q.events; track $index) {
                    <div class="qc-ev">
                      @if (e.type === 'voice') { 🎙 <audio controls [src]="e.detail" style="height:28px;vertical-align:middle"></audio> }
                      @else { <strong>{{ lang.t('qcev_' + e.type) }}</strong>@if (e.detail) { · {{ e.detail }} } }
                      @if (e.user) { · {{ e.user }} } <small class="muted">{{ e.at | date:'short' }}</small>
                    </div>
                  }
                </div>
              }
            } @else {
              <button class="btn btn--ghost btn--sm" (click)="loadQc()">{{ lang.t('start_inspection') }}</button>
            }
          </div>
        }

        <!-- Tasks -->
        <div class="card card-pad fade-in">
          <h3>{{ lang.t('tasks') }}</h3>
          @if (tasks().length) {
            @for (t of tasks(); track t.id) {
              <div class="task" [class.is-done]="t.status === 'done'">
                <div class="t-main">
                  <span class="dep">{{ t.department }}</span>
                  <span class="t-title">{{ t.title }}</span>
                  <small class="muted">{{ lang.t('due_label') }}: {{ t.due_at ? (t.due_at | date:'mediumDate') : '—' }}</small>
                </div>
                @if (t.status !== 'done') {
                  <button class="btn btn--ghost btn--sm" (click)="done(t)">{{ lang.t('mark_done') }}</button>
                } @else {
                  <span class="done-tick">✓</span>
                }
              </div>
            }
          } @else {
            <p class="muted">{{ lang.t('no_tasks') }}</p>
          }
        </div>
      </div>
    } @else if (loading()) {
      <p class="muted">{{ lang.t('loading') }}</p>
    }

    <!-- Cancel modal -->
    @if (showCancel()) {
      <div class="modal-bg" (click)="closeModals()">
        <div class="modal" (click)="$event.stopPropagation()">
          <h3>{{ lang.t('cancel_booking') }}</h3>
          @if (quote(); as q) {
            <div class="kv"><span class="muted">{{ lang.t('days_to_event') }}</span><span>{{ q.days_to_event }}</span></div>
            <div class="kv"><span class="muted">{{ lang.t('penalty_percent') }}</span><span>{{ q.penalty_percent }}%</span></div>
            <div class="kv"><span class="muted">{{ lang.t('penalty_amount') }}</span><span class="due">{{ lang.money(q.penalty_amount) }}</span></div>
            <div class="kv"><span class="muted">{{ lang.t('refund_amount') }}</span><span class="ok">{{ lang.money(q.refund_amount) }}</span></div>
          }
          <div class="field"><label>{{ lang.t('cancellation_reason') }}</label>
            <select [(ngModel)]="reasonCode">
              <option value="">—</option>
              @for (r of cancelReasons(); track r.code) { <option [value]="r.code">{{ lang.lang() === 'ar' ? r.ar : r.en }}</option> }
            </select>
          </div>
          <div class="field"><label>{{ lang.t('note_optional') }}</label><input [(ngModel)]="reason" /></div>
          @if (canOverride()) {
            <div class="field"><label>{{ lang.t('override_penalty') }}</label>
              <input type="number" min="0" max="100" [(ngModel)]="override" (ngModelChange)="refreshQuote('cancel')" placeholder="—" />
            </div>
          }
          <div class="modal-actions">
            <button class="btn btn--ghost" (click)="closeModals()">{{ lang.t('close') }}</button>
            <button class="btn btn--danger" [disabled]="busy()" (click)="doCancel()">{{ busy() ? lang.t('processing') : lang.t('cancel_booking') }}</button>
          </div>
        </div>
      </div>
    }

    <!-- Reschedule modal -->
    @if (showReschedule()) {
      <div class="modal-bg" (click)="closeModals()">
        <div class="modal" (click)="$event.stopPropagation()">
          <h3>{{ lang.t('reschedule_booking') }}</h3>
          <div class="field"><label>{{ lang.t('new_event_date') }}</label><input type="date" [min]="today" [(ngModel)]="newDate" /></div>
          @if (quote(); as q) {
            <div class="kv"><span class="muted">{{ lang.t('penalty_percent') }}</span><span>{{ q.penalty_percent }}%</span></div>
            <div class="kv"><span class="muted">{{ lang.t('rebooking_fee') }}</span><span class="due">{{ lang.money(q.penalty_amount) }}</span></div>
          }
          @if (canOverride()) {
            <div class="field"><label>{{ lang.t('override_penalty') }}</label>
              <input type="number" min="0" max="100" [(ngModel)]="override" (ngModelChange)="refreshQuote('reschedule')" placeholder="—" />
            </div>
          }
          <div class="modal-actions">
            <button class="btn btn--ghost" (click)="closeModals()">{{ lang.t('close') }}</button>
            <button class="btn btn--gold" [disabled]="busy() || !newDate" (click)="doReschedule()">{{ busy() ? lang.t('processing') : lang.t('reschedule_booking') }}</button>
          </div>
        </div>
      </div>
    }
  `,
  styles: [`
    .head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; margin-bottom: 16px; }
    .head h1 { margin-bottom: 4px; }
    .actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 22px; }
    .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 20px; align-items: start; }
    h3 { margin-bottom: 16px; }
    .kv { display: flex; justify-content: space-between; gap: 14px; padding: 9px 0; border-bottom: 1px dashed var(--line); }
    .kv:last-child { border-bottom: none; }
    .ok { color: var(--ok); font-weight: 600; }
    .due { font-weight: 600; }
    .rp { margin: 20px 0 12px; }
    .pay { display: flex; gap: 8px; }
    .pay input { flex: 1; padding: 9px 11px; border: 1px solid var(--line); border-radius: 8px; font-family: inherit; }
    .pay select { padding: 9px 11px; border: 1px solid var(--line); border-radius: 8px; font-family: inherit; background: #fff; }
    .sched { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 0; border-bottom: 1px dashed var(--line); }
    .sched:last-child { border-bottom: none; }
    .sched.is-paid .s-label { color: var(--ink-soft); }
    .s-main { display: flex; flex-direction: column; gap: 2px; }
    .s-label { font-weight: 600; }
    .s-amt { display: flex; align-items: center; gap: 10px; }
    .task { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 0; border-bottom: 1px dashed var(--line); }
    .task:last-child { border-bottom: none; }
    .task.is-done .t-title { text-decoration: line-through; color: var(--ink-soft); }
    .t-main { display: flex; flex-direction: column; gap: 2px; }
    .dep { font-size: .7rem; text-transform: uppercase; letter-spacing: .5px; color: var(--gold-deep); font-weight: 700; }
    .t-title { font-weight: 600; }
    .done-tick { color: var(--ok); font-size: 1.2rem; font-weight: 700; }
    .docgen { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
    .docrow { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px dashed var(--line); }
    .docrow:last-child { border-bottom: none; }
    .qc-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px dashed var(--line); }
    .qc-label { font-size: .9rem; flex: 1; }
    .qc-opts { display: flex; gap: 4px; }
    .qc-opt { border: 1px solid var(--line); background: #fff; border-radius: 7px; padding: 4px 9px; font-size: .76rem; cursor: pointer; font-family: inherit; color: var(--ink-soft); }
    .qc-opt.on.pass { background: #e7f5ec; color: #1d7a46; border-color: #b6e0c4; }
    .qc-opt.on.fail { background: #fde6e6; color: #b5281a; border-color: #f0bcbc; }
    .qc-opt.on.na { background: #efeae0; color: #777; }
    .qc-save { margin-top: 14px; }
    .qc-fail { display: flex; gap: 8px; padding: 0 0 9px 0; border-bottom: 1px dashed var(--line); }
    .qc-fail select, .qc-fail input { padding: 6px 9px; border: 1px solid var(--line); border-radius: 7px; font-family: inherit; font-size: .82rem; }
    .qc-fail input { flex: 1; }
    .qc-actions { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
    .qc-trail { margin-top: 12px; border-top: 1px dashed var(--line); padding-top: 8px; }
    .qc-ev { font-size: .82rem; padding: 4px 0; color: var(--ink-soft); }
    .btn--danger { background: var(--danger, #c0392b); color: #fff; }
    .modal-bg { position: fixed; inset: 0; background: rgba(20,16,12,.55); display: flex; align-items: center; justify-content: center; z-index: 50; padding: 20px; }
    .modal { background: var(--panel, #fff); border-radius: 14px; padding: 24px; width: min(440px, 100%); box-shadow: 0 20px 60px rgba(0,0,0,.3); }
    .field { margin-top: 14px; }
    .field label { display: block; font-size: .82rem; color: var(--ink-soft); margin-bottom: 5px; }
    .field input { width: 100%; padding: 9px 11px; border: 1px solid var(--line); border-radius: 8px; font-family: inherit; }
    .modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 22px; }
  `],
})
export class BookingDetailComponent {
  lang = inject(LangService);
  private api = inject(ApiService);
  private route = inject(ActivatedRoute);

  info = signal<BookingInfo | null>(null);
  tasks = signal<StaffTask[]>([]);
  docs = signal<BookingDoc[]>([]);
  docTypes = ['contract', 'beo', 'run_sheet'];
  qc = signal<QcInspection | null>(null);
  qcStates: ('pass' | 'fail' | 'na')[] = ['pass', 'fail', 'na'];
  qcReasons = signal<{ code: string; en: string; ar: string }[]>([]);
  recording = signal(false);
  private recorder: MediaRecorder | null = null;
  private chunks: Blob[] = [];
  loading = signal(true);
  busy = signal(false);
  amount: number | null = null;
  method = 'cash';

  showCancel = signal(false);
  showReschedule = signal(false);
  quote = signal<CancelQuote | null>(null);
  canOverride = signal(false);
  cancelReasons = signal<{ code: string; en: string; ar: string }[]>([]);
  reason = '';
  reasonCode = '';
  override: number | null = null;
  newDate = '';
  today = new Date().toISOString().slice(0, 10);

  private id = Number(this.route.snapshot.paramMap.get('id'));

  constructor() { this.reload(); }

  reload(): void {
    this.api.booking(this.id).subscribe({
      next: (r) => { this.info.set(r.data); this.loading.set(false); },
      error: () => this.loading.set(false),
    });
    this.api.bookingTasks(this.id).subscribe({ next: (r) => this.tasks.set(r.data.tasks), error: () => {} });
    this.api.bookingDocuments(this.id).subscribe({ next: (r) => this.docs.set(r.data.documents), error: () => {} });
  }

  genDoc(type: string): void {
    this.busy.set(true);
    this.api.generateDocument(this.id, type).subscribe({
      next: () => { this.busy.set(false); this.api.bookingDocuments(this.id).subscribe({ next: (r) => this.docs.set(r.data.documents) }); },
      error: (e) => { this.busy.set(false); alert(e?.error?.message || 'Error'); },
    });
  }

  openDoc(d: BookingDoc, lang?: string): void {
    this.api.downloadDocument(d.id, lang).subscribe({
      next: (blob) => { window.open(URL.createObjectURL(blob), '_blank'); },
      error: () => {},
    });
  }

  loadQc(): void {
    this.api.qcInspection(this.id).subscribe({
      next: (r) => { this.qc.set(r.data.inspection); this.qcReasons.set(r.data.reasons || []); },
      error: () => {},
    });
  }
  submitQc(q: QcInspection): void {
    this.busy.set(true);
    this.api.qcSubmit(q.id, q.items).subscribe({
      next: (r) => { this.qc.set(r.data.inspection); this.busy.set(false); },
      error: (e) => { this.busy.set(false); alert(e?.error?.message || 'Error'); },
    });
  }

  /** Record a voice note (MediaRecorder) → upload to the inspection. */
  async startVoice(q: QcInspection): Promise<void> {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      this.chunks = [];
      this.recorder = new MediaRecorder(stream);
      this.recorder.ondataavailable = (e) => { if (e.data.size) { this.chunks.push(e.data); } };
      this.recorder.onstop = () => {
        stream.getTracks().forEach((t) => t.stop());
        const blob = new Blob(this.chunks, { type: 'audio/webm' });
        this.api.qcVoice(q.id, blob).subscribe({ next: (r) => this.qc.set(r.data.inspection), error: () => {} });
      };
      this.recorder.start();
      this.recording.set(true);
    } catch {
      alert(this.lang.t('mic_denied'));
    }
  }
  stopVoice(): void {
    this.recorder?.stop();
    this.recording.set(false);
  }

  canModify(status: string): boolean {
    return status === 'confirmed' || status === 'contracted';
  }

  confirm(id: number): void { this.act(this.api.confirmBooking(id)); }
  contract(id: number): void { this.act(this.api.contractBooking(id)); }
  complete(id: number): void { this.act(this.api.completeBooking(id)); }

  private act(obs: any): void {
    this.busy.set(true);
    obs.subscribe({
      next: (r: any) => { this.info.set(r.data); this.busy.set(false); this.reload(); },
      error: (e: any) => { this.busy.set(false); alert(e?.error?.message || 'Error'); },
    });
  }

  pay(id: number): void {
    if (!this.amount) return;
    this.busy.set(true);
    this.api.recordPayment(id, { amount: this.amount, method: this.method }).subscribe({
      next: (r) => { this.info.set(r.data); this.amount = null; this.busy.set(false); },
      error: () => this.busy.set(false),
    });
  }

  done(t: StaffTask): void {
    this.api.completeTask(t.id).subscribe({ next: () => { t.status = 'done'; this.tasks.set([...this.tasks()]); }, error: () => {} });
  }

  openCancel(): void { this.resetModal(); this.showCancel.set(true); this.refreshQuote('cancel'); }
  openReschedule(): void { this.resetModal(); this.showReschedule.set(true); this.refreshQuote('reschedule'); }
  closeModals(): void { this.showCancel.set(false); this.showReschedule.set(false); }
  private resetModal(): void { this.reason = ''; this.reasonCode = ''; this.override = null; this.newDate = ''; this.quote.set(null); }

  refreshQuote(kind: 'cancel' | 'reschedule'): void {
    const ov = this.override != null && this.override !== ('' as any) ? Number(this.override) : undefined;
    const obs = kind === 'cancel' ? this.api.cancelQuote(this.id, ov) : this.api.rescheduleQuote(this.id, ov);
    obs.subscribe({ next: (r) => { this.quote.set(r.data.quote); this.canOverride.set(r.data.can_override); if (r.data.reasons) { this.cancelReasons.set(r.data.reasons); } }, error: () => {} });
  }

  doCancel(): void {
    this.busy.set(true);
    const ov = this.override != null && this.override !== ('' as any) ? Number(this.override) : undefined;
    this.api.cancelBooking(this.id, { reason: this.reason || undefined, reason_code: this.reasonCode || undefined, override_penalty_percent: ov }).subscribe({
      next: (r) => { this.info.set(r.data); this.busy.set(false); this.closeModals(); this.reload(); },
      error: (e) => { this.busy.set(false); alert(e?.error?.message || 'Error'); },
    });
  }

  doReschedule(): void {
    if (!this.newDate) return;
    this.busy.set(true);
    const ov = this.override != null && this.override !== ('' as any) ? Number(this.override) : undefined;
    this.api.rescheduleBooking(this.id, { event_date: this.newDate, override_penalty_percent: ov }).subscribe({
      next: (r) => { this.info.set(r.data); this.busy.set(false); this.closeModals(); this.reload(); },
      error: (e) => { this.busy.set(false); alert(e?.error?.message || 'Error'); },
    });
  }

  statusBadge(s: string): string {
    return ({ confirmed: 'badge--won', contracted: 'badge--won', completed: 'badge--won',
      tentative: 'badge--warm', cancelled: 'badge--lost' } as Record<string, string>)[s] || 'badge--new';
  }
  payBadge(status: string): string {
    return status === 'paid' ? 'badge--won' : (status === 'partial' ? 'badge--warm' : 'badge--new');
  }
  schedBadge(status: string): string {
    return ({ paid: 'badge--won', partial: 'badge--warm', overdue: 'badge--lost', cancelled: 'badge--lost' } as Record<string, string>)[status] || 'badge--new';
  }
}
