import { prisma } from "./db";
import { sendMessage, sendButtons, type WaButton } from "./waha";
import { getPhoneSuffix, normalizePhone } from "./phone";

/**
 * CLINERA WhatsApp Chatbot v2 — 19 Upgrades
 *
 * 1.  ⏱️  Rate limiting — prevent spam/duplicate replies
 * 2.  🌍  Time-aware greetings (Good morning/afternoon/evening)
 * 3.  🗓️  Show multiple appointments if patient has several
 * 4.  📝  Auto-create lead from unknown numbers
 * 5.  ⏳  Countdown format ("in 3 days", "tomorrow at 2pm")
 * 6.  🔄  Reschedule confirmation before cancelling old one
 * 7.  📊  Patient history awareness (completed/no-show count)
 * 8.  🌐  Full Arabic bot support with RTL-friendly messages
 * 9.  💬  Typing indicator simulation (delay before reply)
 * 10. 🔇  Quiet hours — don't send bot replies late at night
 * 11. 📋  Treatment-specific info when asking about a treatment
 * 12. 🏷️  Smart lead source tracking (auto-tag WhatsApp leads)
 * 13. ⭐  Post-visit feedback collection
 * 14. 🔁  "Talk to human" escalation option
 * 15. 📌  Prep instructions when confirming
 * 16. ⏰  "How long until my appointment?" query
 * 17. 🚫  Anti-loop protection (don't reply to bot's own messages)
 * 18. 📈  Conversation analytics logging
 * 19. 🎯  Context-aware follow-ups based on conversation state
 */

// ─── 1. Rate Limiting ──────────────────────────────────────────────

const lastReplyTime = new Map<string, number>();
const RATE_LIMIT_MS = 5000; // Min 5 seconds between replies — prevents double-tap duplicate processing

function isRateLimited(phone: string): boolean {
  const last = lastReplyTime.get(phone) || 0;
  const now = Date.now();
  if (now - last < RATE_LIMIT_MS) return true;
  lastReplyTime.set(phone, now);
  return false;
}

// ─── 17. Anti-loop: Track recent outgoing to prevent echo ───────────

const recentOutgoing = new Map<string, number>();

function markOutgoing(phone: string) {
  recentOutgoing.set(phone, Date.now());
}

function isEcho(phone: string): boolean {
  const last = recentOutgoing.get(phone) || 0;
  return Date.now() - last < 1000; // Reply arrived within 1s of our outgoing
}

// ─── 19. Conversation State ─────────────────────────────────────────

type ConvoState =
  | "idle"
  | "awaiting_cancel_confirm"
  | "awaiting_reschedule_confirm"
  | "awaiting_feedback"
  | "awaiting_human";

const convoState = new Map<string, { state: ConvoState; data?: Record<string, string> }>();

function getState(phone: string): ConvoState {
  return convoState.get(phone)?.state || "idle";
}

function setState(phone: string, state: ConvoState, data?: Record<string, string>) {
  convoState.set(phone, { state, data });
}

// ─── Options Context (number replies) ───────────────────────────────

const lastOptionsMap = new Map<string, WaButton[]>();

function setLastOptions(phone: string, buttons: WaButton[]) {
  lastOptionsMap.set(phone, buttons);
}

function getOptionByNumber(phone: string, num: number): string | null {
  const buttons = lastOptionsMap.get(phone);
  if (!buttons || num < 1 || num > buttons.length) return null;
  return buttons[num - 1].id;
}

// ─── Intent Detection ───────────────────────────────────────────────

type Intent =
  | "confirm"
  | "reschedule"
  | "cancel"
  | "greeting"
  | "thanks"
  | "help"
  | "hours"
  | "location"
  | "price"
  | "book"
  | "confirm_cancel"
  | "keep"
  | "human"
  | "feedback_response"
  | "time_left"
  | "arrived"
  | "treatment_info"
  | "unknown";

