/**
 * POST /api/ai/chat
 *
 * Streaming AI luận giải. Body shape:
 *   {
 *     input: ChartInput,             // birth info — server re-builds chart
 *     question: string,
 *     history?: ChatMessage[]        // prior turns (optional)
 *   }
 *
 * Returns a `text/event-stream` SSE response. Each event payload is a JSON
 * object: { delta?: string, done?: true, error?: string }.
 *
 * Why SSE not raw text: lets the client distinguish stream end from server
 * disconnects, and surface graceful errors mid-stream.
 *
 * Rate limiting + auth gating land in Phase 2 — Phase 1.6 is open so the
 * mock provider can be exercised without auth friction.
 */
import { NextRequest } from "next/server";
import { buildChart, type ChartInput } from "@/lib/tuvi/engine";
import { getProvider, type ChatMessage } from "@/lib/ai/provider";

export const runtime = "nodejs";
// Edge runtime can't host the iztro WASM dependency cleanly — pin nodejs.

type Body = {
  input?: ChartInput;
  question?: string;
  history?: ChatMessage[];
};

function sseEvent(payload: Record<string, unknown>): string {
  return `data: ${JSON.stringify(payload)}\n\n`;
}

export async function POST(req: NextRequest) {
  let body: Body;
  try {
    body = (await req.json()) as Body;
  } catch {
    return new Response(JSON.stringify({ error: "Invalid JSON body" }), {
      status: 400,
      headers: { "Content-Type": "application/json" },
    });
  }

  const { input, question, history } = body;
  if (!input || !question || question.trim().length < 2) {
    return new Response(JSON.stringify({ error: "Thiếu input lá số hoặc câu hỏi quá ngắn." }), {
      status: 400,
      headers: { "Content-Type": "application/json" },
    });
  }
  if (question.length > 500) {
    return new Response(JSON.stringify({ error: "Câu hỏi quá dài (giới hạn 500 ký tự)." }), {
      status: 400,
      headers: { "Content-Type": "application/json" },
    });
  }

  let chart;
  try {
    chart = buildChart(input);
  } catch (e) {
    return new Response(
      JSON.stringify({
        error: e instanceof Error ? e.message : "Không an được lá số.",
      }),
      { status: 400, headers: { "Content-Type": "application/json" } }
    );
  }

  const provider = await getProvider();
  const encoder = new TextEncoder();

  const stream = new ReadableStream<Uint8Array>({
    async start(controller) {
      // Tell client which provider we used so the UI can flag mock mode.
      controller.enqueue(encoder.encode(sseEvent({ provider: provider.name })));
      try {
        for await (const chunk of provider.stream({
          chart,
          question,
          history,
        })) {
          controller.enqueue(encoder.encode(sseEvent({ delta: chunk })));
        }
        controller.enqueue(encoder.encode(sseEvent({ done: true })));
      } catch (e) {
        const msg = e instanceof Error ? e.message : "AI provider failed";
        controller.enqueue(encoder.encode(sseEvent({ error: msg })));
      } finally {
        controller.close();
      }
    },
  });

  return new Response(stream, {
    headers: {
      "Content-Type": "text/event-stream; charset=utf-8",
      "Cache-Control": "no-cache, no-transform",
      Connection: "keep-alive",
      // Disable Next.js buffering for server-sent events
      "X-Accel-Buffering": "no",
    },
  });
}
