"use client";

import { useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import Button from "@/components/ui/Button";
import type { OptimizerProduct } from "@/lib/profitOptimizer/types";
import type { AiSettingsView } from "@/components/settings/AiProviderSettings";

type Recommendation = {
  id: string;
  category: string;
  action: string;
  priority: string;
  title: string;
  reason: string;
  productKey: string | null;
  estimatedMonthlyImpact: number | null;
  payload: unknown;
  status: string;
  beforeSnapshot: unknown;
  appliedAt: string | null;
  createdAt: string;
};

type Analysis = {
  id: string;
  shopId: string | null;
  period: string;
  status: string;
  error: string | null;
  createdAt: string;
  aiResult: unknown;
};

type View = "overview" | "price" | "ads" | "listing" | "weekly" | "history";
type DailyRecommendation = { id: string; category: string; action: string; priority: string; title: string; reason: string; productKey: string | null; payload: unknown; status: string; estimatedMonthlyImpact: number | null };
type DailyTask = { shopId: string; shopName: string; focus: string; status: string; analysisVersion: string | null; createdAt: string | null; dateFrom: string | null; dateTo: string | null; provider: string | null; model: string | null; error: string | null; summary: string | null; recommendationCount: number; recommendations: DailyRecommendation[] };
type DailyAgentState = { status: string; day: string; total: number; completed: number; failed: number; tasks: DailyTask[] };

const STATUS_LABEL: Record<string, string> = { new: "Baru", reviewed: "Ditinjau", applied: "Diterapkan", ignored: "Diabaikan", monitor: "Pantau" };
const CATEGORY_LABEL: Record<string, string> = { price: "Harga", ads: "Iklan", listing: "Listing", title: "Judul", description: "Deskripsi", image: "Gambar", general: "Bisnis" };

function money(value: number | null | undefined) {
  return value === null || value === undefined ? "Belum tersedia" : `Rp${Math.round(value).toLocaleString("id-ID")}`;
}

function object(value: unknown) {
  return value && typeof value === "object" && !Array.isArray(value) ? value as Record<string, unknown> : null;
}

function number(value: unknown) {
  return typeof value === "number" && Number.isFinite(value) ? value : null;
}

export default function OptimizerClient({
  aiSettings,
  shopId,
  period,
  dateFrom,
  dateTo,
  weeklyFrom,
  weeklyTo,
  recommendations: initialRecommendations,
  analyses,
  products,
  view,
  shops,
  ownerAutomationEnabled,
}: {
  aiSettings: AiSettingsView;
  shopId: string;
  period: string;
  dateFrom: string;
  dateTo: string;
  weeklyFrom: string;
  weeklyTo: string;
  recommendations: Recommendation[];
  analyses: Analysis[];
  products: OptimizerProduct[];
  view: View;
  shops: Array<{ shopId: string; shopName: string | null }>;
  ownerAutomationEnabled: boolean;
}) {
  const router = useRouter();
  const [busy, setBusy] = useState(false);
  const [message, setMessage] = useState<string | null>(null);
  const [statusOverrides, setStatusOverrides] = useState<Record<string, string>>({});
  const [dailyAgent, setDailyAgent] = useState<DailyAgentState | null>(null);
  const recommendations = useMemo(() => initialRecommendations.map((row) => ({ ...row, status: statusOverrides[row.id] || row.status })), [initialRecommendations, statusOverrides]);
  const productByKey = useMemo(() => new Map(products.map((product) => [product.key, product])), [products]);

  useEffect(() => {
    if (!ownerAutomationEnabled) return;
    let stopped = false;
    let timer: number | null = null;
    let previousStatus = "";
    async function refreshAgentStatus() {
      try {
        const response = await fetch("/api/optimizer/analyze", { cache: "no-store" });
        const result = await response.json() as { ok?: boolean; data?: DailyAgentState };
        if (!response.ok || !result.ok || !result.data || stopped) return;
        setDailyAgent(result.data);
        if (result.data.status === "completed" && previousStatus !== "completed") router.refresh();
        previousStatus = result.data.status;
        if (result.data.status !== "scheduled" && result.data.status !== "running" && timer !== null) {
          window.clearInterval(timer);
          timer = null;
        }
      } catch {
        // Status polling must not block the recommendations page.
      }
    }
    void refreshAgentStatus();
    timer = window.setInterval(() => { void refreshAgentStatus(); }, 15_000);
    return () => {
      stopped = true;
      if (timer !== null) window.clearInterval(timer);
    };
  }, [ownerAutomationEnabled, router]);

  async function runAnalysis(selectedPeriod: string, from: string, to: string, focus: string, onlyShopIds?: string[]) {
    setBusy(true);
    setMessage(null);
    const targets = onlyShopIds
      ? shops.filter((shop) => onlyShopIds.includes(shop.shopId))
      : shopId === "all" ? shops : shops.filter((shop) => shop.shopId === shopId);
    const results: string[] = [];
    try {
      if (!targets.length) throw new Error("Belum ada toko yang dapat dianalisis.");
      for (const [index, shop] of targets.entries()) {
        setMessage(`Menganalisis ${shop.shopName || shop.shopId} (${index + 1}/${targets.length})… Hasil yang selesai akan langsung tersimpan.`);
        try {
          const response = await fetch("/api/optimizer/analyze", {
            method: "POST",
            headers: { "content-type": "application/json" },
            body: JSON.stringify({ shopId: shop.shopId, period: selectedPeriod, dateFrom: from, dateTo: to, focus }),
          });
          const result = await response.json().catch(() => null) as { ok?: boolean; message?: string; error?: string } | null;
          if (!response.ok || !result?.ok) throw new Error(result?.error || "Analisis gagal.");
          results.push(`${shop.shopName || shop.shopId}: ${result.message || "analisis tersimpan"}`);
        } catch (error) {
          results.push(`${shop.shopName || shop.shopId}: ${error instanceof Error ? error.message : "gagal"}`);
        }
        setMessage(results.join(" · "));
        router.refresh();
      }
    } finally {
      setBusy(false);
    }
  }

  async function analyze() {
    await runAnalysis(period, dateFrom, dateTo, view);
  }

  async function analyzeWeekly() {
    await runAnalysis("weekly", weeklyFrom, weeklyTo, "overview");
  }

  async function setStatus(id: string, status: string) {
    const previous = statusOverrides[id];
    setStatusOverrides((rows) => ({ ...rows, [id]: status }));
    const response = await fetch(`/api/optimizer/recommendations/${encodeURIComponent(id)}`, {
      method: "PATCH",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ status }),
    });
    if (!response.ok) {
      setStatusOverrides((rows) => { const next = { ...rows }; if (previous) next[id] = previous; else delete next[id]; return next; });
      const result = await response.json().catch(() => null) as { error?: string } | null;
      setMessage(result?.error || "Status rekomendasi gagal disimpan.");
      return;
    }
    router.refresh();
  }

  const latest = analyses.find((row) => row.period === `${view === "weekly" ? "weekly" : period}:${view === "weekly" ? "overview" : view}` && (shopId === "all" || row.shopId === shopId));
  const latestResult = object(latest?.aiResult);
  const latestSummary = latestResult?.analysisVersion === "evidence-v2" && typeof latestResult.summary === "string" ? latestResult.summary : null;
  const effectiveConfigured = aiSettings.configured;
  const highPriorities = recommendations.filter((row) => row.priority === "high" && row.status !== "ignored");
  const impact = recommendations.filter((row) => row.status !== "ignored").reduce((sum, row) => sum + (row.estimatedMonthlyImpact || 0), 0);
  return <div className="space-y-5">
    <section className={`flex flex-wrap items-center justify-between gap-3 rounded-[14px] border px-5 py-4 shadow-sm ${effectiveConfigured ? "border-emerald-200 bg-emerald-50" : "border-amber-200 bg-amber-50"}`}>
      <div><div className="text-xs font-black uppercase tracking-[0.12em] text-slate-500">Koneksi AI</div><div className="mt-1 font-black text-slate-950">{effectiveConfigured ? `${aiSettings.provider === "openai" ? "OpenAI" : aiSettings.provider === "gemini" ? "Google Gemini" : aiSettings.provider === "cloudflare" ? "Cloudflare Workers AI" : "AI custom"} · ${aiSettings.model}` : "API AI belum diatur"}</div><p className="mt-1 text-xs text-slate-600">API key dikelola terpusat di Pengaturan &amp; Akun agar halaman analisis tetap ringkas.</p></div>
      <Link className="inline-flex min-h-9 items-center justify-center rounded-lg bg-slate-950 px-3 py-2 text-[13px] font-semibold text-white shadow-sm hover:bg-slate-800" href="/settings?shop_id=all#ai-provider">{effectiveConfigured ? "Kelola API AI" : "Atur API AI"}</Link>
    </section>

    <section className="overflow-hidden rounded-2xl border border-violet-200 bg-white shadow-sm">
      <header className="flex flex-wrap items-center justify-between gap-3 px-4 py-4 sm:px-5"><div><div className="text-[10px] font-black uppercase tracking-[0.13em] text-violet-700">Pemantauan agent</div><h2 className="mt-1 text-lg font-black text-slate-950">Tim AI Agent</h2><p className="mt-1 text-xs leading-5 text-slate-600">Analisis harian tiap toko. Buka satu spesialis untuk membaca temuannya dan rekomendasi yang tersimpan.</p></div><Button disabled={busy || !effectiveConfigured || !shops.length} onClick={() => void runAnalysis(period, dateFrom, dateTo, "team")} variant="primary">{busy ? "Tim sedang bekerja…" : !effectiveConfigured ? "Atur provider AI dahulu" : "Analisis sekarang"}</Button></header>
      {ownerAutomationEnabled ? <DailyAgentBoard state={dailyAgent} configured={effectiveConfigured} shopId={shopId} shops={shops} productsByKey={productByKey} busy={busy} onRetry={(task) => {
        if (task.dateFrom && task.dateTo) void runAnalysis("daily-auto", task.dateFrom, task.dateTo, task.focus, [task.shopId]);
      }} /> : <p className="mx-4 mb-4 rounded-xl bg-slate-50 px-3 py-2 text-xs text-slate-600">Agent otomatis berjalan pada server untuk masing-masing akun Owner. Super Admin dapat memilih toko untuk melihat hasilnya.</p>}
    </section>

    <section className="overflow-hidden rounded-2xl border border-violet-200 bg-gradient-to-br from-violet-950 via-slate-950 to-emerald-950 p-5 text-white shadow-sm sm:p-6">
      <div className="grid gap-5 lg:grid-cols-[1fr_auto] lg:items-center">
        <div><div className="text-xs font-black uppercase tracking-[0.16em] text-emerald-300">DATA BISNIS → TIM ANALIS → REKOMENDASI → PROFIT</div><h2 className="mt-2 text-2xl font-black">Analisis bisnis nyata per produk</h2><p className="mt-2 max-w-3xl text-sm leading-6 text-slate-300">Tim memeriksa penjualan terealisasi, harga, HPP Awal/Final, potongan Shopee, iklan, stok, dan performa listing. Tidak ada perubahan harga/iklan otomatis ke Shopee.</p></div>
        <div className="flex flex-col gap-2"><Button disabled={busy || (view === "ads" && shopId === "all")} onClick={view === "weekly" ? analyzeWeekly : analyze} variant="primary">{busy ? "Menganalisis toko…" : view === "weekly" ? "Analisis Catatan Mingguan" : view === "ads" && shopId === "all" ? "Pilih toko untuk analisis" : `Analisis ${view === "price" ? "Harga" : view === "ads" ? "Iklan" : view === "listing" ? "Listing" : "Profit"} Sekarang`}</Button></div>
      </div>
      <div className="mt-5 flex flex-wrap gap-2 text-xs font-bold">
        <span className={`rounded-full px-3 py-1.5 ${effectiveConfigured ? "bg-emerald-400/20 text-emerald-200" : "bg-amber-400/20 text-amber-200"}`}>{effectiveConfigured ? "AI terkonfigurasi" : "AI belum dikonfigurasi"}</span>
        <span className="rounded-full bg-white/10 px-3 py-1.5">Konteks {products.length.toLocaleString("id-ID")} produk</span>
        {latest ? <span className="rounded-full bg-white/10 px-3 py-1.5">Analisis terakhir: {new Date(latest.createdAt).toLocaleString("id-ID")}</span> : <span className="rounded-full bg-white/10 px-3 py-1.5">Belum ada riwayat analisis</span>}
      </div>
      {message ? <div className="mt-4 rounded-xl bg-white/10 px-4 py-3 text-sm font-semibold">{message}</div> : null}
      {latest?.error ? <div className="mt-4 rounded-xl bg-rose-400/15 px-4 py-3 text-sm font-semibold text-rose-100">{latest.error}</div> : null}
      {latest?.status === "completed" && latestResult?.analysisVersion !== "evidence-v2" ? <div className="mt-4 rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-950"><div className="font-black">Hasil terakhir masih memakai validasi lama</div><p className="mt-1 leading-5">Data lama tetap tersimpan di Riwayat. Jalankan Analisis Sekarang untuk memproses semua batch, memeriksa ID produk/toko, dan menampilkan bukti yang tervalidasi.</p></div> : null}
      {latest?.status === "completed" ? <div className="mt-4 rounded-xl border border-emerald-300/30 bg-emerald-400/10 px-4 py-3 text-sm text-emerald-50"><div className="font-black">Hasil analisis terakhir{latest.shopId ? ` · ${shops.find((shop) => shop.shopId === latest.shopId)?.shopName || latest.shopId}` : ""}</div><p className="mt-1 leading-6">{latestSummary || "Analisis selesai. Rekomendasi tersimpan pada bagian di bawah dan tab Riwayat."}</p></div> : null}
    </section>

    {view === "overview" ? <>
    <section className="grid gap-5 lg:grid-cols-2">
      <div id="prioritas-ai" className="scroll-mt-24 rounded-[14px] border border-slate-200 bg-white p-5 shadow-sm">
        <div className="text-xs font-black uppercase tracking-[0.12em] text-rose-600">Prioritas AI</div><h2 className="mt-1 text-lg font-black text-slate-950">Mana yang harus dikerjakan dulu?</h2>
        <div className="mt-4 space-y-3">{highPriorities.length ? highPriorities.slice(0, 5).map((row, index) => <div className="flex gap-3 rounded-xl border border-slate-200 p-3" key={row.id}><span className="grid h-7 w-7 shrink-0 place-items-center rounded-full bg-rose-100 text-xs font-black text-rose-700">{index + 1}</span><div><div className="text-sm font-black text-slate-950">{row.title}</div><div className="mt-1 text-xs leading-5 text-slate-600">{row.reason}</div></div></div>) : <Empty text={effectiveConfigured ? "Belum ada prioritas dari analisis AI." : "Prioritas akan muncul setelah API AI dikonfigurasi dan analisis dijalankan."} />}</div>
      </div>
      <div className="rounded-[14px] border border-slate-200 bg-white p-5 shadow-sm">
        <div className="text-xs font-black uppercase tracking-[0.12em] text-emerald-700">Potensi peningkatan profit</div><h2 className="mt-1 text-lg font-black text-slate-950">Estimasi dampak rekomendasi</h2>
        {impact ? <><div className="mt-5 text-3xl font-black text-emerald-700">+{money(impact)}<span className="ml-1 text-sm font-bold text-slate-500">/ bulan</span></div><p className="mt-2 text-xs leading-5 text-slate-500">Dampak hasil skenario terverifikasi.</p></> : <div className="mt-4"><Empty text="Belum dapat dihitung. AI tidak boleh menjanjikan laba bulanan tanpa skenario, volume, dan asumsi yang bisa diperiksa." /></div>}
      </div>
    </section>
    <div id="hasil-agent-keuangan" className="scroll-mt-24"><RecommendationSection title="Hasil & rekomendasi agent keuangan" description="Rekomendasi hasil analisis otomatis per toko. Tinjau alasan dan data pendukung sebelum mengubah status; perubahan operasional tidak dilakukan otomatis." categories={["general", "price", "ads", "listing", "title", "description", "image"]} recommendations={recommendations} productByKey={productByKey} onStatus={setStatus} /></div>
    </> : null}

    {view === "price" ?
    <RecommendationSection title="Rekomendasi Harga AI" description="Harga impas, minimum aman, harga rekomendasi, range pengujian, dan estimasi profit." categories={["price"]} recommendations={recommendations} productByKey={productByKey} onStatus={setStatus} />
    : null}
    {view === "ads" && shopId !== "all" ?
    <RecommendationSection title="Rekomendasi Produk & Optimasi Iklan" description="Scale up, pertahankan, kurangi, pause, atau test—selalu dengan alasan berbasis data." categories={["ads", "general"]} recommendations={recommendations} productByKey={productByKey} onStatus={setStatus} />
    : null}
    {view === "listing" ?
    <RecommendationSection title="Optimasi Listing" description="Analisis funnel, judul, deskripsi, dan gambar tanpa mengubah listing secara otomatis." categories={["listing", "title", "description", "image"]} recommendations={recommendations} productByKey={productByKey} onStatus={setStatus} />
    : null}
  </div>;
}