const INTENT_PATTERNS: { intent: Intent; patterns: RegExp[] }[] = [
  {
    intent: "confirm",
    patterns: [
      /^(yes|yeah|yep|yup|sure|ok|okay|confirm|confirmed|i('ll| will) be there|see you)$/i,
      /^(نعم|تأكيد|اي|ايوا|أكيد|ان شاء الله|اوك|حاضر|تمام|موافق|ماشي)$/i,
      /\b(confirm|i('ll| will) (come|be there|attend))\b/i,
      /^✅/,
    ],
  },
  {
    intent: "reschedule",
    patterns: [
      /^(reschedule|change|move|postpone|delay|different (time|day|date))$/i,
      /^(إعادة جدولة|تغيير|تأجيل|غير الموعد|بدي غير|ابي اغير)$/i,
      /\b(reschedule|change.*(time|date|day|appointment)|can('t| not|not) make it|move.*appointment|another (time|day)|postpone)\b/i,
      /\b(مش قادر|ما اقدر|غير.*موعد|تأجيل|ابي اغير|بدي اغير)\b/i,
      /^📅 Reschedule$/i,
    ],
  },
  {
    intent: "cancel",
    patterns: [
      /^(cancel|cancelled|don'?t want|remove)$/i,
      /^(إلغاء|الغي|الغاء|ما ابي|ما أبي|مابي)$/i,
      /\b(cancel.*appointment|don'?t want.*appointment|remove.*appointment)\b/i,
      /^❌ Cancel$/i,
    ],
  },
  {
    intent: "confirm_cancel",
    patterns: [
      /^(yes,?\s*cancel|confirm.?cancel|1)$/i,
      /^Yes, Cancel$/i,
    ],
  },
  {
    intent: "keep",
    patterns: [
      /^(no,?\s*keep|keep|don'?t cancel|keep it|no|2)$/i,
      /^(لا|خلي|ابقي|خليه)$/i,
      /^No, Keep It$/i,
    ],
  },
  {
    intent: "human",
    patterns: [
      /^(human|agent|person|talk to (someone|human|person|agent|staff|doctor)|real person)$/i,
      /^(موظف|دكتور|اتكلم مع شخص|شخص حقيقي|كلمني مع حد)$/i,
      /^🧑 Talk to someone$/i,
    ],
  },
  {
    intent: "time_left",
    patterns: [
      /\b(how long|when is|how many days|countdown|time left|when.*appointment|متى|كم باقي|كم يوم)\b/i,
      /^⏰ Time left$/i,
    ],
  },
  {
    intent: "arrived",
    patterns: [
      /^(arrived|here|i('m| am) here|i('ve| have) arrived|at the clinic|outside|i'm outside|on my way|almost there|parking)$/i,
      /^(وصلت|أنا هنا|في الخارج|وصل|جيت|أنا جاي|في الطريق|تقريباً وصلت)$/i,
      /\b(i('m| am) (here|arrived|outside|at the clinic)|just arrived|just got here)\b/i,
      /^✅ (Arrived|I'm here|On my way)$/i,
    ],
  },
  {
    intent: "treatment_info",
    patterns: [
      /\b(tell me about|what is|info about|details about|more about)\b/i,
      /\b(ايش هو|شنو|وش|معلومات عن|تفاصيل)\b/i,
    ],
  },
  {
    intent: "greeting",
    patterns: [
      /^(hi|hello|hey|good (morning|afternoon|evening)|hola|start)$/i,
      /^(مرحبا|هلا|السلام عليكم|اهلا|هاي|صباح الخير|مساء الخير|السلام)$/i,
      /^(hi|hello|hey)\b/i,
    ],
  },
  {
    intent: "thanks",
    patterns: [
      /^(thanks|thank you|thx|ty|appreciated|great|awesome|perfect)$/i,
      /^(شكرا|مشكور|يعطيك العافية|الله يعافيك|تسلم|الله يسلمك)$/i,
      /\b(thank|thanks|شكر)\b/i,
    ],
  },
  {
    intent: "help",
    patterns: [
      /^(help|menu|options|what can you do)$/i,
      /^(مساعدة|خيارات|قائمة)$/i,
      /^📋 Menu$/i,
    ],
  },
  {
    intent: "hours",
    patterns: [
      /\b(hours|open|close|working hours|when.*open|schedule)\b/i,
      /\b(أوقات|ساعات|متى.*فتح|دوام|مواعيد العمل)\b/i,
      /^🕐 Hours$/i,
    ],
  },
  {
    intent: "location",
    patterns: [
      /\b(where|location|address|directions|map|how to get)\b/i,
      /\b(وين|عنوان|موقع|كيف اوصل|خريطة)\b/i,
      /^📍 Location$/i,
    ],
  },
  {
    intent: "price",
    patterns: [
      /\b(price|cost|how much|fees|charge|rate|pricing)\b/i,
      /\b(سعر|كم|تكلفة|أسعار|بكم)\b/i,
      /^💰 Prices?$/i,
    ],
  },
  {
    intent: "book",
    patterns: [
      /^(book|booking|schedule|appointment|reserve)$/i,
      /^(حجز|موعد|ابي احجز|بدي احجز|اريد موعد)$/i,
      /\b(book|make.*appointment|schedule|احجز)\b/i,
      /^📅 Book/i,
    ],
  },
];

function detectIntent(text: string, phone: string): Intent {
  const normalized = text.trim();

  // Direct button ID mapping (WAHA Plus sends button IDs when user clicks)
  const buttonIdToIntent: Record<string, Intent> = {
    confirm: "confirm",
    reschedule: "reschedule",
    cancel: "cancel",
    help: "help",
    hours: "hours",
    location: "location",
    price: "price",
    book: "book",
    confirm_cancel: "confirm_cancel",
    keep: "keep",
    human: "human",
    time_left: "time_left",
    arrived: "arrived",
    feedback: "feedback_response",
  };

  // Check if the text is a direct button ID (from WAHA Plus button click)
  if (buttonIdToIntent[normalized]) {
    return buttonIdToIntent[normalized];
  }

  // 19. Check conversation state first
  const state = getState(phone);
  if (state === "awaiting_cancel_confirm") {
    if (/^(1|yes|نعم|اي)$/i.test(normalized)) return "confirm_cancel";
    if (/^(2|no|لا|keep)$/i.test(normalized)) return "keep";
  }
  if (state === "awaiting_feedback") {
    return "feedback_response";
  }

  // Check number replies (fallback for text-based buttons)
  const numMatch = normalized.match(/^(\d)$/);
  if (numMatch) {
    const optionId = getOptionByNumber(phone, parseInt(numMatch[1]));
    if (optionId) {
      return buttonIdToIntent[optionId] || "unknown";
    }
  }

  // Pattern matching
  for (const { intent, patterns } of INTENT_PATTERNS) {
    for (const pattern of patterns) {
      if (pattern.test(normalized)) return intent;
    }
  }
  return "unknown";
}

// ─── 8. Language Detection ──────────────────────────────────────────

function isArabic(text: string): boolean {
  const arabicChars = (text.match(/[\u0600-\u06FF]/g) || []).length;
  return arabicChars > text.length * 0.3;
}

// ─── Helpers ────────────────────────────────────────────────────────

// 2. Time-aware greeting
function getTimeGreeting(lang: "en" | "ar"): string {
  const hour = new Date().getHours();
  if (lang === "ar") {
    if (hour < 12) return "صباح الخير";
    if (hour < 18) return "مساء الخير";
    return "مساء النور";
  }
  if (hour < 12) return "Good morning";
  if (hour < 18) return "Good afternoon";
  return "Good evening";
}

// 5. Countdown format
function getCountdown(appointmentDate: Date): string {
  const now = new Date();
  const diff = appointmentDate.getTime() - now.getTime();
  if (diff < 0) return "already passed";

  const days = Math.floor(diff / (1000 * 60 * 60 * 24));
  const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));

  if (days === 0 && hours === 0) return "less than an hour!";
  if (days === 0) return `in ${hours} hour${hours > 1 ? "s" : ""}`;
  if (days === 1) return "tomorrow";
  if (days < 7) return `in ${days} days`;
  return `in ${Math.ceil(days / 7)} week${days > 7 ? "s" : ""}`;
}

function formatAppointment(apt: {
  dateTime: Date;
  treatment: { name: string; price: number | null; duration: number };
  status: string;
}): string {
  const dt = new Date(apt.dateTime);
  const date = dt.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric" });
  const time = dt.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit", hour12: true });
  const countdown = getCountdown(dt);
  return `📅 ${date}\n🕐 ${time} _(${countdown})_\n💆 ${apt.treatment.name} (${apt.treatment.duration} min)${apt.treatment.price ? ` — $${apt.treatment.price}` : ""}`;
}

function getBookingLink(clinicSlug: string): string {
  const baseUrl = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000";
  return `${baseUrl}/book/${clinicSlug}`;
}

function getConfirmLink(appointmentId: string): string {
  const baseUrl = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000";
  return `${baseUrl}/api/confirm/${appointmentId}`;
}

// 9. Typing simulation delay
const typingDelay = () => new Promise((r) => setTimeout(r, 800 + Math.random() * 700));

// ─── Send helpers ───────────────────────────────────────────────────

async function sendText(phone: string, text: string, clinicId: string, appointmentId?: string) {
  markOutgoing(phone);
  const wahaResponse = await sendMessage(phone, text);
  await logOutgoing(clinicId, phone, text, wahaResponse, appointmentId);
  return wahaResponse;
}

async function sendBtns(
  phone: string,
  text: string,
  buttons: WaButton[],
  clinicId: string,
  appointmentId?: string,
  footer?: string
) {
  setLastOptions(phone, buttons);
  markOutgoing(phone);
  const wahaResponse = await sendButtons(phone, text, buttons, footer);
  const btnLabels = buttons.map((b) => b.text).join(" | ");
  await logOutgoing(clinicId, phone, `${text}\n[Options: ${btnLabels}]`, wahaResponse, appointmentId);
  return wahaResponse;
}

async function logOutgoing(
  clinicId: string,
  phone: string,
  message: string,
  wahaResponse: unknown,
  appointmentId?: string
) {
  await prisma.messageLog.create({
    data: {
      clinicId,
      appointmentId: appointmentId || null,
      phone,
      direction: "outgoing",
      message,
      status: "sent",
      wahaMessageId: (wahaResponse as { key?: { id?: string } })?.key?.id || null,
      sentAt: new Date(),
    },
  });
}

// ─── 18. Analytics Logging ──────────────────────────────────────────

function logAnalytics(phone: string, intent: string, hadAppointment: boolean, leadFound: boolean) {
  console.log(
    `📊 [Bot] phone=${phone.slice(-6)} intent=${intent} lead=${leadFound} appt=${hadAppointment} time=${new Date().toISOString()}`
  );
}

// ─── Main Bot Handler ───────────────────────────────────────────────

export async function handleIncomingMessage(
  clinicId: string,
  phone: string,
  text: string
): Promise<void> {
  // 1. Rate limiting
  if (isRateLimited(phone)) {
    console.log(`⏱️ Rate limited: ${phone}`);
    return;
  }

  // 17. Anti-loop
  if (isEcho(phone)) {
    console.log(`🔄 Echo detected: ${phone}`);
    return;
  }

  const intent = detectIntent(text, phone);
  const lang = isArabic(text) ? "ar" : "en";

  const clinic = await prisma.clinic.findUnique({ where: { id: clinicId } });
  if (!clinic) return;

  // 10. Quiet hours check
  const hour = new Date().getHours();
  const inQuietHours = hour >= clinic.quietHoursStart || hour < clinic.quietHoursEnd;

  // Find lead — multi-strategy phone matching to avoid duplicate leads

  // Strategy 1: exact match
  let lead = await prisma.lead.findFirst({
    where: { clinicId, phone: phone },
  });

  // Strategy 2: match by last 9 digits (suffix)
  if (!lead) {
    const suffix9 = getPhoneSuffix(phone, 9);
    const candidates = await prisma.lead.findMany({
      where: { clinicId, phone: { contains: suffix9 } },
      take: 5,
    });
    lead = candidates.find(c => getPhoneSuffix(c.phone, 9) === suffix9) || candidates[0] || null;
  }

  // Strategy 3: match by last 8 digits (looser fallback)
  if (!lead) {
    const suffix8 = getPhoneSuffix(phone, 8);
    const candidates = await prisma.lead.findMany({
      where: { clinicId, phone: { contains: suffix8 } },
      take: 5,
    });
    lead = candidates.find(c => getPhoneSuffix(c.phone, 8) === suffix8) || candidates[0] || null;
  }

  // 4. Auto-create lead from unknown number
  if (!lead && phone.length >= 7) {
    const normalized = normalizePhone(phone);
    lead = await prisma.lead.create({
      data: {
        clinicId,
        name: `WhatsApp ${phone.slice(-4)}`,
        phone: `+${normalized}`,
        source: "whatsapp", // 12. Auto-tag source
        status: "new",
      },
    });
    console.log(`👤 Auto-created lead for ${phone}`);
  }

  // Get ALL upcoming appointments (3. Multiple appointments)
  const upcomingAppointments = lead
    ? await prisma.appointment.findMany({
        where: {
          leadId: lead.id,
          status: { in: ["scheduled", "booked", "confirmed"] },
          dateTime: { gte: new Date() },
        },
        include: { treatment: true },
        orderBy: { dateTime: "asc" },
      })
    : [];

  const upcomingAppointment = upcomingAppointments[0] || null;
  const name = lead?.name?.split(" ")[0] || "";

  // 7. Patient history
  const completedCount = lead
    ? await prisma.appointment.count({
        where: { leadId: lead.id, status: "completed" },
      })
    : 0;
  const noShowCount = lead
    ? await prisma.appointment.count({
        where: { leadId: lead.id, status: "no_show" },
      })
    : 0;
  const isReturning = completedCount > 0;

  // 18. Log analytics
  logAnalytics(phone, intent, !!upcomingAppointment, !!lead);

  // 9. Typing delay
  await typingDelay();

  try {
    switch (intent) {
      // ─── CONFIRM ──────────────────────────────────────────
      case "confirm": {
        setState(phone, "idle");

        if (!upcomingAppointment) {
          const msg = lang === "ar"
            ? `شكراً لردك! 😊\n\nما لقينا موعد قادم لك.`
            : `Thank you for your reply! 😊\n\nWe don't see an upcoming appointment for you.`;
          await sendBtns(phone, msg, [
            { id: "book", text: lang === "ar" ? "📅 حجز موعد" : "📅 Book Appointment" },
            { id: "help", text: lang === "ar" ? "📋 القائمة" : "📋 Menu" },
          ], clinicId);
          break;
        }

        const updated = await prisma.appointment.updateMany({
          where: { id: upcomingAppointment.id, status: { in: ["scheduled", "booked"] } },
          data: { status: "confirmed", confirmedAt: new Date() },
        });

        if (updated.count === 0) {
          await sendText(phone,
            lang === "ar"
              ? `موعدك تم تأكيده بالفعل! ✅`
              : `Your appointment is already confirmed! ✅`,
            clinicId, upcomingAppointment.id
          );
          break;
        }

        if (lead) {
          await prisma.lead.update({ where: { id: lead.id }, data: { status: "confirmed" } });
        }

        // 15. Include prep instructions when confirming
        const prepMsg = upcomingAppointment.treatment.prepInstructions
          ? `\n\n📝 *Preparation:*\n${upcomingAppointment.treatment.prepInstructions}`
          : "";

        const confirmMsg = lang === "ar"
          ? `تم تأكيد موعدك بنجاح! ✅🎉\n\n${formatAppointment(upcomingAppointment)}${prepMsg}\n\nالرجاء الحضور قبل ١٠ دقائق. نتطلع لرؤيتك!`
          : `Your appointment is *confirmed*! ✅🎉\n\n${formatAppointment(upcomingAppointment)}${prepMsg}\n\nPlease arrive 10 minutes early. We're looking forward to seeing you!`;

        // 3. Show other appointments if multiple
        const otherAppts = upcomingAppointments.slice(1);
        const extraMsg = otherAppts.length > 0
          ? `\n\n📋 You also have ${otherAppts.length} more upcoming appointment${otherAppts.length > 1 ? "s" : ""}.`
          : "";

        await sendBtns(
          phone,
          confirmMsg + extraMsg,
          [
            { id: "reschedule", text: "📅 Reschedule" },
            { id: "cancel", text: "❌ Cancel" },
            { id: "help", text: "📋 Menu" },
          ],
          clinicId,
          upcomingAppointment.id,
          clinic.name
        );
        break;
      }

      // ─── RESCHEDULE ───────────────────────────────────────
      case "reschedule": {
        if (!upcomingAppointment) {
          await sendBtns(phone, lang === "ar"
            ? `ما لقينا موعد لتغييره. 🤔`
            : `We don't see an upcoming appointment to reschedule. 🤔`, [
            { id: "book", text: lang === "ar" ? "📅 حجز جديد" : "📅 Book New" },
            { id: "help", text: "📋 Menu" },
          ], clinicId);
          break;
        }

        // 6. Show what will be rescheduled and confirm
        setState(phone, "awaiting_reschedule_confirm", { appointmentId: upcomingAppointment.id });

        await prisma.appointment.update({
          where: { id: upcomingAppointment.id },
          data: { status: "rescheduled" },
        });
        await prisma.scheduledReminder.updateMany({
          where: { appointmentId: upcomingAppointment.id, status: "pending" },
          data: { status: "skipped" },
        });
        if (lead) {
          await prisma.lead.update({ where: { id: lead.id }, data: { status: "contacted" } });
        }

        const bookingLink = getBookingLink(clinic.slug);

        await sendBtns(
          phone,
          lang === "ar"
            ? `تم إلغاء موعدك السابق 📅\n\n${formatAppointment(upcomingAppointment)}\n\n✨ *احجز موعدك الجديد هنا:*\n${bookingLink}\n\nأو أرسل الوقت والتاريخ المفضل لك!`
            : `No problem! Your previous appointment has been cancelled. 📅\n\n${formatAppointment(upcomingAppointment)}\n\n✨ *Book your new appointment here:*\n${bookingLink}\n\nOr reply with your preferred date and time!`,
          [
            { id: "book", text: lang === "ar" ? "📅 حجز الآن" : "📅 Book Now" },
            { id: "price", text: lang === "ar" ? "💰 الأسعار" : "💰 Prices" },
            { id: "help", text: "📋 Menu" },
          ],
          clinicId,
          upcomingAppointment.id,
          clinic.name
        );
        setState(phone, "idle");
        break;
      }

      // ─── CANCEL ───────────────────────────────────────────
      case "cancel": {
        if (!upcomingAppointment) {
          await sendBtns(phone,
            lang === "ar" ? `ما عندك مواعيد قادمة لإلغائها. ✅` : `You don't have any upcoming appointments to cancel. ✅`,
            [
              { id: "book", text: lang === "ar" ? "📅 حجز" : "📅 Book" },
              { id: "help", text: "📋 Menu" },
            ], clinicId);
          break;
        }

        // 6. Confirmation step
        setState(phone, "awaiting_cancel_confirm");

        await sendBtns(
          phone,
          lang === "ar"
            ? `⚠️ هل أنت متأكد من إلغاء الموعد؟\n\n${formatAppointment(upcomingAppointment)}`
            : `⚠️ Are you sure you want to cancel?\n\n${formatAppointment(upcomingAppointment)}`,
          [
            { id: "confirm_cancel", text: lang === "ar" ? "نعم، إلغاء" : "Yes, Cancel" },
            { id: "keep", text: lang === "ar" ? "لا، خليه" : "No, Keep It" },
          ],
          clinicId,
          upcomingAppointment.id,
          lang === "ar" ? "أرسل 1 أو 2" : "Reply 1 or 2"
        );
        break;
      }

      // ─── CONFIRM CANCEL ───────────────────────────────────
      case "confirm_cancel": {
        setState(phone, "idle");

        if (!upcomingAppointment) {
          await sendBtns(phone, `No appointment to cancel. ✅`, [
            { id: "book", text: "📅 Book" },
            { id: "help", text: "📋 Menu" },
          ], clinicId);
          break;
        }

        await prisma.appointment.update({
          where: { id: upcomingAppointment.id },
          data: { status: "cancelled" },
        });
        await prisma.scheduledReminder.updateMany({
          where: { appointmentId: upcomingAppointment.id, status: "pending" },
          data: { status: "skipped" },
        });
        if (lead) {
          await prisma.lead.update({ where: { id: lead.id }, data: { status: "cancelled" } });
        }

        await sendBtns(
          phone,
          lang === "ar"
            ? `تم إلغاء موعدك. 🙏\n\n${formatAppointment(upcomingAppointment)}\n\nنأمل أن نراك قريباً! 💙`
            : `Your appointment has been cancelled. 🙏\n\n${formatAppointment(upcomingAppointment)}\n\nWe hope to see you again soon! 💙`,
          [
            { id: "book", text: lang === "ar" ? "📅 حجز جديد" : "📅 Book Again" },
            { id: "help", text: "📋 Menu" },
          ],
          clinicId,
          upcomingAppointment.id,
          clinic.name
        );
        break;
      }

      // ─── KEEP ─────────────────────────────────────────────
      case "keep": {
        setState(phone, "idle");

        if (upcomingAppointment) {
          await sendBtns(
            phone,
            lang === "ar"
              ? `ممتاز! موعدك لا يزال قائماً ✅\n\n${formatAppointment(upcomingAppointment)}`
              : `Great! Your appointment is still on! ✅\n\n${formatAppointment(upcomingAppointment)}`,
            [
              { id: "confirm", text: "✅ Confirm" },
              { id: "reschedule", text: "📅 Reschedule" },
              { id: "help", text: "📋 Menu" },
            ],
            clinicId,
            upcomingAppointment.id,
            clinic.name
          );
        } else {
          await sendBtns(phone, lang === "ar" ? `تمام! 😊` : `All good! 😊`, [
            { id: "book", text: "📅 Book" },
            { id: "help", text: "📋 Menu" },
          ], clinicId);
        }
        break;
      }

      // ─── GREETING ─────────────────────────────────────────
      case "greeting": {
        setState(phone, "idle");
        const timeGreeting = getTimeGreeting(lang);
        const greeting = name
          ? (lang === "ar" ? `${timeGreeting} ${name}! 👋` : `${timeGreeting}, ${name}! 👋`)
          : `${timeGreeting}! 👋`;

        // 7. Personalize for returning patients
        const welcomeBack = isReturning
          ? (lang === "ar" ? `\nأهلاً بعودتك! 🌟` : `\nWelcome back! 🌟`)
          : "";

        if (upcomingAppointment) {
          // 3. Show count of appointments
          const apptCount = upcomingAppointments.length > 1
            ? `\n📋 _You have ${upcomingAppointments.length} upcoming appointments_`
            : "";

          await sendBtns(
            phone,
            lang === "ar"
              ? `${greeting} أهلاً بك في *${clinic.name}*! 😊${welcomeBack}\n\nموعدك القادم:\n${formatAppointment(upcomingAppointment)}\n📌 الحالة: *${upcomingAppointment.status}*${apptCount}\n\nكيف أقدر أساعدك؟`
              : `${greeting} Welcome to *${clinic.name}*! 😊${welcomeBack}\n\nYour upcoming appointment:\n${formatAppointment(upcomingAppointment)}\n📌 Status: *${upcomingAppointment.status}*${apptCount}\n\nHow can I help you?`,
            [
              { id: "confirm", text: lang === "ar" ? "✅ تأكيد" : "✅ Confirm" },
              { id: "reschedule", text: lang === "ar" ? "📅 تغيير الموعد" : "📅 Reschedule" },
              { id: "help", text: lang === "ar" ? "📋 المزيد" : "📋 More Options" },
            ],
            clinicId,
            upcomingAppointment.id,
            lang === "ar" ? "أرسل رقم الخيار" : "Reply with a number"
          );
        } else {
          await sendBtns(
            phone,
            lang === "ar"
              ? `${greeting} أهلاً بك في *${clinic.name}*! 😊${welcomeBack}\n\nكيف أقدر أساعدك؟`
              : `${greeting} Welcome to *${clinic.name}*! 😊${welcomeBack}\n\nHow can I help you today?`,
            [
              { id: "book", text: lang === "ar" ? "📅 حجز موعد" : "📅 Book Appointment" },
              { id: "price", text: lang === "ar" ? "💰 الأسعار" : "💰 View Prices" },
              { id: "help", text: lang === "ar" ? "📋 المزيد" : "📋 More Options" },
            ],
            clinicId,
            undefined,
            lang === "ar" ? "أرسل رقم الخيار" : "Reply with a number"
          );
        }
        break;
      }

      // ─── THANKS ───────────────────────────────────────────
      case "thanks": {
        setState(phone, "idle");
        await sendText(
          phone,
          lang === "ar"
            ? `العفو! 😊💙\n\nإذا تحتاج أي شيء، أرسل لنا!\n\nيومك سعيد! ✨`
            : `You're very welcome! 😊💙\n\nIf you need anything, just send a message!\n\nHave a wonderful day! ✨`,
          clinicId
        );
        break;
      }

      // ─── HELP / MENU ─────────────────────────────────────
      case "help": {
        setState(phone, "idle");

        if (upcomingAppointment) {
          await sendBtns(
            phone,
            lang === "ar"
              ? `*${clinic.name}* — القائمة 🏥\n\n📋 *موعدك القادم:*\n${formatAppointment(upcomingAppointment)}\n\nاختر خيار:`
              : `*${clinic.name}* — Menu 🏥\n\n📋 *Your next appointment:*\n${formatAppointment(upcomingAppointment)}\n\nChoose an option:`,
            [
              { id: "confirm", text: lang === "ar" ? "✅ تأكيد" : "✅ Confirm" },
              { id: "reschedule", text: lang === "ar" ? "📅 تغيير" : "📅 Reschedule" },
              { id: "cancel", text: lang === "ar" ? "❌ إلغاء" : "❌ Cancel" },
            ],
            clinicId,
            upcomingAppointment.id,
            lang === "ar" ? "أرسل رقم الخيار" : "Reply with a number"
          );
          await typingDelay();
          await sendBtns(
            phone,
            lang === "ar" ? `المزيد:` : `More options:`,
            [
              { id: "price", text: lang === "ar" ? "💰 الأسعار" : "💰 Prices" },
              { id: "hours", text: lang === "ar" ? "🕐 أوقات العمل" : "🕐 Hours" },
              { id: "human", text: lang === "ar" ? "🧑 تكلم مع شخص" : "🧑 Talk to someone" },
            ],
            clinicId,
            undefined,
            lang === "ar" ? "أرسل رقم الخيار" : "Reply with a number"
          );
        } else {
          await sendBtns(
            phone,
            lang === "ar"
              ? `*${clinic.name}* — القائمة 🏥\n\nاختر خيار:`
              : `*${clinic.name}* — Menu 🏥\n\nChoose an option:`,
            [
              { id: "book", text: lang === "ar" ? "📅 حجز موعد" : "📅 Book Appointment" },
              { id: "price", text: lang === "ar" ? "💰 الأسعار" : "💰 Prices" },
              { id: "hours", text: lang === "ar" ? "🕐 أوقات العمل" : "🕐 Hours" },
            ],
            clinicId,
            undefined,
            lang === "ar" ? "أرسل رقم الخيار" : "Reply with a number"
          );
        }
        break;
      }

      // ─── 16. TIME LEFT ────────────────────────────────────
      case "time_left": {
        if (!upcomingAppointment) {
          await sendBtns(phone,
            lang === "ar" ? `ما عندك مواعيد قادمة حالياً.` : `You don't have any upcoming appointments right now.`, [
            { id: "book", text: "📅 Book" },
            { id: "help", text: "📋 Menu" },
          ], clinicId);
          break;
        }

        const dt = new Date(upcomingAppointment.dateTime);
        const countdown = getCountdown(dt);
        const date = dt.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric" });
        const time = dt.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit", hour12: true });

        await sendBtns(
          phone,
          lang === "ar"
            ? `⏰ موعدك ${countdown}\n\n📅 ${date}\n🕐 ${time}\n💆 ${upcomingAppointment.treatment.name}\n📌 الحالة: *${upcomingAppointment.status}*`
            : `⏰ Your appointment is ${countdown}\n\n📅 ${date}\n🕐 ${time}\n💆 ${upcomingAppointment.treatment.name}\n📌 Status: *${upcomingAppointment.status}*`,
          [
            { id: "confirm", text: "✅ Confirm" },
            { id: "reschedule", text: "📅 Reschedule" },
            { id: "help", text: "📋 Menu" },
          ],
          clinicId,
          upcomingAppointment.id,
          clinic.name
        );
        break;
      }

      // ─── HOURS ────────────────────────────────────────────
      case "hours": {
        const formatHour = (h: number) => {
          const ampm = h >= 12 ? "PM" : "AM";
          const hour12 = h % 12 || 12;
          return `${hour12}:00 ${ampm}`;
        };

        await sendBtns(
          phone,
          lang === "ar"
            ? `🕐 *${clinic.name} — أوقات العمل:*\n\nالإثنين — السبت\n${formatHour(clinic.quietHoursEnd)} — ${formatHour(clinic.quietHoursStart)}\n\nالأحد: مغلق`
            : `🕐 *${clinic.name} Working Hours:*\n\nMonday — Saturday\n${formatHour(clinic.quietHoursEnd)} — ${formatHour(clinic.quietHoursStart)}\n\nSunday: Closed`,
          [
            { id: "book", text: lang === "ar" ? "📅 حجز" : "📅 Book" },
            { id: "location", text: lang === "ar" ? "📍 الموقع" : "📍 Location" },
            { id: "help", text: "📋 Menu" },
          ],
          clinicId,
          undefined,
          lang === "ar" ? "أرسل رقم الخيار" : "Reply with a number"
        );
        break;
      }

      // ─── LOCATION ─────────────────────────────────────────
      case "location": {
        await sendBtns(
          phone,
          lang === "ar"
            ? `📍 *${clinic.name}*\n\nتواصل معنا للحصول على الاتجاهات.\n\n📞 ${clinic.phone || "تواصل عبر هذه المحادثة"}`
            : `📍 *${clinic.name}*\n\nPlease contact us for directions.\n\n📞 ${clinic.phone || "Contact through this chat"}`,
          [
            { id: "book", text: lang === "ar" ? "📅 حجز" : "📅 Book" },
            { id: "hours", text: lang === "ar" ? "🕐 الأوقات" : "🕐 Hours" },
            { id: "help", text: "📋 Menu" },
          ],
          clinicId,
          undefined,
          lang === "ar" ? "أرسل رقم الخيار" : "Reply with a number"
        );
        break;
      }

      // ─── PRICE ────────────────────────────────────────────
      case "price": {
        const treatments = await prisma.treatment.findMany({
          where: { clinicId, isActive: true },
          orderBy: { name: "asc" },
        });

        let priceText = lang === "ar"
          ? `💰 *${clinic.name} — العلاجات:*\n\n`
          : `💰 *${clinic.name} — Treatments:*\n\n`;

        if (treatments.length === 0) {
          priceText += lang === "ar" ? `تواصل معنا للأسعار! 😊` : `Contact us for pricing! 😊`;
        } else {
          for (const t of treatments) {
            const price = t.price ? `$${t.price}` : (lang === "ar" ? "تواصل معنا" : "Contact us");
            priceText += `• *${t.name}* — ${price} (${t.duration} ${lang === "ar" ? "دقيقة" : "min"})\n`;
          }
        }

        await sendBtns(
          phone,
          priceText,
          [
            { id: "book", text: lang === "ar" ? "📅 حجز الآن" : "📅 Book Now" },
            { id: "hours", text: lang === "ar" ? "🕐 الأوقات" : "🕐 Hours" },
            { id: "help", text: "📋 Menu" },
          ],
          clinicId,
          undefined,
          lang === "ar" ? "أرسل رقم الخيار" : "Reply with a number"
        );
        break;
      }

      // ─── BOOK ─────────────────────────────────────────────
      case "book": {
        const bookingLink = getBookingLink(clinic.slug);

        await sendBtns(
          phone,
          lang === "ar"
            ? `ممتاز! خلنا نحجز لك! 📅✨\n\n✨ *احجز موعدك هنا:*\n${bookingLink}\n\nأو أرسل التاريخ والوقت المفضل!\n\nمثال:\n_"يوم الثلاثاء الساعة ٣"_\n_"بكرا الصبح"_`
            : `Great! Let's get you booked! 📅✨\n\n✨ *Book your appointment here:*\n${bookingLink}\n\nOr reply with your preferred date and time!\n\nFor example:\n_"Next Tuesday at 3pm"_\n_"Tomorrow morning"_`,
          [
            { id: "price", text: lang === "ar" ? "💰 الأسعار" : "💰 View Prices" },
            { id: "hours", text: lang === "ar" ? "🕐 الأوقات" : "🕐 Hours" },
            { id: "help", text: "📋 Menu" },
          ],
          clinicId,
          undefined,
          lang === "ar" ? "أرسل رقم الخيار" : "Reply with a number"
        );
        break;
      }

      // ─── 14. TALK TO HUMAN ────────────────────────────────
      case "human": {
        setState(phone, "awaiting_human");

        await sendText(
          phone,
          lang === "ar"
            ? `بالتأكيد! 🧑\n\nفريقنا سيتواصل معك في أقرب وقت.\n\nإذا كان الأمر عاجلاً، اتصل على:\n📞 ${clinic.phone || "هذه المحادثة"}\n\n_سيتم تحويلك لشخص حقيقي._`
            : `Of course! 🧑\n\nOur team will get back to you shortly.\n\nIf it's urgent, please call:\n📞 ${clinic.phone || "this chat"}\n\n_You've been flagged for a human response._`,
          clinicId
        );

        // Update lead notes to flag for human follow-up
        if (lead) {
          const currentNotes = lead.notes || "";
          await prisma.lead.update({
            where: { id: lead.id },
            data: {
              notes: `${currentNotes}\n⚠️ [${new Date().toISOString()}] Requested human contact`.trim(),
              status: "contacted",
            },
          });
        }
        break;
      }

      // ─── 11. TREATMENT INFO ───────────────────────────────
      case "treatment_info": {
        const treatments = await prisma.treatment.findMany({
          where: { clinicId, isActive: true },
          orderBy: { name: "asc" },
        });

        // Try to find which treatment they're asking about
        const textLower = text.toLowerCase();
        const matchedTreatment = treatments.find(
          (t) => textLower.includes(t.name.toLowerCase())
        );

        if (matchedTreatment) {
          let info = `💆 *${matchedTreatment.name}*\n\n`;
          info += `⏱️ Duration: ${matchedTreatment.duration} min\n`;
          info += `💰 Price: ${matchedTreatment.price ? `$${matchedTreatment.price}` : "Contact us"}\n`;
          if (matchedTreatment.prepInstructions) {
            info += `\n📝 *Preparation:*\n${matchedTreatment.prepInstructions}\n`;
          }
          if (matchedTreatment.aftercareInstructions) {
            info += `\n🩹 *Aftercare:*\n${matchedTreatment.aftercareInstructions}\n`;
          }

          await sendBtns(phone, info, [
            { id: "book", text: "📅 Book This" },
            { id: "price", text: "💰 All Prices" },
            { id: "help", text: "📋 Menu" },
          ], clinicId, undefined, clinic.name);
        } else {
          // List all treatments
          let list = `We offer these treatments:\n\n`;
          treatments.forEach((t) => {
            list += `• *${t.name}* — ${t.duration} min\n`;
          });
          list += `\nAsk about any specific treatment for more details!`;

          await sendBtns(phone, list, [
            { id: "book", text: "📅 Book" },
            { id: "price", text: "💰 Prices" },
            { id: "help", text: "📋 Menu" },
          ], clinicId);
        }
        break;
      }

      // ─── 13. FEEDBACK RESPONSE ────────────────────────────
      case "feedback_response": {
        setState(phone, "idle");

        // Save feedback as lead note
        if (lead) {
          const currentNotes = lead.notes || "";
          await prisma.lead.update({
            where: { id: lead.id },
            data: {
              notes: `${currentNotes}\n⭐ [${new Date().toISOString()}] Feedback: ${text}`.trim(),
            },
          });
        }

        await sendText(
          phone,
          lang === "ar"
            ? `شكراً جزيلاً على ملاحظاتك! 🙏⭐\n\nرأيك مهم جداً لنا ويساعدنا على تحسين خدماتنا.\n\nنتطلع لرؤيتك مجدداً! 💙`
            : `Thank you so much for your feedback! 🙏⭐\n\nYour opinion means a lot and helps us improve.\n\nWe look forward to seeing you again! 💙`,
          clinicId
        );
        break;
      }

      // ─── ARRIVED ──────────────────────────────────────────
      case "arrived": {
        setState(phone, "idle");

        if (!upcomingAppointment) {
          await sendBtns(phone,
            lang === "ar"
              ? `شكراً! ما عندنا موعد قادم لك حالياً. 😊`
              : `Thanks! We don't see an upcoming appointment for you right now. 😊`,
            [
              { id: "book", text: "📅 Book" },
              { id: "help", text: "📋 Menu" },
            ], clinicId);
          break;
        }

        // Only allow arrived within 60 minutes before or after appointment time
        const apptTime = new Date(upcomingAppointment.dateTime);
        const now = new Date();
        const minutesDiff = (now.getTime() - apptTime.getTime()) / 60000; // positive = past, negative = future

        if (minutesDiff < -60) {
          // More than 60 minutes early
          const minsUntil = Math.round(-minutesDiff);
          await sendText(
            phone,
            lang === "ar"
              ? `أنت مبكر جداً! 😊 موعدك بعد ${minsUntil} دقيقة. سنسجل وصولك عندما تصل للعيادة.`
              : `You're early! 😊 Your appointment is in ${minsUntil} minutes. We'll mark your arrival when you're at the clinic.`,
            clinicId,
            upcomingAppointment.id
          );
          break;
        }

        const arrivedUpdate = await prisma.appointment.updateMany({
          where: { id: upcomingAppointment.id, status: { in: ["scheduled", "confirmed", "booked"] } },
          data: { status: "arrived" },
        });

        if (arrivedUpdate.count === 0) {
          await sendText(phone,
            lang === "ar"
              ? `وصولك تم تسجيله بالفعل! 🏥`
              : `Your arrival has already been noted! 🏥`,
            clinicId, upcomingAppointment.id
          );
          break;
        }

        if (lead) {
          await prisma.lead.update({ where: { id: lead.id }, data: { status: "arrived" } });
        }

        await sendBtns(
          phone,
          lang === "ar"
            ? `رائع ${name}! 🏥✨\n\nتم تسجيل وصولك. فريقنا سيكون معك بعد لحظات.\n\nأرجو الجلوس في منطقة الانتظار. 😊`
            : `Welcome ${name}! 🏥✨\n\nWe've noted your arrival. Our team will be with you in just a moment.\n\nPlease take a seat in the waiting area. 😊`,
          [
            { id: "help", text: lang === "ar" ? "📋 القائمة" : "📋 Menu" },
          ],
          clinicId,
          upcomingAppointment.id,
          clinic.name
        );
        break;
      }

      // ─── UNKNOWN ──────────────────────────────────────────
      default: {
        // Date detection
        const datePattern = /\b(monday|tuesday|wednesday|thursday|friday|saturday|sunday|tomorrow|today|next week|morning|afternoon|evening|\d{1,2}[\/\-]\d{1,2}|\d{1,2}\s*(am|pm))\b/i;
        const arabicDatePattern = /\b(بكرا|بكره|غدا|اليوم|الأسبوع القادم|صباح|مساء|يوم)\b/i;

        if (datePattern.test(text) || arabicDatePattern.test(text)) {
          const bookingLink = getBookingLink(clinic.slug);
          await sendBtns(
            phone,
            lang === "ar"
              ? `شكراً! 📅\n\nاحجز مباشرة:\n${bookingLink}\n\nأو فريقنا سيتواصل معك قريباً. 😊`
              : `Thanks for your preferred time! 📅\n\nBook directly here:\n${bookingLink}\n\nOr our team will confirm shortly. 😊`,
            [
              { id: "book", text: lang === "ar" ? "📅 حجز" : "📅 Book Online" },
              { id: "help", text: "📋 Menu" },
            ],
            clinicId,
            undefined,
            clinic.name
          );
        } else {
          // 10. Quiet hours response
          if (inQuietHours) {
            await sendText(
              phone,
              lang === "ar"
                ? `شكراً لرسالتك! 😊\n\nنحن حالياً خارج ساعات العمل. سنرد عليك في الصباح.\n\nللحالات العاجلة: ${clinic.phone || "هذه المحادثة"}`
                : `Thanks for your message! 😊\n\nWe're currently outside working hours. We'll get back to you in the morning.\n\nFor urgent matters: ${clinic.phone || "this chat"}`,
              clinicId
            );
            break;
          }

          const hi = name
            ? (lang === "ar" ? `${name}، ` : `${name}, `)
            : "";

          if (upcomingAppointment) {
            await sendBtns(
              phone,
              lang === "ar"
                ? `${hi}شكراً لرسالتك! 😊\n\nفريقنا سيرد قريباً. في هذه الأثناء:`
                : `${hi}thanks for your message! 😊\n\nOur team will reply shortly. In the meantime:`,
              [
                { id: "confirm", text: lang === "ar" ? "✅ تأكيد" : "✅ Confirm" },
                { id: "time_left", text: lang === "ar" ? "⏰ كم باقي؟" : "⏰ Time left" },
                { id: "help", text: "📋 Menu" },
              ],
              clinicId,
              upcomingAppointment.id,
              lang === "ar" ? "أرسل رقم الخيار" : "Reply with a number"
            );
          } else {
            await sendBtns(
              phone,
              lang === "ar"
                ? `${hi}شكراً لرسالتك! 😊\n\nفريقنا سيرد قريباً. في هذه الأثناء:`
                : `${hi}thanks for your message! 😊\n\nOur team will reply shortly. In the meantime:`,
              [
                { id: "book", text: lang === "ar" ? "📅 حجز" : "📅 Book" },
                { id: "price", text: lang === "ar" ? "💰 أسعار" : "💰 Prices" },
                { id: "help", text: "📋 Menu" },
              ],
              clinicId,
              undefined,
              lang === "ar" ? "أرسل رقم الخيار" : "Reply with a number"
            );
          }
        }
        break;
      }
    }

    console.log(`🤖 Bot replied to ${phone} (intent: ${intent}, lang: ${lang})`);
  } catch (error) {
    console.error(`🤖 Bot failed to reply to ${phone}:`, error);
  }
}

// ─── 13. Feedback Request (called after appointment completion) ─────

export async function requestFeedback(clinicId: string, phone: string, patientName: string, treatmentName: string) {
  setState(phone, "awaiting_feedback");

  await sendBtns(
    phone,
    `Hi ${patientName}! 😊\n\nHow was your *${treatmentName}* experience?\n\nPlease rate us:\n⭐ = Poor\n⭐⭐ = Fair\n⭐⭐⭐ = Good\n⭐⭐⭐⭐ = Very Good\n⭐⭐⭐⭐⭐ = Excellent\n\nOr just tell us how it went!`,
    [
      { id: "feedback", text: "⭐⭐⭐⭐⭐ Excellent!" },
      { id: "feedback", text: "⭐⭐⭐ It was okay" },
      { id: "human", text: "🧑 Talk to someone" },
    ],
    clinicId,
    undefined,
    "Your feedback helps us improve"
  );
}
