import type { LabCaseDetail } from '@/types/cases';
import type { CaseToothChartProsthesisRow } from '@/components/ui/lab/CaseToothChartPanel';
import { formatAppDateTime } from '@/lib/i18n/format';
import type { FdiToothId } from '@/types/treatment';

export function formatPatientName(patient: { firstName: string; lastName: string }) {
  return `${patient.firstName} ${patient.lastName}`.trim();
}

export function formatCaseDateTime(value: string | null, locale: string) {
  if (!value) return '—';
  return formatAppDateTime(value, locale, { dateStyle: 'medium', timeStyle: 'short' });
}

export function buildCaseProsthesisRows(labCase: LabCaseDetail): CaseToothChartProsthesisRow[] {
  if (labCase.toothProsthesis.length > 0) {
    const byKey = new Map<string, CaseToothChartProsthesisRow>();
    for (const row of labCase.toothProsthesis) {
      const selectionGroupId = row.selectionGroupId?.trim() || '';
      const key = `${selectionGroupId}::${row.prosthesisTypeCode}`;
      const existing = byKey.get(key);
      if (existing) {
        if (!existing.teeth.includes(row.tooth)) existing.teeth.push(row.tooth);
      } else {
        byKey.set(key, {
          prosthesisTypeCode: row.prosthesisTypeCode,
          teeth: [row.tooth],
          selectionGroupId: selectionGroupId || undefined,
          connected: Boolean(selectionGroupId),
        });
      }
    }
    return [...byKey.values()].map((row) => ({
      ...row,
      connected: Boolean(row.selectionGroupId) && row.teeth.length > 1,
    }));
  }
  return labCase.tasksByTooth.map((g) => ({
    prosthesisTypeCode: g.prosthesisTypeCode,
    teeth: g.teeth,
    selectionGroupId: g.selectionGroupId,
    connected: Boolean(g.connected ?? (g.selectionGroupId && g.teeth.length > 1)),
  }));
}

/** Teeth that belong to a multi-tooth connected bridge (for FDI chart dots). */
export function buildCaseConnectedTeeth(labCase: LabCaseDetail): Set<FdiToothId> {
  const set = new Set<FdiToothId>();
  const rows = buildCaseProsthesisRows(labCase);
  for (const row of rows) {
    if (!row.connected || row.teeth.length < 2) continue;
    for (const tooth of row.teeth) set.add(tooth as FdiToothId);
  }
  return set;
}

export function latestCaseAttachment(labCase: LabCaseDetail) {
  if (!labCase.attachments.length) return null;
  return [...labCase.attachments].sort(
    (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
  )[0];
}