function DailyAgentBoard({ state, configured, shopId, shops, productsByKey, busy, onRetry }: { state: DailyAgentState | null; configured: boolean; shopId: string; shops: Array<{ shopId: string; shopName: string | null }>; productsByKey: Map<string, OptimizerProduct>; busy: boolean; onRetry: (task: DailyTask) => void }) {
  const agents = [
    { focus: "overview", title: "Keuangan", detail: "Penjualan, settlement, biaya, dan profit" },
    { focus: "price", title: "Harga", detail: "HPP, margin, dan harga impas" },
    { focus: "ads", title: "Iklan", detail: "Belanja, ROAS, dan kampanye" },
    { focus: "listing", title: "Listing", detail: "CTR, konversi, dan kualitas produk" },
  ];
  const label: Record<string, string> = { completed: "Selesai", analyzing: "Menganalisis", scheduled: "Menunggu giliran", stale: "Perlu analisis ulang", failed: "Gagal", awaiting_ai: "AI belum siap" };
  const tone: Record<string, string> = { completed: "bg-emerald-100 text-emerald-800", analyzing: "bg-violet-100 text-violet-800", scheduled: "bg-amber-100 text-amber-800", stale: "bg-amber-100 text-amber-900", failed: "bg-rose-100 text-rose-800", awaiting_ai: "bg-slate-200 text-slate-700" };
  const visibleTasks = (state?.tasks || []).filter((task) => shopId === "all" || task.shopId === shopId);
  const total = visibleTasks.length;
  const completed = visibleTasks.filter((task) => task.status === "completed").length;
  const failed = visibleTasks.filter((task) => task.status === "failed").length;
  const pending = total - completed - failed;
  const recommendationTotal = visibleTasks.reduce((sum, task) => sum + (task.status === "completed" ? task.recommendationCount : 0), 0);
  const message = !configured ? "AI belum aktif. Periksa koneksi provider sebelum menjalankan agent." : !state ? "Menghubungkan ke status agent…" : state.status === "running" || pending > 0 ? `${completed} analisis selesai, ${pending} menunggu${failed ? `, ${failed} gagal` : ""}.` : failed ? `${completed} analisis selesai dan ${failed} gagal. Hasil sukses tetap tersimpan.` : `${completed} analisis selesai dengan ${recommendationTotal} rekomendasi untuk ditinjau.`;
  const stores = Array.from(new Map(visibleTasks.map((task) => [task.shopId, task.shopName])).entries());
  const scopeLabel = shopId === "all" ? `Semua toko · ${stores.length} toko` : shops.find((shop) => shop.shopId === shopId)?.shopName || shopId;
  return <section className="mt-4 overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-sm">
    <header className="flex flex-wrap items-center justify-between gap-3 border-b border-slate-100 bg-slate-50 px-4 py-3 sm:px-5">
      <div><div className="text-sm font-black text-slate-950">Hasil kerja · {scopeLabel}</div><p aria-live="polite" className="mt-0.5 text-xs text-slate-600">{message} Periode analisis: 7 hari. Iklan tidak diubah otomatis.</p></div>
      <div className="flex items-center gap-2"><span className="rounded-lg border border-slate-200 bg-white px-2.5 py-1.5 text-[11px] font-bold text-slate-600">{state?.day || "Menunggu"}</span>{failed > 0 ? <span className="rounded-lg bg-rose-100 px-2.5 py-1.5 text-[11px] font-black text-rose-800">{failed} gagal</span> : <span className="rounded-lg bg-emerald-100 px-2.5 py-1.5 text-[11px] font-black text-emerald-800">{completed}/{total} selesai</span>}</div>
    </header>
    <div className="grid grid-cols-2 gap-2 border-b border-slate-100 p-3 sm:grid-cols-4 sm:px-4">
      <AgentCount label="Analisis selesai" value={completed} tone="success" />
      <AgentCount label="Perlu dicoba lagi" value={failed} tone="danger" />
      <AgentCount label="Rekomendasi" value={recommendationTotal} tone="primary" />
      <AgentCount label="Menunggu" value={pending} tone="neutral" />
    </div>
    <div className="space-y-2 p-3 sm:p-4">
      {stores.length ? stores.map(([storeId, storeName]) => {
        const tasks = visibleTasks.filter((task) => task.shopId === storeId);
        const storeCompleted = tasks.filter((task) => task.status === "completed").length;
        const storeFailed = tasks.filter((task) => task.status === "failed").length;
        const storeStale = tasks.filter((task) => task.status === "stale").length;
        const storeRecommendations = tasks.reduce((sum, task) => sum + (task.status === "completed" ? task.recommendationCount : 0), 0);
        const allScope = shopId === "all";
        return <details className="group rounded-xl border border-slate-200 bg-white open:border-violet-200" key={storeId} open={!allScope}>
          <summary className="flex cursor-pointer list-none flex-wrap items-center justify-between gap-2 rounded-xl px-3 py-3 hover:bg-slate-50 [&::-webkit-details-marker]:hidden">
            <span className="flex min-w-0 items-center gap-2"><span className={`h-2.5 w-2.5 shrink-0 rounded-full ${storeFailed ? "bg-rose-500" : storeCompleted === 4 ? "bg-emerald-500" : "bg-amber-400"}`} /><span className="truncate text-sm font-black text-slate-900">{storeName}</span></span>
            <span className="flex items-center gap-2"><span className="text-[11px] font-semibold text-slate-500">{storeCompleted}/4 tervalidasi · {storeRecommendations} rekomendasi{storeFailed ? ` · ${storeFailed} gagal` : ""}{storeStale ? ` · ${storeStale} perlu ulang` : ""}</span><span aria-hidden="true" className="text-slate-400 transition group-open:rotate-180">⌄</span></span>
          </summary>
          <div className="border-t border-slate-100 px-3 py-2">
            <div className="divide-y divide-slate-100">{agents.map((agent) => {
              const task = tasks.find((row) => row.focus === agent.focus);
              const status = task?.status || "scheduled";
              const resultView = agent.focus === "price" ? "price" : agent.focus === "ads" ? "ads" : agent.focus === "listing" ? "listing" : "overview";
              const href = `/optimizer?shop_id=${encodeURIComponent(storeId)}&period=7d&view=${resultView}${resultView === "overview" ? "#hasil-agent-keuangan" : "#rekomendasi-ai"}`;
              return <article className="space-y-2 py-3" key={agent.focus}>
                <div className="flex flex-wrap items-center justify-between gap-2">
                  <div className="min-w-0"><span className="block text-xs font-black text-slate-800">{agent.title}</span><span className="mt-0.5 block text-[10px] text-slate-500">{agent.detail}</span></div>
                  <div className="flex flex-wrap items-center gap-2"><span className={`rounded-full px-2 py-1 text-[10px] font-black ${tone[status] || tone.scheduled}`}>{label[status] || status}</span>{task?.recommendationCount ? <span className="text-[10px] font-bold text-violet-800">{task.recommendationCount} rekomendasi</span> : null}{task && (task.status === "failed" || task.status === "stale") ? <Button className="min-h-8 px-2.5 text-xs" disabled={busy || !task.dateFrom || !task.dateTo} loading={busy} onClick={() => onRetry(task)} variant="secondary">{task.status === "stale" ? "Jalankan versi terbaru" : "Coba lagi tugas ini"}</Button> : null}</div>
                </div>
                <div className="space-y-2 pl-3 sm:pl-4">
                  {task?.provider ? <p className="text-[10px] text-slate-500">Model: {task.provider === "cloudflare" ? "Cloudflare Workers AI" : task.provider === "gemini" ? "Google Gemini" : task.provider === "openai" ? "OpenAI" : "AI custom"}{task.model ? ` · ${task.model}` : ""}{task.createdAt ? ` · ${new Date(task.createdAt).toLocaleString("id-ID")}` : ""}</p> : null}
                  {task?.status === "completed" ? <p className="text-xs leading-5 text-slate-700">{task.summary || (task.recommendationCount ? `${task.recommendationCount} rekomendasi tersimpan.` : "Tidak ada tindakan prioritas untuk toko ini berdasarkan data yang tersedia.")}</p> : null}
                  {task?.status === "stale" ? <p className="rounded-lg bg-amber-50 px-3 py-2 text-xs leading-5 text-amber-950">Hasil lama disimpan di Riwayat, tetapi tidak ditampilkan sebagai analisis tervalidasi. Jalankan ulang spesialis ini.</p> : null}
                  {task?.recommendations.length ? <div className="space-y-2">{task.recommendations.map((recommendation) => <article className="rounded-lg border border-slate-200 bg-slate-50 p-3" key={recommendation.id}>
                    <div className="flex flex-wrap items-center gap-1.5"><span className={`rounded px-2 py-1 text-[9px] font-black uppercase ${recommendation.priority === "high" ? "bg-rose-100 text-rose-800" : recommendation.priority === "low" ? "bg-slate-200 text-slate-700" : "bg-amber-100 text-amber-800"}`}>{recommendation.priority === "high" ? "Prioritas tinggi" : recommendation.priority === "low" ? "Prioritas rendah" : "Prioritas sedang"}</span><span className="text-[10px] font-bold text-violet-800">{CATEGORY_LABEL[recommendation.category] || recommendation.category}</span><span className="rounded bg-white px-2 py-1 text-[9px] font-bold text-slate-600">{STATUS_LABEL[recommendation.status] || recommendation.status}</span></div>
                    <h4 className="mt-2 text-xs font-black leading-5 text-slate-950">{recommendation.title}</h4>{recommendation.productKey ? <p className="mt-1 text-[10px] font-bold text-violet-800">{productsByKey.get(recommendation.productKey)?.name || recommendation.productKey}</p> : null}<p className="mt-1 text-xs leading-5 text-slate-600">{recommendation.reason}</p>{recommendation.estimatedMonthlyImpact !== null ? <p className="mt-2 text-[11px] font-black text-emerald-700">Potensi menurut AI: {money(recommendation.estimatedMonthlyImpact)} / bulan</p> : null}
                  </article>)}</div> : task?.status === "completed" && task.recommendationCount === 0 ? <div className="rounded-lg border border-emerald-100 bg-emerald-50 px-3 py-2 text-xs text-emerald-900">Tidak ada rekomendasi tindakan untuk analisis ini.</div> : null}
                  {task?.recommendationCount && task.recommendations.length < task.recommendationCount ? <p className="text-[10px] text-slate-500">Menampilkan {task.recommendations.length} dari {task.recommendationCount}. Buka tab terkait untuk melihat dan mengelola semua rekomendasi.</p> : null}
                  {task?.error ? <div className="rounded-lg border border-rose-200 bg-rose-50 p-3"><p className="text-xs font-bold text-rose-900">Analisis ini gagal</p><p className="mt-1 text-xs leading-5 text-rose-800">{friendlyAgentError(task.error)}</p><details className="mt-2"><summary className="cursor-pointer text-[11px] font-bold text-rose-800">Detail teknis</summary><pre className="mt-2 max-h-28 overflow-auto whitespace-pre-wrap break-words rounded bg-white p-2 text-[10px] leading-4 text-slate-600">{task.error}</pre></details></div> : null}
                  {task?.status === "completed" && task.recommendationCount > 0 ? <Link className="inline-flex min-h-9 items-center rounded-lg bg-violet-700 px-3 py-2 text-xs font-black text-white hover:bg-violet-800" href={href}>Tinjau dan kelola rekomendasi →</Link> : null}
                </div>
              </article>;
            })}</div>
            {storeFailed > 0 ? <p className="mt-2 rounded-lg bg-rose-50 px-3 py-2 text-[11px] leading-5 text-rose-800">{storeFailed} dari 4 analisis gagal. Buka spesialis yang gagal dan gunakan “Coba lagi” agar tugas yang sudah sukses tidak dijalankan ulang.</p> : null}
          </div>
        </details>;
      }) : <div className="rounded-xl border border-dashed border-slate-200 bg-slate-50 px-4 py-6 text-center text-sm text-slate-600">{configured ? "Belum ada hasil agent untuk toko ini hari ini." : "Atur provider AI untuk mengaktifkan analisis agent."}</div>}
    </div>
  </section>;
}

