import type { TreatmentCatalogEntry } from '@/types/treatment-catalog';
import type { TreatmentDetailDraft } from '@/types/treatment';

export type LabCaseTaskProgress = {
  completed: number;
  total: number;
};

type DetailLike = {
  id?: string;
  treatmentType: string;
  teeth: readonly string[];
  comment?: string;
  sentAt?: string | null;
  labCaseId?: string | null;
  taskProgress?: LabCaseTaskProgress | null;
};
export function isAppointmentOnlyPurpose(
  purpose: string | undefined,
  catalog: TreatmentCatalogEntry[],
): boolean {
  if (!purpose) return false;
  const entry = catalog.find((e) => e.code === purpose);
  return entry ? !entry.availableInTreatment : false;
}

/** Default detail type from appointment purpose — only when purpose is a real treatment type. */
export function defaultTreatmentTypeForAppointment(
  purpose: string | undefined,
  catalog: TreatmentCatalogEntry[],
): string | undefined {
  if (!purpose || isAppointmentOnlyPurpose(purpose, catalog)) {
    return undefined;
  }
  const treatmentOptions = catalog.filter((entry) => entry.availableInTreatment);
  if (treatmentOptions.some((entry) => entry.code === purpose)) {
    return purpose;
  }
  return undefined;
}

export function isDetailTypeSelected(detail: Pick<DetailLike, 'treatmentType'>): boolean {
  return Boolean(detail.treatmentType?.trim());
}

export function isEmptyDraftDetail(detail: TreatmentDetailDraft): boolean {
  return isBlankTreatmentDetail(detail);
}

/** Strip-card delete: no type, teeth, notes, or attachments — including an empty list. */
export function isBlankTreatmentDetail(detail: {
  treatmentType?: string | null;
  teeth?: readonly string[] | null;
  comment?: string | null;
  notes?: string | null;
  attachmentMetas?: readonly unknown[] | null;
}): boolean {
  return (
    !detail.treatmentType?.trim() &&
    (detail.teeth?.length ?? 0) === 0 &&
    !`${detail.comment ?? ''}${detail.notes ?? ''}`.trim() &&
    (detail.attachmentMetas?.length ?? 0) === 0
  );
}

export function areUnscheduledDetailsStripDeletable(
  details: readonly {
    treatmentType?: string | null;
    teeth?: readonly string[] | null;
    comment?: string | null;
    notes?: string | null;
    attachmentMetas?: readonly unknown[] | null;
  }[],
): boolean {
  return details.every(isBlankTreatmentDetail);
}

export function areDetailsPersistable(details: TreatmentDetailDraft[]): boolean {
  return details.every((d) => isDetailTypeSelected(d));
}

/** Lab dispatch UI applies only to persisted prosthesis lines with teeth and/or arch jobs. */
export function isDetailReadyForLabDispatch(
  detail: DetailLike,
  labDependentCodes: Set<string>,
  hasArchJobs = false,
): boolean {
  return (
    Boolean(detail.id) &&
    isDetailTypeSelected(detail) &&
    labDependentCodes.has(detail.treatmentType) &&
    (detail.teeth.length > 0 || hasArchJobs)
  );
}

export function isDetailEligibleForLabAttention(
  detail: DetailLike,
  labDependentCodes: Set<string>,
  isCurrentDraft: boolean,
  hasArchJobs = false,
): boolean {
  if (detail.sentAt || !isDetailTypeSelected(detail)) return false;
  if (!labDependentCodes.has(detail.treatmentType)) return false;
  if (detail.teeth.length === 0 && !hasArchJobs) return false;
  if (isCurrentDraft && !detail.id) return false;
  return true;
}

/** Saved lab-dependent line with no teeth and no arch jobs — can save, cannot ship. */
export function isLabDependentDetailMissingTeeth(
  detail: DetailLike,
  labDependentCodes: Set<string>,
  hasArchJobs = false,
): boolean {
  return (
    Boolean(detail.id) &&
    isDetailTypeSelected(detail) &&
    labDependentCodes.has(detail.treatmentType) &&
    detail.teeth.length === 0 &&
    !hasArchJobs &&
    !detail.sentAt
  );
}

export function isLabCaseCompleted(progress: LabCaseTaskProgress | null | undefined): boolean {
  if (!progress || progress.total <= 0) return false;
  return progress.completed >= progress.total;
}

/** Detail was sent to lab and the lab case still has open tasks. */
export function canCommentOnDetailLabCase(detail: DetailLike): boolean {
  if (!detail.sentAt || !detail.labCaseId) return false;
  return !isLabCaseCompleted(detail.taskProgress);
}
