"use client";

import { useState } from "react";
import Button from "@/components/ui/Button";

export type AiSettingsView = {
  configured: boolean;
  provider: "openai" | "gemini" | "cloudflare" | "custom";
  model: string;
  source: "owner" | "environment" | "none";
  hasKey: boolean;
  keyCount: number;
  accountId: string | null;
  maskedKey: string | null;
  lastTestedAt: string | null;
  lastTestStatus: string | null;
  lastTestMessage: string | null;
};

const PROVIDERS = {
  openai: {
    name: "OpenAI API",
    subtitle: "Model ChatGPT untuk analisis profit",
    model: "gpt-5-mini",
    keyLabel: "OpenAI API key",
    keyPlaceholder: "sk-...",
    keyUrl: "https://platform.openai.com/api-keys",
    keyAction: "Buat API key OpenAI",
    note: "API OpenAI terpisah dari langganan ChatGPT. Pemakaian API mengikuti saldo dan tarif akun OpenAI Platform.",
  },
  gemini: {
    name: "Google AI Studio",
    subtitle: "Gemini API dengan pilihan Free Tier",
    model: "gemini-2.5-flash",
    keyLabel: "Gemini API key",
    keyPlaceholder: "AIza...",
    keyUrl: "https://aistudio.google.com/apikey",
    keyAction: "Buat key Google AI Studio",
    note: "Cocok untuk mulai tanpa biaya pada model dan kuota Free Tier yang tersedia di akun Google Anda.",
  },
  cloudflare: {
    name: "Cloudflare Workers AI",
    subtitle: "Model open source · tersedia paket Free dan Paid",
    model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    keyLabel: "Cloudflare API token · satu token per baris",
    keyPlaceholder: "Token API Cloudflare, satu per baris (maks. 20)",
    keyUrl: "https://dash.cloudflare.com/?to=/:account/workers/ai",
    keyAction: "Buka Workers AI Cloudflare",
    note: "Free mendapat 10.000 Neurons per hari per akun Cloudflare (reset 00.00 UTC); di atasnya perlu paket berbayar. Beberapa token pada Account ID yang sama berbagi kuota. Buat token Workers AI dengan izin Read dan Edit.",
  },
} as const;

// Keep model selection independent from provider catalog endpoints. Catalog
// APIs are inconsistent across providers and should not block changing a model.
// The save endpoint still tests the selected model before making it active.
const MODEL_OPTIONS = {
  openai: [
    { id: "gpt-5-mini", label: "GPT-5 mini · direkomendasikan" },
    { id: "gpt-5", label: "GPT-5" },
    { id: "gpt-4.1-mini", label: "GPT-4.1 mini" },
    { id: "gpt-4.1", label: "GPT-4.1" },
    { id: "gpt-4o-mini", label: "GPT-4o mini" },
  ],
  gemini: [
    { id: "gemini-2.5-flash-lite", label: "Gemini 2.5 Flash-Lite · hemat" },
    { id: "gemini-2.5-flash", label: "Gemini 2.5 Flash · direkomendasikan" },
    { id: "gemini-2.5-pro", label: "Gemini 2.5 Pro" },
    { id: "gemini-2.0-flash-lite", label: "Gemini 2.0 Flash-Lite" },
    { id: "gemini-2.0-flash", label: "Gemini 2.0 Flash" },
  ],
  cloudflare: [
    { id: "@cf/meta/llama-3.3-70b-instruct-fp8-fast", label: "Llama 3.3 70B · direkomendasikan" },
    { id: "@cf/meta/llama-3.1-8b-instruct", label: "Llama 3.1 8B · ringan" },
    { id: "@cf/meta/llama-3-8b-instruct", label: "Llama 3 8B · ringan" },
    { id: "@hf/nousresearch/hermes-2-pro-mistral-7b", label: "Hermes 2 Pro Mistral 7B" },
    { id: "@cf/deepseek-ai/deepseek-r1-distill-qwen-32b", label: "DeepSeek R1 Distill Qwen 32B" },
  ],
} as const;

function dateTime(value: string | null) {
  if (!value) return null;
  return new Intl.DateTimeFormat("id-ID", { dateStyle: "medium", timeStyle: "short" }).format(new Date(value));
}

