import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/db";
import { getSession } from "@/lib/auth";

export async function POST(req: NextRequest) {
  try {
    const session = await getSession();
    if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

    const { treeId, treeName, nodes, edges } = await req.json();

    if (!nodes || !Array.isArray(nodes)) {
      return NextResponse.json({ error: "Invalid nodes payload" }, { status: 400 });
    }

    // Determine trigger type from start node
    const startNode = nodes.find((n: any) => n.data?.kind === "start");
    const triggerType = startNode?.data?.content ?? "booking_created";

    let tree;

    if (treeId) {
      // Update existing tree
      tree = await prisma.reminderTree.update({
        where: { id: treeId },
        data: {
          name: treeName || "Untitled Tree",
          triggerType,
          metadata: JSON.stringify({ canvasNodes: nodes, canvasEdges: edges, savedAt: new Date().toISOString() }),
          updatedAt: new Date(),
        },
      });

      // Rebuild nodes: delete old, insert new
      await prisma.treeNode.deleteMany({ where: { treeId } });
    } else {
      // Create new tree
      tree = await prisma.reminderTree.create({
        data: {
          clinicId: session.id,
          name: treeName || "Untitled Tree",
          triggerType,
          isActive: false,
          metadata: JSON.stringify({ canvasNodes: nodes, canvasEdges: edges, savedAt: new Date().toISOString() }),
        },
      });
    }

    // Save each canvas node as a TreeNode for execution engine
    const nodeIdMap = new Map<string, string>(); // canvas id → db id

    for (let i = 0; i < nodes.length; i++) {
      const n = nodes[i];
      const nd = n.data;

      const dbNode = await prisma.treeNode.create({
        data: {
          treeId: tree.id,
          name: nd.label || nd.kind,
          nodeType: nd.kind,
          content: buildNodeContent(nd),
          conditions: nd.branches ? JSON.stringify(nd.branches) : nd.aiConditionPrompt ? JSON.stringify({ aiPrompt: nd.aiConditionPrompt }) : null,
          offsetMinutes: nd.delayMinutes ?? 0,
          sortOrder: i,
          metadata: JSON.stringify({
            canvasId: n.id,
            position: n.position,
          }),
        },
      });

      nodeIdMap.set(n.id, dbNode.id);
    }

    // Update parentId linkages using edges
    for (const edge of edges) {
      const childDbId  = nodeIdMap.get(edge.target);
      const parentDbId = nodeIdMap.get(edge.source);
      if (childDbId && parentDbId) {
        await prisma.treeNode.update({
          where: { id: childDbId },
          data: { parentId: parentDbId },
        });
      }
    }

    return NextResponse.json({ treeId: tree.id, message: "Saved!" });
  } catch (err: any) {
    console.error("Save error:", err);
    return NextResponse.json({ error: err.message }, { status: 500 });
  }
}

function buildNodeContent(nd: any): string | null {
  if (nd.kind === "start") return nd.content ?? null;
  if (nd.kind === "message") return nd.content ?? null;
  if (nd.kind === "ai_response") return nd.aiSystemPrompt ?? null;
  if (nd.kind === "buttons") {
    return JSON.stringify({ message: nd.content ?? "", buttons: nd.buttons ?? [] });
  }
  if (nd.kind === "condition") return nd.aiConditionPrompt ?? null;
  if (nd.kind === "wait") return null;
  return null;
}