function friendlyAgentError(error: string) {
  if (/429|quota|rate.?limit/i.test(error)) return "Batas penggunaan API AI sudah tercapai. Tidak ada rekomendasi baru dari tugas ini. Periksa kuota/billing provider atau ganti provider di Pengaturan AI.";
  if (/503|unavailable|high demand/i.test(error)) return "Layanan AI sedang padat. Hasil tugas ini gagal disimpan; coba ulang hanya spesialis ini setelah provider pulih.";
  if (/context_length|context window/i.test(error)) return "Data yang dikirim melebihi batas model. Kurangi ukuran konteks atau pilih model dengan jendela konteks lebih besar.";
  if (/timeout|timed out|aborted/i.test(error)) return "Permintaan terlalu lama dan tidak selesai. Coba lagi setelah koneksi/provider stabil.";
  if (/JSON yang valid|strukturnya tidak sesuai laporan/i.test(error)) return "Provider AI membalas, tetapi format hasilnya tidak bisa dibaca Sellfin. Tidak ada rekomendasi dari tugas ini yang disimpan; gunakan tombol Coba lagi tugas ini untuk mengulang spesialis ini saja.";
  return "Provider AI gagal memproses tugas. Buka detail teknis di bawah atau uji koneksi provider pada Pengaturan AI.";
}

