import { NextRequest, NextResponse } from "next/server";
import { GoogleGenerativeAI } from "@google/generative-ai";
import { nanoid } from "nanoid";

const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!);

export async function POST(req: NextRequest) {
  try {
    const { goal, clinicType = "Medical Clinic", language = "English", templateType = "booking_created" } = await req.json();
    if (!goal?.trim()) return NextResponse.json({ error: "No goal provided" }, { status: 400 });

    const systemPrompt = `You are a WhatsApp chatbot architect building flows for ${clinicType} clinics.
Return ONLY valid JSON — no markdown, no code fences, no explanation.

OUTPUT SHAPE:
{"nodes":[...],"edges":[...],"suggestedName":"..."}

━━━ NODE TYPES ━━━

start     → {id, type:"start",     position:{x,y}, data:{kind:"start",     label:"...", content:"${templateType}"}}
message   → {id, type:"message",   position:{x,y}, data:{kind:"message",   label:"...", content:"WhatsApp text with emoji"}}
buttons   → {id, type:"buttons",   position:{x,y}, data:{kind:"buttons",   label:"...", content:"question text", buttons:[{id:"btn1",label:"✅ Yes",text:"Yes"},{id:"btn2",label:"📅 Reschedule",text:"Reschedule"}]}}
condition → {id, type:"condition", position:{x,y}, data:{kind:"condition", label:"...", branches:[{id:"branch1",label:"Confirmed",keywords:["yes","1","ok","confirm"]},{id:"branch2",label:"Cancelled",keywords:["no","3","cancel"]}]}}
wait      → {id, type:"wait",      position:{x,y}, data:{kind:"wait",      label:"...", delayMinutes:60}}
retry     → {id, type:"retry",     position:{x,y}, data:{kind:"retry",     label:"...", retryDelayMinutes:1440, maxRetries:2, retryMessage:"Hi {{name}}, just checking in — did you receive our message?"}}
end       → {id, type:"end",       position:{x,y}, data:{kind:"end",       label:"..."}}

━━━ EDGE SHAPE ━━━
{id, source:"nodeId", target:"nodeId", sourceHandle?:"buttonId or branchId"}

━━━ CRITICAL RULES ━━━
1. NEVER use ai_response nodes — they are DISABLED. Use message nodes only.
2. When a patient says "reschedule": send a plain message node with text like:
   "No problem at all, {{name}}! 😊 Click here to pick a new time: https://book.{{clinic}}.com"
   Then connect to an end node. Do NOT wait for a reply.
3. When a patient confirms: send a confirmation message → end node.
4. When a patient cancels: send a brief empathetic message → end node.
5. condition node branches use keyword arrays — the engine matches patient replies by keyword.
   Keywords for confirm: ["yes","1","ok","confirm","going","✅"]
   Keywords for reschedule: ["2","reschedule","change"]
   Keywords for cancel: ["no","3","cancel","❌"]
6. Always use {{name}} {{treatment}} {{clinic}} {{date}} {{time}} as placeholders.
7. Use WhatsApp formatting: *bold*, _italic_, line breaks with \\n.
8. Emoji in every message — keep it warm, human, professional.
9. Nodes go left → right. Start at x:60,y:200. Each step: +360px on x. Branch vertically ±180px.
10. 6–10 nodes total. Always start with start node, always end with end nodes.
11. No orphan nodes — every node must have a path to an end node.
12. The flow must be complete — do not leave any branch dangling.
13. Language: ${language}.

━━━ EXAMPLE RESCUE BRANCH (reschedule) ━━━
{id:"m-reschedule", type:"message", position:{x:1080,y:320}, data:{kind:"message", label:"Reschedule Link", content:"No problem at all, {{name}}! 😊 You can pick a new time here:\\nhttps://book.clinera.app/{{clinic}}\\n\\nWe'll confirm your new slot right away! 📅"}}
Then edge from m-reschedule → end node.

Build a complete, realistic ${clinicType} flow for: "${goal}"`;

    const model = genAI.getGenerativeModel({
      model: "gemini-2.0-flash",
      systemInstruction: systemPrompt,
    });

    const response = await model.generateContent({
      contents: [{
        role: "user",
        parts: [{ text: `Build the flow now. Return ONLY the JSON object, nothing else.` }],
      }],
      generationConfig: { maxOutputTokens: 4000, temperature: 0.4 },
    });

    const raw = response.response.text().trim();
    const clean = raw.replace(/^```[a-z]*\n?/i, "").replace(/\n?```$/i, "").trim();
    const jsonMatch = clean.match(/\{[\s\S]*\}/);
    if (!jsonMatch) throw new Error("Could not parse AI response as JSON");

    const parsed = JSON.parse(jsonMatch[0]);
    if (!parsed.nodes || !Array.isArray(parsed.nodes)) throw new Error("Invalid flow structure");

    // Remove any ai_response nodes the model hallucinated — replace with message
    parsed.nodes = parsed.nodes.map((n: any) => {
      if (n.data?.kind === "ai_response" || n.type === "ai_response") {
        const content = n.data?.content || n.data?.aiSystemPrompt
          ? "Thank you for your message, {{name}}! 😊 Our team will follow up with you shortly."
          : "Thank you, {{name}}! 😊 We'll be in touch soon.";
        return { ...n, type: "message", data: { ...n.data, kind: "message", content, aiSystemPrompt: undefined } };
      }
      return n;
    });

    // Stamp fresh IDs
    const idMap = new Map<string, string>();
    const freshNodes = parsed.nodes.map((n: any) => {
      const kind = n.data?.kind || n.type || "message";
      const newId = `${kind}-${nanoid(5)}`;
      idMap.set(n.id, newId);
      return { ...n, id: newId, type: kind, data: { ...n.data, kind } };
    });

    const freshEdges = (parsed.edges || []).map((e: any) => ({
      ...e,
      id: `e-${nanoid(5)}`,
      source: idMap.get(e.source) ?? e.source,
      target: idMap.get(e.target) ?? e.target,
      type: "deletable",
      animated: true,
      style: { strokeWidth: 2.5, stroke: "#6366f1" },
      markerEnd: { type: "arrowclosed", width: 18, height: 18, color: "#6366f1" },
    }));

    return NextResponse.json({
      nodes: freshNodes,
      edges: freshEdges,
      suggestedName: parsed.suggestedName || goal,
    });

  } catch (err: any) {
    console.error("generate-flow error:", err.message);
    return NextResponse.json({ error: err.message || "Generation failed" }, { status: 500 });
  }
}
