import { NextResponse } from "next/server";
import { cookies } from "next/headers";
import { sql } from "@/db";
import { detectMedicalIntent, ESCALATION_RULES } from "@/lib/ai/medical-triggers";
import { classifyIntent } from "@/lib/ai/classifier";
import { answerStructuredQuery } from "@/lib/ai/structured-query";
import { answerMemoryQuery } from "@/lib/ai/memory-search";
import { answerParentingQuery } from "@/lib/ai/parenting";
import { logAudit } from "@/lib/audit";
import { requireFamily } from "@/lib/auth";

export async function POST(request: Request) {
  const start = Date.now();
  try {
    const auth = await requireFamily();
    if (!auth.success) {
      return NextResponse.json({ error: auth.error }, { status: auth.status });
    }

    const session = auth.session!;
    const familyId = session.familyId!;

    const body = await request.json();
    const { messages, childId } = body as {
      messages: { role: "user" | "assistant"; content: string }[];
      childId?: string;
    };

    if (!messages || !Array.isArray(messages)) {
      return NextResponse.json({ error: "messages array required" }, { status: 400 });
    }

    const lastUserMsg = [...messages].reverse().find(m => m.role === "user")?.content || "";
    if (!lastUserMsg.trim()) {
      return NextResponse.json({ error: "Empty message" }, { status: 400 });
    }

    // ── 1. HARD GUARDRAIL: keyword-based medical detection (most conservative) ──
    const medicalIntent = detectMedicalIntent(lastUserMsg);
    if (medicalIntent.isMedical) {
      const families = await sql`SELECT pediatrician_phone, pediatrician_name FROM families WHERE id = ${familyId} LIMIT 1`;
      const phone = families[0]?.pediatrician_phone;
      const pedName = families[0]?.pediatrician_name;
      const pedLabel = pedName ? `Dr. ${pedName.replace(/^Dr\.?\s*/i, "")}` : "your pediatrician";

      const reply = [
        `I can't interpret symptoms — that's a pediatrician's job, not mine.`,
        ``,
        ESCALATION_RULES[medicalIntent.category],
        ``,
        phone
          ? `Call ${pedLabel} now: ${phone}`
          : `Add your pediatrician's info in Settings so I can show it here.`,
      ].join("\n");

      await logAudit({
        action: "ai_medical_redirect",
        metadata: { category: medicalIntent.category, keyword: medicalIntent.matchedKeyword },
        request,
        userId: session.userId,
        familyId,
      });

      await logUsage({ familyId, userId: session.userId, intent: "medical_redirect", durationMs: Date.now() - start });

      return NextResponse.json({ reply, redirected: true, category: medicalIntent.category });
    }

    // ── 2. Resolve child context ──────────────────────────────────────────────
    let childName = "your baby";
    let childAge = "unknown age";
    let birthDate = "";

    const resolvedChildId = childId || null;
    if (resolvedChildId) {
      const kids = await sql`SELECT name, birth_date FROM children WHERE id = ${resolvedChildId} AND family_id = ${familyId} LIMIT 1`;
      if (kids[0]) {
        childName = kids[0].name;
        birthDate = kids[0].birth_date;
        childAge = calculateAge(birthDate);
      }
    }

    // ── 3. LLM-based intent classification ───────────────────────────────────
    const classification = await classifyIntent(lastUserMsg);

    // Medical_redirect from classifier → also redirect
    if (classification.intent === "medical_redirect") {
      const families = await sql`SELECT pediatrician_phone, pediatrician_name FROM families WHERE id = ${familyId} LIMIT 1`;
      const phone = families[0]?.pediatrician_phone;
      const pedName = families[0]?.pediatrician_name;
      const pedLabel = pedName ? `Dr. ${pedName.replace(/^Dr\.?\s*/i, "")}` : "your pediatrician";
      const reply = [
        `That sounds like something your pediatrician should assess.`,
        ``,
        ESCALATION_RULES["default"],
        phone ? `Call ${pedLabel}: ${phone}` : `Add your pediatrician's info in Settings.`,
      ].join("\n");

      await logUsage({ familyId, userId: session.userId, intent: "medical_redirect", durationMs: Date.now() - start });
      return NextResponse.json({ reply, redirected: true });
    }

    // ── 4. Route to appropriate handler ──────────────────────────────────────
    let reply: string;
    let memories: unknown[] | undefined;

    if (classification.intent === "structured_query" && resolvedChildId) {
      reply = await answerStructuredQuery(lastUserMsg, {
        childId: resolvedChildId,
        familyId,
        childName,
        birthDate,
      });
    } else if (classification.intent === "memory_search") {
      const cookieStore = await cookies();
      const sessionCookie = `tia_session=${cookieStore.get("tia_session")?.value || ""}`;
      const result = await answerMemoryQuery(lastUserMsg, resolvedChildId, sessionCookie);
      reply = result.text;
      memories = result.memories;
    } else {
      // general_parenting (default)
      const history = messages.slice(0, -1); // all but the last user message
      reply = await answerParentingQuery(lastUserMsg, history, { childName, childAge });
    }

    await logUsage({
      familyId,
      userId: session.userId,
      intent: classification.intent,
      durationMs: Date.now() - start,
    });

    await logAudit({
      action: "ai_query",
      metadata: { intent: classification.intent, confidence: classification.confidence },
      request,
      userId: session.userId,
      familyId,
    });

    return NextResponse.json({ reply, memories, intent: classification.intent });
  } catch (error) {
    console.error("[ai/route]", error);
    return NextResponse.json({ error: String(error) }, { status: 500 });
  }
}

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

function calculateAge(birthDate: string): string {
  if (!birthDate) return "unknown age";
  const birth = new Date(birthDate);
  const now = new Date();
  const totalDays = Math.floor((now.getTime() - birth.getTime()) / 86400000);
  const months = Math.floor(totalDays / 30.44);
  const years = Math.floor(months / 12);
  if (years > 0) return `${years} year${years > 1 ? "s" : ""} ${months % 12} month${months % 12 !== 1 ? "s" : ""}`;
  if (months > 0) return `${months} month${months > 1 ? "s" : ""}`;
  return `${totalDays} day${totalDays !== 1 ? "s" : ""}`;
}

async function logUsage(opts: {
  familyId: string;
  userId?: string;
  intent: string;
  durationMs: number;
}) {
  try {
    await sql`
      INSERT INTO ai_usage (family_id, user_id, intent, duration_ms)
      VALUES (${opts.familyId}, ${opts.userId || null}, ${opts.intent}, ${opts.durationMs})
    `;
  } catch {
    // Non-critical — don't break the response
  }
}
