import { requireOrg } from "@/lib/ctx";
import { STAGES, STAGE_LABEL, STAGE_EVENT, type Stage } from "@/lib/stage-defs";

type Row = Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any

const idr = (n: number) =>
  new Intl.NumberFormat("id-ID", { style: "currency", currency: "IDR", maximumFractionDigits: 0 }).format(n);
const pct = (a: number, b: number) => (b ? `${Math.round((a / b) * 100)}%` : "-");

export default async function Dashboard() {
  const c = await requireOrg();
  const since = new Date(Date.now() - 30 * 864e5).toISOString();
  const noClicks = c.role === "cs"; // CS tidak punya akses ke data klik dan log event

  const [leadsR, clicksR, ordersR, histR, eventsR] = await Promise.all([
    c.db.from("leads").select("id, temperature, source_click_id").gte("created_at", since).limit(5000),
    noClicks ? Promise.resolve({ data: [] as Row[] }) : c.db.from("clicks").select("id, utm_campaign").gte("clicked_at", since).limit(5000),
    c.db.from("orders").select("lead_id, amount").gte("paid_at", since).limit(5000),
    c.db.from("lead_stage_history").select("lead_id, stage").gte("occurred_at", since).limit(20000),
    noClicks ? Promise.resolve({ data: [] as Row[] }) : c.db.from("meta_events").select("event_name, status").gte("created_at", since).limit(20000),
  ]);

  const leads: Row[] = leadsR.data ?? [];
  const clicks: Row[] = clicksR.data ?? [];
  const orders: Row[] = ordersR.data ?? [];
  const hist: Row[] = histR.data ?? [];
  const events: Row[] = eventsR.data ?? [];

  const revenue = orders.reduce((t, o) => t + Number(o.amount), 0);
  const hot = leads.filter((l) => l.temperature === "hot").length;

  // jumlah lead unik per tahap
  const reached = (s: Stage) => new Set(hist.filter((h) => h.stage === s).map((h) => h.lead_id)).size;
  const funnel = (["contacted", "product_selected", "checkout", "payment_info", "purchased"] as Stage[]).map((s) => ({
    s,
    n: reached(s),
  }));
  const top = Math.max(clicks.length, ...funnel.map((f) => f.n), 1);

  // performa per kampanye (UTM): klik -> lead -> closing -> omzet
  const camp = new Map<string, { clicks: number; leads: number; buys: number; rev: number }>();
  const clickCamp = new Map<string, string>();
  const get = (k: string) => camp.get(k) ?? camp.set(k, { clicks: 0, leads: 0, buys: 0, rev: 0 }).get(k)!;
  for (const k of clicks) {
    const name = k.utm_campaign || "(tanpa kampanye)";
    clickCamp.set(k.id, name);
    get(name).clicks++;
  }
  const leadCamp = new Map<string, string>();
  for (const l of leads) {
    const name = (l.source_click_id && clickCamp.get(l.source_click_id)) || "(tanpa kampanye)";
    leadCamp.set(l.id, name);
    if (!noClicks) get(name).leads++;
  }
  const buyers = new Set(hist.filter((h) => h.stage === "purchased").map((h) => h.lead_id));
  if (!noClicks) {
    buyers.forEach((id) => {
      const name = leadCamp.get(id);
      if (name) get(name).buys++;
    });
    for (const o of orders) {
      const name = leadCamp.get(o.lead_id);
      if (name) get(name).rev += Number(o.amount);
    }
  }
  const campRows = [...camp.entries()].sort((a, b) => b[1].rev - a[1].rev || b[1].clicks - a[1].clicks);

  // status pengiriman event ke Meta
  const ev = new Map<string, Record<string, number>>();
  for (const e of events) {
    const m = ev.get(e.event_name) ?? ev.set(e.event_name, {}).get(e.event_name)!;
    m[e.status] = (m[e.status] ?? 0) + 1;
  }
  const order = ["Lead", ...STAGES.map((s) => STAGE_EVENT[s]).filter(Boolean)] as string[];

  return (
    <>
      <h1>Dashboard · 30 hari terakhir</h1>
      <div className="grid">
        {!noClicks && <div className="card stat"><b>{clicks.length}</b><span>Klik tombol WA</span></div>}
        <div className="card stat"><b>{leads.length}</b><span>Lead masuk chat</span></div>
        <div className="card stat"><b className="hot">{hot}</b><span>Lead hot</span></div>
        <div className="card stat"><b>{buyers.size}</b><span>Closing</span></div>
        <div className="card stat"><b>{idr(revenue)}</b><span>Omzet tercatat</span></div>
      </div>

      <div className="card">
        <h2>Funnel</h2>
        <div className="scroll">
          <table>
            <tbody>
              {!noClicks && (
                <tr>
                  <td>Klik tombol WA (Lead)</td>
                  <td style={{ width: "50%" }}><div className="bar" style={{ width: `${(clicks.length / top) * 100}%` }} /></td>
                  <td>{clicks.length}</td>
                  <td className="muted">100%</td>
                </tr>
              )}
              {funnel.map((f) => (
                <tr key={f.s}>
                  <td>{STAGE_LABEL[f.s]} <span className="muted">({STAGE_EVENT[f.s]})</span></td>
                  <td style={{ width: "50%" }}><div className="bar" style={{ width: `${(f.n / top) * 100}%` }} /></td>
                  <td>{f.n}</td>
                  <td className="muted">{noClicks ? "" : pct(f.n, clicks.length)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      {!noClicks && (
        <>
          <div className="card">
            <h2>Performa per kampanye (utm_campaign)</h2>
            <div className="scroll">
              <table>
                <thead><tr><th>Kampanye</th><th>Klik</th><th>Lead</th><th>Closing</th><th>Omzet</th><th>Klik→Lead</th></tr></thead>
                <tbody>
                  {campRows.map(([name, v]) => (
                    <tr key={name}>
                      <td>{name}</td><td>{v.clicks}</td><td>{v.leads}</td><td>{v.buys}</td><td>{idr(v.rev)}</td><td>{pct(v.leads, v.clicks)}</td>
                    </tr>
                  ))}
                  {!campRows.length && <tr><td colSpan={6} className="muted">Belum ada data.</td></tr>}
                </tbody>
              </table>
            </div>
          </div>

          <div className="card">
            <h2>Pengiriman event ke Meta</h2>
            <div className="scroll">
              <table>
                <thead><tr><th>Event</th><th>Terkirim</th><th>Menunggu</th><th>Gagal</th><th>Dilewati</th></tr></thead>
                <tbody>
                  {order.map((name) => {
                    const m = ev.get(name) ?? {};
                    return (
                      <tr key={name}>
                        <td>{name}</td>
                        <td className="ok">{m.sent ?? 0}</td><td>{m.pending ?? 0}</td>
                        <td className={m.failed ? "hot" : ""}>{m.failed ?? 0}</td><td className="muted">{m.skipped ?? 0}</td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </div>
        </>
      )}
    </>
  );
}
