/**
 * POST /api/ugc-generator
 *
 * Generate UGC Package lengkap dari data produk + konfigurasi.
 *
 * Body:  UGCGenerateRequest
 * Response: { success: true, data: UGCPackage }
 */

import { NextRequest, NextResponse } from "next/server";
import { createClient } from "@/lib/supabase/server";
import { generatePrompt } from "@/lib/ai/provider";
import { checkRateLimit } from "@/lib/rate-limit";
import { resolveUserEnvVarsCached, hasAnyAiKey } from "@/lib/env-vars-resolver";
import { checkAndIncrementUsage } from "@/lib/usage-quota";
import { calcEstimatedCost } from "@/lib/model-costs";
import { isCsrfSafe, csrfForbiddenPayload } from "@/lib/csrf";
import type { UGCGenerateRequest, UGCPackage, UGCScene } from "@/types/ugc-generator";
import { UGC_PLATFORMS, UGC_LANGUAGE_STYLES, UGC_HOOK_STYLES } from "@/types/ugc-generator";

export const maxDuration = 60; // Allow up to 60s for AI generation on Vercel

export async function POST(request: NextRequest) {
  try {
    // BUG-13 FIX: CSRF check
    if (!isCsrfSafe(request)) {
      return NextResponse.json(csrfForbiddenPayload(), { status: 403 });
    }

    // ── Auth ──────────────────────────────────────────────────────────────────
    const supabase = createClient();
    const { data: { user }, error: authError } = await supabase.auth.getUser();
    if (authError || !user) {
      return NextResponse.json({ success: false, error: "Unauthorized" }, { status: 401 });
    }

    // ── Rate limit ────────────────────────────────────────────────────────────
    const rateLimit = await checkRateLimit(user.id);
    if (!rateLimit.allowed) {
      return NextResponse.json(
        { success: false, error: "Rate limit exceeded. Coba lagi dalam 1 menit." },
        { status: 429 }
      );
    }

    // ── Resolve keys ──────────────────────────────────────────────────────────
    const resolvedVars = await resolveUserEnvVarsCached(supabase, user.id);

    if (!hasAnyAiKey(resolvedVars)) {
      return NextResponse.json(
        { success: false, error: "Belum ada AI API key. Tambahkan di Settings → API Keys.", redirectTo: "/settings" },
        { status: 402 }
      );
    }

    // ── Atomic quota check + pre-increment ───────────────────────────────────
    const quotaResult = await checkAndIncrementUsage(supabase, user.id, 1);
    if (quotaResult === "quota_exceeded") {
      return NextResponse.json(
        { success: false, error: "Kuota habis. Upgrade plan untuk lebih banyak generasi." },
        { status: 403 }
      );
    }

    // ── Parse body ────────────────────────────────────────────────────────────
    const body = await request.json() as Partial<UGCGenerateRequest>;
    const { product, platform, durasi, gayaBahasa, presenter, hookStyle, language = "id", customInstructions, brandVoice } = body;

    if (!product?.namaProduk) {
      return NextResponse.json({ success: false, error: "Data produk tidak lengkap" }, { status: 400 });
    }
    if (!platform || !durasi) {
      return NextResponse.json({ success: false, error: "Platform dan durasi wajib diisi" }, { status: 400 });
    }

    // ── Build AI prompts ──────────────────────────────────────────────────────
    const platformInfo    = UGC_PLATFORMS[platform];
    const langStyleInfo   = UGC_LANGUAGE_STYLES[gayaBahasa ?? "santai_gaul"];
    const hookStyleInfo   = UGC_HOOK_STYLES[hookStyle ?? "masalah_solusi"];
    const langLabel       = language === "id" ? "Bahasa Indonesia" : "English";
    const presenterLabel  = presenter ?? "wanita";

    const systemPrompt = `Kamu adalah copywriter UGC (User Generated Content) profesional kelas dunia.
Spesialisasimu: membuat script video produk yang autentik, relatable, dan convert tinggi untuk platform ${platformInfo?.label ?? platform}.

ATURAN OUTPUT:
1. Hook harus langsung menarik perhatian dalam 3 detik pertama
2. Gunakan gaya bahasa: ${langStyleInfo?.label} — ${langStyleInfo?.desc}
3. Hook style: ${hookStyleInfo?.label} — contoh: ${hookStyleInfo?.example}
4. Presenter: ${presenterLabel}
5. Durasi total video: ${durasi}
6. Semua teks dalam ${langLabel}
7. Script harus terasa AUTENTIK seperti UGC asli, bukan iklan korporat
8. Output HARUS valid JSON — tidak ada teks di luar JSON
${brandVoice ? `9. Brand voice: ${brandVoice}` : ""}
${customInstructions ? `10. Instruksi khusus: ${customInstructions}` : ""}

OUTPUT FORMAT (JSON):
{
  "hook": "kalimat pembuka yang paling menarik (diucapkan di 0-3 detik pertama)",
  "script": [
    {
      "durasi": "0-3 detik",
      "aksi": "apa yang dilakukan presenter di depan kamera",
      "dialog": "teks yang diucapkan / voiceover",
      "visualNote": "catatan untuk kameraman/editor"
    }
  ],
  "fullScript": "seluruh script dalam satu paragraf mengalir, siap dibaca presenter",
  "caption": "caption untuk posting di ${platformInfo?.label ?? platform} (dengan emoji, engaging)",
  "hashtags": ["hashtag1", "hashtag2", ...],
  "callToAction": "CTA spesifik di akhir video",
  "tipsProduction": [
    "tip produksi 1",
    "tip produksi 2",
    "tip produksi 3"
  ]
}`;

    const userPrompt = `Buat UGC Package untuk produk berikut:

NAMA PRODUK: ${product.namaProduk}
KATEGORI: ${product.kategori}
DESKRIPSI: ${product.deskripsiProduk}
MASALAH / PAIN POINT: ${product.masalahPainPoint}
MANFAAT UTAMA: ${product.manfaatUtama}
FITUR / KANDUNGAN: ${product.fiturKandungan}
TARGET AUDIENS: ${product.targetAudiens}
${product.harga ? `HARGA: ${product.harga}` : ""}
${product.sourceUrl ? `SUMBER: ${product.sourceUrl}` : ""}

KONFIGURASI:
- Platform: ${platformInfo?.label ?? platform}
- Durasi: ${durasi}
- Gaya Bahasa: ${langStyleInfo?.label}
- Hook Style: ${hookStyleInfo?.label}
- Presenter: ${presenterLabel}
- Bahasa: ${langLabel}

Buat script yang terasa seperti review/unboxing dari user asli, bukan iklan brand langsung.
Sesuaikan jumlah scene dengan durasi ${durasi}.`;

    // ── Generate dengan retry ─────────────────────────────────────────────────
    const MAX_RETRIES = 2;
    let rawOutput  = "";
    let model      = "unknown";
    let provider   = "unknown";
    let lastError: Error | null = null;
    let tokenUsage: { promptTokens: number; completionTokens: number; totalTokens: number } | undefined;

    for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
      try {
        const response = await generatePrompt(
          [
            { role: "system", content: systemPrompt },
            { role: "user",   content: userPrompt },
          ],
          { temperature: 0.8, maxTokens: 6000 },
          resolvedVars
        );
        rawOutput  = response.content;
        model      = response.model;
        provider   = response.provider;
        tokenUsage = response.usage;
        lastError  = null;
        break;
      } catch (e) {
        lastError = e as Error;
        if (attempt < MAX_RETRIES) await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)));
      }
    }

    if (lastError) {
      return NextResponse.json({ success: false, error: lastError.message }, { status: 500 });
    }

    // ── Parse output ──────────────────────────────────────────────────────────
    let parsed: Partial<UGCPackage & { script: UGCScene[] }>;
    try {
      const cleaned = rawOutput.replace(/^```(?:json)?\s*/i, "").replace(/\s*```$/i, "").trim();
      parsed = JSON.parse(cleaned);
    } catch {
      const match = rawOutput.match(/\{[\s\S]*\}/);
      if (!match) {
        return NextResponse.json({ success: false, error: "AI menghasilkan output tidak valid. Coba lagi." }, { status: 500 });
      }
      try { parsed = JSON.parse(match[0]); }
      catch { return NextResponse.json({ success: false, error: "Gagal memparse output AI. Coba lagi." }, { status: 500 }); }
    }

    const output: UGCPackage = {
      hook:            parsed.hook        ?? "",
      script:          Array.isArray(parsed.script) ? parsed.script : [],
      fullScript:      parsed.fullScript  ?? "",
      caption:         parsed.caption     ?? "",
      hashtags:        Array.isArray(parsed.hashtags) ? parsed.hashtags : [],
      callToAction:    parsed.callToAction ?? "",
      tipsProduction:  Array.isArray(parsed.tipsProduction) ? parsed.tipsProduction : [],
      metadata: {
        generatedAt: new Date().toISOString(),
        model:       `${provider}/${model}`,
        platform,
        durasi,
        language,
      },
    };

    // ── Cost tracking + save history + usage increment ───────────────────────
    const estimatedCostUsd = calcEstimatedCost(provider, model, tokenUsage ?? null);

    await Promise.all([
      // Save full output to ugc_history — quota sudah di-increment atomic di atas
      supabase.from("ugc_history").insert({
        user_id:      user.id,
        product_name: product.namaProduk,
        product_url:  product.sourceUrl ?? null,
        platform,
        durasi,
        gaya_bahasa:  gayaBahasa ?? "santai_gaul",
        presenter:    presenter  ?? "wanita",
        hook_style:   hookStyle  ?? "masalah_solusi",
        language,
        output,
      }),
      tokenUsage
        ? supabase.from("usage_logs").insert({
            user_id:  user.id,
            action:   "ugc_generate",
            platform,
            metadata: { model, provider, durasi, product_name: product.namaProduk },
            prompt_tokens:      tokenUsage.promptTokens,
            completion_tokens:  tokenUsage.completionTokens,
            total_tokens:       tokenUsage.totalTokens,
            estimated_cost_usd: estimatedCostUsd,
          })
        : Promise.resolve(),
    ]);

    return NextResponse.json(
      { success: true, data: output },
      { headers: { "X-RateLimit-Remaining": String(rateLimit.remaining) } }
    );
  } catch (error) {
    console.error("[ugc-generator]", error);
    return NextResponse.json({ success: false, error: "Internal server error" }, { status: 500 });
  }
}
