/**
 * /api/env-vars
 *
 * GET    — list semua env vars milik user (tanpa raw value, hanya masked)
 * POST   — buat / update (upsert) satu atau banyak env var
 * DELETE — hapus satu env var berdasarkan key
 *
 * KEAMANAN:
 * - Raw value TIDAK PERNAH keluar dari route ini ke frontend
 * - Semua value dienkripsi AES-256-GCM sebelum masuk DB
 * - RLS Supabase memastikan user hanya akses data sendiri
 */

import { NextRequest, NextResponse } from "next/server";
import { createClient } from "@/lib/supabase/server";
import { encrypt, decrypt, maskValue } from "@/lib/crypto";
import { invalidateEnvVarsCache } from "@/lib/env-vars-resolver";
import { isCsrfSafe, csrfForbiddenPayload } from "@/lib/csrf";
import type { EnvVar, EnvVarPublic } from "@/types/env-vars";

// =====================
// GET — list env vars (masked)
// =====================
export async function GET() {
  const supabase = createClient();
  const { data: { user } } = await supabase.auth.getUser();
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const { data, error } = await supabase
    .from("env_vars")
    .select("id, key, category, description, is_active, last_used_at, updated_at, encrypted_value")
    .eq("user_id", user.id)
    .order("category")
    .order("key");

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

  // Transform: decrypt lalu mask — raw value TIDAK ikut response
  const safeData: EnvVarPublic[] = (data as EnvVar[]).map((row) => {
    let masked = "••••••";
    try {
      const plain = decrypt(row.encrypted_value);
      masked = maskValue(plain);
    } catch {
      masked = "[enkripsi gagal]";
    }

    return {
      id: row.id,
      key: row.key,
      category: row.category,
      description: row.description,
      is_active: row.is_active,
      masked_value: masked,
      last_used_at: row.last_used_at,
      updated_at: row.updated_at,
    };
  });

  return NextResponse.json({ data: safeData });
}

// =====================
// POST — upsert satu atau banyak env var
// Body: { vars: Array<{ key, value, category?, description? }> }
// =====================
export async function POST(request: NextRequest) {
  // Fix Issue B: CSRF check — env-vars menyimpan API key terenkripsi, wajib terlindungi
  if (!isCsrfSafe(request)) return NextResponse.json(csrfForbiddenPayload(), { status: 403 });
  const supabase = createClient();
  const { data: { user } } = await supabase.auth.getUser();
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const body = await request.json() as {
    vars: Array<{
      key: string;
      value: string;
      category?: string;
      description?: string;
    }>;
  };

  if (!Array.isArray(body.vars) || body.vars.length === 0) {
    return NextResponse.json({ error: "Field 'vars' harus berupa array" }, { status: 400 });
  }

  const results: Array<{ key: string; success: boolean; error?: string }> = [];

  for (const item of body.vars) {
    const { key, value, category = "ai_provider", description } = item;

    if (!key || typeof key !== "string") {
      results.push({ key: key ?? "unknown", success: false, error: "Key tidak valid" });
      continue;
    }

    // Skip jika value kosong atau berisi karakter mask
    if (!value || value.includes("•") || value.trim() === "") {
      results.push({ key, success: false, error: "Value kosong — dilewati" });
      continue;
    }

    try {
      // Enkripsi value sebelum simpan ke DB
      const encryptedValue = encrypt(value.trim());

      const { error } = await supabase.rpc("upsert_env_var", {
        p_user_id: user.id,
        p_key: key,
        p_encrypted_val: encryptedValue,
        p_category: category,
        p_description: description ?? null,
      });

      if (error) throw new Error(error.message);

      results.push({ key, success: true });
    } catch (e) {
      results.push({ key, success: false, error: (e as Error).message });
    }
  }

  const allSuccess = results.every((r) => r.success);
  const anySuccess = results.some((r) => r.success);

  // Fix 4: Invalidate cached env vars so next generate request reads fresh keys
  if (anySuccess) {
    invalidateEnvVarsCache(user.id);
  }

  return NextResponse.json(
    { success: anySuccess, results },
    { status: allSuccess ? 200 : anySuccess ? 207 : 500 }
  );
}

// =====================
// DELETE — hapus env var berdasarkan key
// Query: ?key=OPENAI_API_KEY
// =====================
export async function DELETE(request: NextRequest) {
  if (!isCsrfSafe(request)) return NextResponse.json(csrfForbiddenPayload(), { status: 403 });
  const supabase = createClient();
  const { data: { user } } = await supabase.auth.getUser();
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const { searchParams } = new URL(request.url);
  const key = searchParams.get("key");
  if (!key) return NextResponse.json({ error: "Query 'key' diperlukan" }, { status: 400 });

  const { error } = await supabase
    .from("env_vars")
    .delete()
    .eq("user_id", user.id)
    .eq("key", key);

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

  // Fix 4: Invalidate cache on delete too
  invalidateEnvVarsCache(user.id);

  return NextResponse.json({ success: true, deleted: key });
}

// =====================
// PATCH — toggle is_active
// Body: { key, is_active }
// =====================
export async function PATCH(request: NextRequest) {
  if (!isCsrfSafe(request)) return NextResponse.json(csrfForbiddenPayload(), { status: 403 });
  const supabase = createClient();
  const { data: { user } } = await supabase.auth.getUser();
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const { key, is_active } = await request.json() as { key: string; is_active: boolean };
  if (!key) return NextResponse.json({ error: "Key diperlukan" }, { status: 400 });

  const { error } = await supabase
    .from("env_vars")
    .update({ is_active })
    .eq("user_id", user.id)
    .eq("key", key);

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

  return NextResponse.json({ success: true });
}