function AgentCount({ label, value, tone }: { label: string; value: number; tone: "success" | "danger" | "primary" | "neutral" }) {
  const styles = { success: "border-emerald-100 bg-white text-emerald-800", danger: "border-rose-100 bg-white text-rose-800", primary: "border-violet-100 bg-white text-violet-900", neutral: "border-slate-100 bg-white text-slate-700" };
  return <div className={`rounded-lg border px-2 py-2 text-center ${styles[tone]}`}><div className="text-base font-black tabular-nums sm:text-lg">{value.toLocaleString("id-ID")}</div><div className="text-[9px] font-bold uppercase tracking-wide opacity-75 sm:text-[10px]">{label}</div></div>;
}

function RecommendationSection({ title, description, categories, recommendations, productByKey, onStatus }: { title: string; description: string; categories: string[]; recommendations: Recommendation[]; productByKey: Map<string, OptimizerProduct>; onStatus: (id: string, status: string) => void }) {
  const rows = recommendations.filter((row) => categories.includes(row.category));
  return <section id="rekomendasi-ai" className="scroll-mt-24 rounded-[14px] border border-slate-200 bg-white p-5 shadow-sm"><div><h2 className="text-[15px] font-bold text-slate-900">{title}</h2><p className="mt-1 text-xs leading-5 text-slate-500">{description}</p></div><div className="mt-5 space-y-4">{rows.length ? rows.map((row) => <RecommendationCard key={row.id} row={row} product={row.productKey ? productByKey.get(row.productKey) : undefined} onStatus={onStatus} />) : <Empty text="Belum ada rekomendasi AI pada kategori ini." />}</div></section>;
}

