import { NextResponse } from "next/server";
import { prisma } from "@/lib/db";
import { getSession } from "@/lib/auth";
import { scheduleReminders, sendBookingConfirmation, generateConfirmToken } from "@/lib/reminders";
import { getPhoneSuffix, normalizePhone } from "@/lib/phone";

/**
 * POST /api/appointments/quick-book
 * 
 * ONE-STEP booking: Creates lead (or finds existing) + appointment + schedules reminders.
 * This is the receptionist's dream — Name + Phone + Treatment + DateTime = Done.
 * 
 * Body: { name, phone, treatmentId, dateTime, email?, notes?, source? }
 */
export async function POST(req: Request) {
  const session = await getSession();
  if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  let body: Record<string, unknown>;
  try {
    body = await req.json();
  } catch {
    return NextResponse.json({ error: "Invalid JSON" }, { status: 400 });
  }

  const { name, phone, treatmentId, dateTime, email, notes, source } = body as {
    name?: string;
    phone?: string;
    treatmentId?: string;
    dateTime?: string;
    email?: string;
    notes?: string;
    source?: string;
  };

  // Validate required fields
  if (!name?.trim()) return NextResponse.json({ error: "Patient name is required" }, { status: 400 });
  if (!phone?.trim()) return NextResponse.json({ error: "Phone number is required" }, { status: 400 });
  if (!treatmentId) return NextResponse.json({ error: "Treatment is required" }, { status: 400 });
  if (!dateTime) return NextResponse.json({ error: "Date and time are required" }, { status: 400 });

  const dt = new Date(dateTime);
  if (isNaN(dt.getTime())) return NextResponse.json({ error: "Invalid date/time format" }, { status: 400 });
  if (dt < new Date()) return NextResponse.json({ error: "Cannot book appointments in the past" }, { status: 400 });

  // Verify treatment
  const treatment = await prisma.treatment.findFirst({
    where: { id: treatmentId, clinicId: session.id, isActive: true },
  });
  if (!treatment) return NextResponse.json({ error: "Treatment not found or inactive" }, { status: 404 });

  // ─── Find or Create Lead (with deduplication) ───
  const phoneSuffix = getPhoneSuffix(phone);
  const normalized = normalizePhone(phone);

  let lead = await prisma.lead.findFirst({
    where: { clinicId: session.id, phone: { contains: phoneSuffix } },
  });

  if (lead) {
    // Update name if it was auto-generated (from WhatsApp)
    if (lead.name.startsWith("WhatsApp ")) {
      lead = await prisma.lead.update({
        where: { id: lead.id },
        data: { name: name.trim() },
      });
    }
  } else {
    // Create new lead
    lead = await prisma.lead.create({
      data: {
        clinicId: session.id,
        name: name.trim(),
        phone: normalized.startsWith("+") ? normalized : `+${normalized}`,
        email: email?.trim() || null,
        source: source || "manual",
        status: "new",
        notes: notes?.trim() || null,
      },
    });
  }

  // ─── Double-booking prevention ───
  const appointmentEndTime = new Date(dt.getTime() + treatment.duration * 60000);
  const leadConflict = await prisma.appointment.findFirst({
    where: {
      leadId: lead.id,
      status: { in: ["scheduled", "confirmed", "booked"] },
      dateTime: { gte: new Date() },
      AND: [{ dateTime: { lt: appointmentEndTime } }],
    },
    include: { treatment: true },
  });

  if (leadConflict) {
    const existingEnd = new Date(new Date(leadConflict.dateTime).getTime() + leadConflict.treatment.duration * 60000);
    if (dt < existingEnd && appointmentEndTime > new Date(leadConflict.dateTime)) {
      const conflictDate = new Date(leadConflict.dateTime).toLocaleDateString("en-US", {
        weekday: "short", month: "short", day: "numeric", hour: "numeric", minute: "2-digit",
      });
      return NextResponse.json({
        error: `This patient already has an appointment at ${conflictDate} (${leadConflict.treatment.name}). Please cancel or reschedule the existing one first.`,
      }, { status: 409 });
    }
  }

  // ─── Create Appointment ───
  const confirmToken = generateConfirmToken();

  const appointment = await prisma.appointment.create({
    data: {
      clinicId: session.id,
      leadId: lead.id,
      treatmentId,
      dateTime: dt,
      confirmToken,
      notes: notes?.trim() || null,
    },
    include: { lead: true, treatment: true },
  });

  // Update lead status
  await prisma.lead.update({
    where: { id: lead.id },
    data: { status: "booked" },
  }).catch(() => {});

  // Schedule reminders
  scheduleReminders(appointment.id).catch(console.error);
  sendBookingConfirmation(appointment.id).catch(console.error);

  return NextResponse.json({
    ...appointment,
    _quickBooked: true,
    _leadCreated: !leadConflict,
  });
}
