import type { LabTaskListItem, TaskSortField } from '@/types/cases';

export type ProsthesisTaskGroup = {
  key: string;
  treatmentDetailId: string;
  prosthesisTypeCode: string;
  prosthesisTypeLabel: string;
  teeth: string[];
  tasks: LabTaskListItem[];
};

export type CaseTaskGroup = {
  labCaseId: string;
  clinic: LabTaskListItem['clinic'];
  patient: LabTaskListItem['patient'];
  caseSentAt: string | null;
  caseDueDate: string | null;
  isCaseOverdue: boolean;
  isImportant: boolean;
  origin?: 'CLINIC_DISPATCH' | 'LAB_INTERNAL';
  prosthesisGroups: ProsthesisTaskGroup[];
};

export type TaskDisplayModel =
  | { mode: 'grouped'; cases: CaseTaskGroup[] }
  | { mode: 'flat'; tasks: LabTaskListItem[] };

function prosthesisGroupKey(task: LabTaskListItem): string {
  return `${task.treatmentDetailId}:${task.teeth.join(',')}:${task.prosthesisTypeCode}`;
}

export function groupTasksForDisplay(
  tasks: LabTaskListItem[],
  sortBy: TaskSortField,
): TaskDisplayModel {
  if (sortBy !== 'date') {
    return { mode: 'flat', tasks };
  }

  const cases: CaseTaskGroup[] = [];
  const caseIndex = new Map<string, number>();

  for (const task of tasks) {
    let caseIdx = caseIndex.get(task.labCaseId);
    if (caseIdx === undefined) {
      caseIdx = cases.length;
      caseIndex.set(task.labCaseId, caseIdx);
      cases.push({
        labCaseId: task.labCaseId,
        clinic: task.clinic,
        patient: task.patient,
        caseSentAt: task.caseSentAt ?? null,
        caseDueDate: task.caseDueDate ?? null,
        isCaseOverdue: task.isCaseOverdue,
        isImportant: task.isImportant,
        origin: task.origin,
        prosthesisGroups: [],
      });
    }

    const caseGroup = cases[caseIdx];
    const pgKey = prosthesisGroupKey(task);
    let prosthesisGroup = caseGroup.prosthesisGroups.find((g) => g.key === pgKey);
    if (!prosthesisGroup) {
      prosthesisGroup = {
        key: pgKey,
        treatmentDetailId: task.treatmentDetailId,
        prosthesisTypeCode: task.prosthesisTypeCode,
        prosthesisTypeLabel: task.prosthesisTypeLabel,
        teeth: task.teeth,
        tasks: [],
      };
      caseGroup.prosthesisGroups.push(prosthesisGroup);
    }

    prosthesisGroup.tasks.push(task);
  }

  return { mode: 'grouped', cases };
}

export function countCaseTaskProgress(caseGroup: CaseTaskGroup): {
  completed: number;
  total: number;
} {
  let completed = 0;
  let total = 0;
  for (const group of caseGroup.prosthesisGroups) {
    for (const task of group.tasks) {
      total += 1;
      if (task.status === 'COMPLETED') completed += 1;
    }
  }
  return { completed, total };
}