function RecommendationCard({ row, product, onStatus }: { row: Recommendation; product?: OptimizerProduct; onStatus: (id: string, status: string) => void }) {
  const router = useRouter();
  const payload = object(row.payload);
  const isTextSuggestion = row.category === "title" || row.category === "description";
  const suggestedText = typeof payload?.recommendedText === "string" ? payload.recommendedText.trim() : "";
  const currentText = row.category === "title" ? product?.name || "" : row.category === "description" ? product?.description || "" : "";
  const [editingText, setEditingText] = useState(false);
  const [draftText, setDraftText] = useState(suggestedText);
  const [applyingText, setApplyingText] = useState(false);
  const [applyFeedback, setApplyFeedback] = useState<string | null>(null);
  async function applyText() {
    const text = (editingText ? draftText : suggestedText).trim();
    if (!text || !window.confirm(`Kirim ${row.category === "title" ? "judul" : "deskripsi"} baru ke Shopee untuk ${product?.name || "produk ini"}?`)) return;
    setApplyingText(true);
    setApplyFeedback(null);
    try {
      const response = await fetch(`/api/optimizer/recommendations/${encodeURIComponent(row.id)}`, {
        method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ text }),
      });
      const result = await response.json() as { ok?: boolean; message?: string; error?: string };
      if (!response.ok || !result.ok) throw new Error(result.error || "Shopee belum mengonfirmasi perubahan listing.");
      setApplyFeedback(result.message || "Perubahan terkonfirmasi di Shopee.");
      router.refresh();
    } catch (error) {
      setApplyFeedback(error instanceof Error ? error.message : "Gagal menerapkan rekomendasi.");
    } finally {
      setApplyingText(false);
    }
  }
  const before = object(row.beforeSnapshot);
  const priceFields = row.category === "price" ? [
    ["Harga sekarang", number(payload?.currentPrice) ?? product?.price], ["Harga impas", number(payload?.breakEvenPrice) ?? product?.breakEvenPrice],
    ["Harga minimum aman", number(payload?.minimumSafePrice)], ["Harga rekomendasi", number(payload?.recommendedPrice)],
    ["Range bawah", number(payload?.testRangeMin)], ["Range atas", number(payload?.testRangeMax)], ["Estimasi profit", number(payload?.estimatedProfit)],
  ] as Array<[string, number | null | undefined]> : [];
  return <article className="rounded-2xl border border-slate-200 p-4">
    <div className="flex flex-wrap items-start justify-between gap-3"><div><div className="flex flex-wrap gap-2"><span className={`rounded-full px-2.5 py-1 text-[10px] font-black uppercase ${row.priority === "high" ? "bg-rose-100 text-rose-700" : row.priority === "low" ? "bg-slate-100 text-slate-600" : "bg-amber-100 text-amber-700"}`}>{row.priority === "high" ? "Prioritas tinggi" : row.priority === "low" ? "Prioritas rendah" : "Prioritas sedang"}</span><span className="rounded-full bg-violet-100 px-2.5 py-1 text-[10px] font-black uppercase text-violet-700">{CATEGORY_LABEL[row.category] || row.category}</span><span className="rounded-full bg-slate-100 px-2.5 py-1 text-[10px] font-black uppercase text-slate-700">{row.action.replaceAll("_", " ")}</span></div><h3 className="mt-2 font-black text-slate-950">{row.title}</h3>{product ? <div className="mt-1 text-xs font-semibold text-slate-500">{product.name} · {product.shopName}</div> : null}</div><select aria-label="Status rekomendasi" className="rounded-lg border border-slate-200 bg-white px-3 py-2 text-xs font-bold" value={row.status} onChange={(event) => onStatus(row.id, event.target.value)}>{Object.entries(STATUS_LABEL).map(([value, label]) => <option disabled={isTextSuggestion && value === "applied" && row.status !== "applied"} key={value} value={value}>{label}</option>)}</select></div>
    <p className="mt-3 text-sm leading-6 text-slate-700">{row.reason}</p>
    {product ? <div className="mt-4 rounded-xl border border-sky-100 bg-sky-50/60 p-3"><div className="text-[10px] font-black uppercase tracking-wide text-sky-900">Data Sellfin yang mendukung · {product.key}</div><div className="mt-2 grid grid-cols-2 gap-2 sm:grid-cols-4 xl:grid-cols-6">{[
      ["Terjual", `${product.soldQuantity.toLocaleString("id-ID")} unit`], ["Order", product.orderCount.toLocaleString("id-ID")],
      ["Harga", money(product.price)], ["HPP Awal", money(product.hppAwal)], ["HPP Final", money(product.hppFinal)],
      ["Dana settlement", money(product.realizedIncome)], ["Potongan Shopee", money(product.shopeeCosts)],
      ["Biaya iklan", money(product.adsCost)], ["Profit", money(product.profit)],
      ["Margin", product.margin === null ? "Belum tersedia" : `${product.margin.toFixed(1)}%`],
      ["ROAS iklan", product.roas === null ? "Belum teratribusi" : `${product.roas.toFixed(2)}×`],
      ["Stok", product.stock === null ? "Belum tersedia" : product.stock.toLocaleString("id-ID")],
    ].map(([label, value]) => <div className="rounded-lg bg-white px-2.5 py-2" key={label}><div className="text-[9px] font-bold uppercase tracking-wide text-slate-500">{label}</div><div className="mt-1 text-xs font-black text-slate-900">{value}</div></div>)}</div><p className="mt-2 text-[10px] text-slate-500">Nilai berasal dari produk/toko yang terhubung pada analisis ini. Profit dan ROAS yang belum lengkap ditampilkan sebagai tidak tersedia.</p></div> : null}
    {priceFields.length ? <div className="mt-4 grid gap-2 sm:grid-cols-2 xl:grid-cols-4">{priceFields.map(([label, value]) => <div className="rounded-xl bg-slate-50 p-3" key={label}><div className="text-[10px] font-black uppercase tracking-wide text-slate-500">{label}</div><div className="mt-1 text-sm font-black text-slate-950">{money(value)}</div></div>)}</div> : null}
    {row.estimatedMonthlyImpact !== null ? <div className="mt-3 text-xs font-black text-emerald-700">Estimasi dampak: +{money(row.estimatedMonthlyImpact)} / bulan</div> : null}
    {row.status === "applied" && before && product ? <BeforeAfter before={before} after={product} /> : null}
    {isTextSuggestion ? <div className="mt-4 space-y-3 rounded-xl border border-slate-200 bg-slate-50 p-3">
      <div className="text-[11px] font-black uppercase text-slate-500">{row.category === "title" ? "Judul" : "Deskripsi"} saat ini</div><p className="whitespace-pre-wrap text-xs text-slate-700">{currentText || "Belum tersedia di data Sellfin"}</p>
      <div className="text-[11px] font-black uppercase text-violet-700">Usulan AI · periksa fakta sebelum kirim</div>
      {editingText ? <textarea aria-label="Edit teks rekomendasi" className="min-h-28 w-full rounded-lg border border-slate-300 bg-white p-3 text-sm" value={draftText} onChange={(event) => setDraftText(event.target.value)} /> : <p className="whitespace-pre-wrap rounded-lg bg-white p-3 text-sm text-slate-900">{suggestedText || "AI belum memberikan teks usulan yang dapat diterapkan."}</p>}
      {applyFeedback ? <p role="status" className="text-xs font-semibold text-slate-700">{applyFeedback}</p> : null}
      <div className="flex flex-wrap gap-2"><Button disabled={!suggestedText || applyingText || row.status === "applied"} onClick={applyText} variant="primary">{applyingText ? "Memverifikasi Shopee…" : "Terapkan ke Shopee"}</Button><Button onClick={() => { setEditingText((value) => !value); onStatus(row.id, "reviewed"); }} variant="secondary">{editingText ? "Selesai edit" : "Edit teks"}</Button><Button onClick={() => onStatus(row.id, "ignored")} variant="secondary">Abaikan</Button></div>
    </div> : null}
  </article>;
}

