import type {
  AppointmentRef,
  PatientVerificationInput,
  PatientVerificationResult,
  RescheduleSlot,
} from "./types.ts";

function digitsOnly(value: string): string {
  return value.replace(/\D/g, "");
}

function normalizePhone(value: string): string {
  const digits = digitsOnly(value);
  return digits.length === 11 && digits.startsWith("1") ? digits.slice(1) : digits;
}

function normalizeName(value: string): string {
  return value
    .toLowerCase()
    .replace(/[^a-z0-9 ]/g, " ")
    .replace(/\s+/g, " ")
    .trim();
}

export function verifyPatientIdentity(
  input: PatientVerificationInput,
): PatientVerificationResult {
  if (input.candidates.length === 0) return { ok: false, reason: "no_candidates" };

  const caller = normalizePhone(input.callerNumber);
  const phoneMatches = input.candidates.filter((candidate) =>
    candidate.phones.map(normalizePhone).includes(caller),
  );

  if (input.candidates.length > 1 && phoneMatches.length === 0) {
    return { ok: false, reason: "phone_mismatch" };
  }

  if (phoneMatches.length > 1) {
    return { ok: false, reason: "multiple_candidates" };
  }

  const candidate = phoneMatches[0] ?? input.candidates[0]!;
  const candidatePhones = candidate.phones.map(normalizePhone);
  if (!candidatePhones.includes(caller)) {
    return { ok: false, reason: "phone_mismatch" };
  }

  if (candidate.dob !== input.statedDob) {
    return { ok: false, reason: "dob_mismatch" };
  }

  if (normalizeName(candidate.legalName) !== normalizeName(input.statedLegalName)) {
    return { ok: false, reason: "name_mismatch" };
  }

  return {
    ok: true,
    patient: { patientId: candidate.patientId, legalName: candidate.legalName },
  };
}

export function isSameServiceSameProviderSlot(
  appointment: AppointmentRef,
  slot: RescheduleSlot,
): boolean {
  return (
    appointment.providerId === slot.providerId &&
    appointment.serviceCode === slot.serviceCode
  );
}

export function isSameDayAppointment(appointment: AppointmentRef, now = new Date()): boolean {
  const apptDate = appointment.startsAt.slice(0, 10);
  const nowDate = now.toISOString().slice(0, 10);
  return apptDate === nowDate;
}

export const ESCALATION_LANGUAGE = [
  "chest pain",
  "shortness of breath",
  "suicidal",
  "emergency",
  "urgent",
  "controlled substance",
  "refill",
  "insurance",
  "billing",
  "guardian",
] as const;

export function shouldEscalateForLanguage(text: string): boolean {
  const lower = text.toLowerCase();
  return ESCALATION_LANGUAGE.some((phrase) => lower.includes(phrase));
}
