/**
 * 📋 APPOINTMENT INTENT DETECTOR
 *
 * Reads the patient's WhatsApp reply (+ the destination node name) and
 * automatically updates the appointment / lead status to match.
 *
 * Called by BOTH the reminder-tree engine AND the canvas chatbot engine
 * whenever a patient replies so the clinic always sees the correct status.
 */

import { prisma } from "./db";

export type AppointmentIntent = "confirmed" | "cancelled" | "rescheduled" | null;

// ─── Keyword sets ────────────────────────────────────────────────
const CONFIRM_RESP = /^(yes|y|1|ok|okay|sure|confirm|confirmed|attend|attending|going|will|coming|i'll be there|i will be there|will be there|✅|👍|yep|yup|of course|absolutely|definitely)$/i;
const CONFIRM_PARTIAL = /\b(yes|confirm|attend|going|will come|i will|i'll come|i'll be|will be there|✅|👍)\b/i;

const CANCEL_RESP = /^(no|n|3|cancel|cancelled|cancel it|don't|dont|stop|quit|can't|cannot|won't|wont|❌|👎|nope|nah)$/i;
const CANCEL_PARTIAL = /\b(cancel|❌|can't make it|cannot make|won't be able|wont be)\b/i;

const RESCHEDULE_RESP = /^(2|reschedule|change|different time|another time|postpone|later|delay|move it)$/i;
const RESCHEDULE_PARTIAL = /\b(reschedule|change.*time|different.*time|another.*time|postpone|delay)\b/i;

// ─── Detect intent ────────────────────────────────────────────────
export function detectIntent(
  userResponse: string,
  nextNodeName: string | null = null
): AppointmentIntent {
  const resp = userResponse.trim();
  const node = (nextNodeName ?? "").toLowerCase();

  // 1. Check destination node name first (most reliable signal)
  if (/confirm|attendance|confirmed|all.good|will.be.there/i.test(node)) return "confirmed";
  if (/cancel/i.test(node)) return "cancelled";
  if (/reschedule|change.*time/i.test(node)) return "rescheduled";

  // 2. Check exact response match (strong signal)
  if (CONFIRM_RESP.test(resp))    return "confirmed";
  if (CANCEL_RESP.test(resp))     return "cancelled";
  if (RESCHEDULE_RESP.test(resp)) return "rescheduled";

  // 3. Check partial match for longer replies
  if (CONFIRM_PARTIAL.test(resp))    return "confirmed";
  if (CANCEL_PARTIAL.test(resp))     return "cancelled";
  if (RESCHEDULE_PARTIAL.test(resp)) return "rescheduled";

  return null;
}

// ─── Apply intent → update DB ────────────────────────────────────
export async function applyAppointmentIntent(
  appointmentId: string,
  intent: "confirmed" | "cancelled" | "rescheduled"
): Promise<void> {
  try {
    // Load current appointment
    const apt = await prisma.appointment.findUnique({
      where: { id: appointmentId },
      select: { id: true, status: true, leadId: true },
    });
    if (!apt) return;

    // Don't downgrade a terminal status
    const terminal = ["completed", "no_show", "arrived", "in_progress"];
    if (terminal.includes(apt.status)) return;

    // Build appointment update
    const aptUpdate: Record<string, unknown> = { status: intent };
    if (intent === "confirmed") aptUpdate.confirmedAt = new Date();

    await prisma.appointment.update({
      where: { id: appointmentId },
      data: aptUpdate,
    });

    // Sync lead status
    const leadStatusMap: Record<string, string> = {
      confirmed:   "confirmed",
      cancelled:   "cancelled",
      rescheduled: "rescheduled",
    };
    if (leadStatusMap[intent]) {
      await prisma.lead.update({
        where: { id: apt.leadId },
        data: { status: leadStatusMap[intent] },
      }).catch(() => {/* non-blocking */});
    }

    // Cancel pending reminders when appointment is cancelled
    if (intent === "cancelled") {
      await prisma.scheduledReminder.updateMany({
        where: { appointmentId, status: "pending" },
        data: { status: "skipped" },
      }).catch(() => {});
    }

    // Skip pre-appointment reminders when rescheduled
    if (intent === "rescheduled") {
      await prisma.scheduledReminder.updateMany({
        where: { appointmentId, status: "pending" },
        data: { status: "skipped" },
      }).catch(() => {});
    }

    console.log(`📋 Appointment ${appointmentId}: ${apt.status} → ${intent} (patient reply)`);
  } catch (err: any) {
    console.error(`❌ applyAppointmentIntent failed for ${appointmentId}:`, err.message);
  }
}