function BeforeAfter({ before, after }: { before: Record<string, unknown>; after: OptimizerProduct }) {
  const rows = [
    ["Harga", number(before.price), after.price], ["ROAS", number(before.roas), after.roas],
    ["Conversion", number(before.conversionRate), after.conversionRate], ["Produk terjual", number(before.soldQuantity), after.soldQuantity],
    ["Profit", number(before.profit), after.profit],
  ] as Array<[string, number | null, number | null]>;
  return <div className="mt-4 overflow-hidden rounded-xl border border-emerald-200"><div className="bg-emerald-50 px-3 py-2 text-xs font-black text-emerald-800">Pemantauan sebelum vs sesudah</div><table className="w-full text-xs"><thead><tr className="text-slate-500"><th className="px-3 py-2 text-left">Metrik</th><th className="px-3 py-2 text-right">Sebelum</th><th className="px-3 py-2 text-right">Sekarang</th></tr></thead><tbody>{rows.map(([label, oldValue, newValue]) => <tr className="border-t border-slate-100" key={label}><td className="px-3 py-2 font-bold">{label}</td><td className="px-3 py-2 text-right">{oldValue === null ? "Belum tersedia" : label === "Harga" || label === "Profit" ? money(oldValue) : oldValue.toLocaleString("id-ID")}</td><td className="px-3 py-2 text-right font-black">{newValue === null ? "Belum tersedia" : label === "Harga" || label === "Profit" ? money(newValue) : newValue.toLocaleString("id-ID")}</td></tr>)}</tbody></table></div>;
}

function Empty({ text }: { text: string }) {
  return <div className="rounded-xl border border-dashed border-slate-300 bg-slate-50 px-4 py-5 text-center text-sm text-slate-500">{text}</div>;
}