export default function AiProviderSettings({ initialSettings }: { initialSettings: AiSettingsView }) {
  const [settings, setSettings] = useState(initialSettings);
  const [provider, setProvider] = useState<"openai" | "gemini" | "cloudflare">(initialSettings.provider === "openai" || initialSettings.provider === "cloudflare" ? initialSettings.provider : "gemini");
  const [model, setModel] = useState(initialSettings.model || PROVIDERS[initialSettings.provider === "openai" || initialSettings.provider === "cloudflare" ? initialSettings.provider : "gemini"].model);
  const [apiKey, setApiKey] = useState("");
  const [accountId, setAccountId] = useState(initialSettings.accountId || "");
  const [busy, setBusy] = useState<"save" | "test" | null>(null);
  const [message, setMessage] = useState<string | null>(null);
  const [isError, setIsError] = useState(false);
  const selected = PROVIDERS[provider];

  function chooseProvider(value: "openai" | "gemini" | "cloudflare") {
    setProvider(value);
    setModel(value === settings.provider ? settings.model : PROVIDERS[value].model);
    setApiKey("");
    setAccountId(value === settings.provider ? settings.accountId || "" : "");
    setMessage(null);
    setIsError(false);
  }

  async function save() {
    if (!apiKey.trim() && (!settings.hasKey || settings.provider !== provider)) {
      setIsError(true);
      setMessage(`Masukkan ${selected.keyLabel} terlebih dahulu.`);
      return;
    }
    setBusy("save");
    setMessage(null);
    setIsError(false);
    try {
      const response = await fetch("/api/optimizer/settings", {
        method: "PATCH",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ provider, model, apiKey, accountId }),
      });
      const result = await response.json().catch(() => null) as { ok?: boolean; data?: AiSettingsView; message?: string; error?: string } | null;
      if (!response.ok || !result?.ok || !result.data) throw new Error(result?.error || "Pengaturan AI gagal disimpan.");
      setSettings(result.data);
      setApiKey("");
      setMessage(result.message || "Pengaturan AI tersimpan.");
    } catch (error) {
      setIsError(true);
      setMessage(error instanceof Error ? error.message : "Pengaturan AI gagal disimpan.");
    } finally {
      setBusy(null);
    }
  }

  async function test() {
    setBusy("test");
    setMessage(null);
    setIsError(false);
    try {
      const response = await fetch("/api/optimizer/settings", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ action: "test", provider, model, apiKey, accountId }),
      });
      const result = await response.json().catch(() => null) as { ok?: boolean; data?: AiSettingsView; message?: string; error?: string } | null;
      if (result?.data) setSettings(result.data);
      if (!response.ok || !result?.ok) throw new Error(result?.error || "Uji koneksi AI gagal.");
      setMessage(result.message || "Koneksi AI berhasil.");
    } catch (error) {
      setIsError(true);
      setMessage(error instanceof Error ? error.message : "Uji koneksi AI gagal.");
    } finally {
      setBusy(null);
    }
  }

  return <section className="scroll-mt-20 overflow-hidden rounded-xl border border-violet-200 bg-white shadow-sm dark:border-violet-900 dark:bg-slate-900" id="ai-provider">
    <div className="flex flex-wrap items-start justify-between gap-3 border-b border-violet-100 bg-violet-50/60 px-5 py-4 dark:border-violet-950 dark:bg-violet-950/20">
      <div>
        <div className="text-[10px] font-black uppercase tracking-[0.14em] text-violet-700 dark:text-violet-300">Integrasi AI</div>
        <h2 className="mt-1 font-bold text-slate-950 dark:text-white">Provider AI · OpenAI, Google, Cloudflare</h2>
        <p className="mt-1 max-w-3xl text-xs leading-5 text-slate-500">Simpan beberapa key terenkripsi. Jika key terkena limit atau gangguan sementara, Agent mencoba key berikutnya. Key tidak pernah ditampilkan kembali.</p>
      </div>
      <span className={`rounded-full px-3 py-1.5 text-xs font-black ${settings.configured ? "bg-emerald-100 text-emerald-800" : "bg-amber-100 text-amber-800"}`}>
        {settings.configured ? `${settings.provider === "openai" ? "OpenAI" : settings.provider === "cloudflare" ? "Cloudflare Workers AI" : settings.provider === "gemini" ? "Gemini" : "AI custom"} ${settings.lastTestStatus === "success" ? "teruji" : "key tersimpan"}` : "Belum terhubung"}
      </span>
    </div>

    <div className="p-5">
      <div className="grid gap-3 md:grid-cols-3">
        {(Object.keys(PROVIDERS) as Array<keyof typeof PROVIDERS>).map((value) => {
          const item = PROVIDERS[value];
          const active = provider === value;
          return <button aria-pressed={active} className={`rounded-xl border p-4 text-left transition ${active ? "border-violet-500 bg-violet-50 ring-2 ring-violet-100 dark:bg-violet-950/30" : "border-slate-200 hover:border-slate-300 dark:border-slate-700"}`} key={value} onClick={() => chooseProvider(value)} type="button">
            <div className="flex items-center justify-between gap-3"><div className="font-black text-slate-950 dark:text-white">{item.name}</div><span className={`h-4 w-4 rounded-full border-4 ${active ? "border-violet-600 bg-white" : "border-slate-300 bg-white"}`} /></div>
            <div className="mt-1 text-xs font-semibold text-slate-600 dark:text-slate-300">{item.subtitle}</div>
            <div className="mt-3 text-[11px] leading-5 text-slate-500">{item.note}</div>
          </button>;
        })}
      </div>

      <p className="mt-4 text-xs text-slate-500">Pilih model dari daftar, lalu simpan. Sellfin menguji model ke provider sebelum mengaktifkannya. Untuk multi-key, masukkan satu key per baris; key yang tersimpan tidak perlu dimasukkan ulang saat hanya mengganti model.</p>
      <div className={`mt-5 grid gap-4 lg:items-end ${provider === "cloudflare" ? "lg:grid-cols-[1fr_1fr_1fr_auto]" : "lg:grid-cols-[1fr_1fr_auto]"}`}>
        <label><span className="muted-label">Model AI</span><select className="mt-1.5 w-full rounded-lg border border-slate-200 bg-white px-3 py-2.5 text-sm dark:border-slate-700 dark:bg-slate-950" value={model} onChange={(event) => setModel(event.target.value)}>{model && !MODEL_OPTIONS[provider].some((item) => item.id === model) ? <option value={model}>{model} · model tersimpan</option> : null}{MODEL_OPTIONS[provider].map((item) => <option key={item.id} value={item.id}>{item.label}</option>)}</select></label>
        {provider === "cloudflare" ? <label><span className="muted-label">Account ID Cloudflare</span><input autoComplete="off" className="mt-1.5 w-full rounded-lg border border-slate-200 bg-white px-3 py-2.5 text-sm dark:border-slate-700 dark:bg-slate-950" placeholder="32 karakter dari dashboard Cloudflare" value={accountId} onChange={(event) => setAccountId(event.target.value)} /></label> : null}
        <label className={provider === "cloudflare" ? "lg:col-span-1" : ""}><span className="muted-label">{selected.keyLabel}</span><textarea autoComplete="off" className="mt-1.5 min-h-[44px] w-full rounded-lg border border-slate-200 bg-white px-3 py-2.5 text-sm [-webkit-text-security:disc] dark:border-slate-700 dark:bg-slate-950" placeholder={settings.hasKey && settings.provider === provider ? `${settings.maskedKey || "Key tersimpan"}${settings.keyCount > 1 ? ` · ${settings.keyCount} key aktif` : ""} · tempel untuk mengganti` : selected.keyPlaceholder} value={apiKey} onChange={(event) => setApiKey(event.target.value)} /></label>
        <div className="flex flex-wrap gap-2"><Button loading={busy === "save"} onClick={save} variant="primary">Simpan & uji model</Button><Button disabled={!settings.configured && !apiKey.trim()} loading={busy === "test"} onClick={test} variant="secondary">Uji koneksi</Button></div>
      </div>

      <div className="mt-4 flex flex-wrap items-center justify-between gap-3 rounded-xl bg-slate-50 px-4 py-3 text-xs dark:bg-slate-950">
        <div className="text-slate-600 dark:text-slate-300">
          <b>{settings.configured ? `Aktif: ${settings.provider === "openai" ? "OpenAI" : settings.provider === "cloudflare" ? "Cloudflare Workers AI" : "Google Gemini"} · ${settings.model} · ${settings.keyCount || 1} key` : "Belum ada API key aktif"}</b>
          {settings.lastTestedAt ? <> · terakhir diuji {dateTime(settings.lastTestedAt)}</> : null}
        </div>
        <a className="font-black text-violet-700 hover:underline dark:text-violet-300" href={selected.keyUrl} rel="noreferrer" target="_blank">{selected.keyAction} ↗</a>
      </div>

      {settings.lastTestMessage && settings.provider === provider ? <div className={`mt-3 rounded-lg px-3 py-2 text-xs font-semibold ${settings.lastTestStatus === "success" ? "bg-emerald-50 text-emerald-800" : "bg-rose-50 text-rose-800"}`}>{settings.lastTestMessage}</div> : null}
      {message ? <div aria-live="polite" className={`mt-3 rounded-lg border px-3 py-2 text-xs font-semibold ${isError ? "border-rose-200 bg-rose-50 text-rose-800" : "border-emerald-200 bg-emerald-50 text-emerald-800"}`}>{message}</div> : null}
    </div>
  </section>;
}
