import { createFileRoute } from "@tanstack/react-router";
import { createClient } from "@supabase/supabase-js";
import type { Database } from "@/integrations/supabase/types";

// Authenticated SSE-streaming image endpoint. Rate limited per plan.
export const Route = createFileRoute("/api/generate-moodboard-image")({
  server: {
    handlers: {
      POST: async ({ request }) => {
        // --- AuthN: require a valid bearer token ---
        const authHeader = request.headers.get("authorization");
        if (!authHeader?.startsWith("Bearer ")) {
          return new Response("Unauthorized", { status: 401 });
        }
        const token = authHeader.slice(7);

        const url = process.env.SUPABASE_URL;
        const pubKey = process.env.SUPABASE_PUBLISHABLE_KEY;
        if (!url || !pubKey) {
          return new Response("Backend not configured", { status: 500 });
        }
        const supabase = createClient<Database>(url, pubKey, {
          global: { headers: { Authorization: `Bearer ${token}` } },
          auth: { persistSession: false, autoRefreshToken: false, storage: undefined },
        });
        const { data: claimsData, error: claimsErr } = await supabase.auth.getClaims(token);
        const userId = claimsData?.claims?.sub as string | undefined;
        if (claimsErr || !userId) return new Response("Unauthorized", { status: 401 });

        // --- Input validation ---
        let body: { prompt?: string };
        try { body = (await request.json()) as { prompt?: string }; }
        catch { return new Response("Invalid JSON", { status: 400 }); }
        const prompt = body.prompt;
        if (!prompt || typeof prompt !== "string" || prompt.length < 5 || prompt.length > 4000) {
          return new Response("Invalid prompt", { status: 400 });
        }

        // --- Rate limit (per user/plan) ---
        const { enforceRateLimit, RateLimitError } = await import("@/lib/rate-limit.server");
        try {
          await enforceRateLimit(supabase, userId, "moodboard_image");
        } catch (e) {
          if (e instanceof RateLimitError) {
            return new Response(e.message, { status: 429 });
          }
          throw e;
        }

        const key = process.env.LOVABLE_API_KEY;
        if (!key) return new Response("Missing LOVABLE_API_KEY", { status: 500 });

        const { logAiRequest } = await import("@/lib/ai-monitoring.server");
        const startedAt = Date.now();
        const model = "google/gemini-3.1-flash-image-preview";

        const upstream = await fetch("https://ai.gateway.lovable.dev/v1/images/generations", {
          method: "POST",
          headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
          body: JSON.stringify({
            model,
            messages: [{ role: "user", content: prompt }],
            modalities: ["image", "text"],
            stream: true,
          }),
        });

        if (!upstream.ok || !upstream.body) {
          const errText = await upstream.text();
          await logAiRequest({
            userId, kind: "moodboard_image", status: "error",
            latencyMs: Date.now() - startedAt, model,
            errorCode: String(upstream.status), errorMessage: errText.slice(0, 500),
          });
          if (upstream.status === 429) return new Response("AI service is busy. Try again shortly.", { status: 429 });
          if (upstream.status === 402) return new Response("AI credits exhausted.", { status: 402 });
          return new Response("Image generation failed", { status: upstream.status });
        }

        // Fire-and-forget success log; we don't know completion size until client finishes streaming.
        void logAiRequest({
          userId, kind: "moodboard_image", status: "ok",
          latencyMs: Date.now() - startedAt, model,
        });

        return new Response(upstream.body, {
          headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache" },
        });
      },
    },
  },
});
