// App shell: top bar station + routing dashboard/detail + Tweaks.

const APP_VERSION = "1.4.0";

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "qcLayout": "list",
  "accent": "#2563eb",
  "beep": true,
  "simulator": true,
  "density": "regular"
}/*EDITMODE-END*/;

const ACCENTS = {
  "#2563eb": ["#2563eb", "#eff4ff", "#1d4ed8"],   // biru
  "#0d9488": ["#0d9488", "#effbf8", "#0f766e"],   // teal
  "#7c3aed": ["#7c3aed", "#f5f0ff", "#6d28d9"],   // ungu
  "#ea580c": ["#ea580c", "#fff3ec", "#c2410c"],   // oranye
};

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [orders, setOrders] = React.useState([]);
  const [pagination, setPagination] = React.useState({ page: 1, totalPages: 1, total: 0 });
  const [counts, setCounts] = React.useState({ pending: 0, proses: 0, done: 0 });
  const [orderFilter, setOrderFilter] = React.useState("done");
  const [orderPage, setOrderPage] = React.useState(1);
  const [couriers, setCouriers] = React.useState(window.QC_COURIERS || {});
  const [auth, setAuth] = React.useState(() => QC_API.getStoredUser());
  const [view, setView] = React.useState({ name: "dashboard", resi: null });
  const [toasts, push] = useToasts();
  const [clock, setClock] = React.useState("");
  const [loadingOrders, setLoadingOrders] = React.useState(false);
  const [lastUpdated, setLastUpdated] = React.useState(null);

  React.useEffect(() => {
    const tick = () => setClock(new Date().toLocaleTimeString("id-ID", { hour: "2-digit", minute: "2-digit" }));
    tick(); const id = setInterval(tick, 10000); return () => clearInterval(id);
  }, []);

  // Terapkan accent ke CSS vars
  React.useEffect(() => {
    const [base, bg, ink2] = ACCENTS[t.accent] || ACCENTS["#2563eb"];
    const r = document.documentElement.style;
    r.setProperty("--pri", base); r.setProperty("--pri-bg", bg); r.setProperty("--pri-ink2", ink2);
  }, [t.accent]);

  React.useEffect(() => {
    document.documentElement.setAttribute("data-density", t.density);
  }, [t.density]);

  const fetchOrders = React.useCallback(async (page, filter) => {
    if (!auth) return;
    setLoadingOrders(true);
    try {
      const data = await QC_API.getOrders({ page, filter });
      setOrders(data.orders);
      setPagination({ page: data.page, totalPages: data.totalPages, total: data.total });
      if (data.counts) setCounts(data.counts);
      setLastUpdated(new Date());
      if (data.couriers) {
        setCouriers(data.couriers);
        window.QC_COURIERS = { ...window.QC_COURIERS, ...data.couriers };
      }
    } catch (ex) {
      push({ kind: "err", msg: "Gagal memuat antrian", sub: ex.message });
    } finally {
      setLoadingOrders(false);
    }
  }, [auth]);

  // Muat orders saat login/page/filter berubah
  React.useEffect(() => {
    fetchOrders(orderPage, orderFilter);
  }, [orderPage, orderFilter, auth]);

  const openOrder = (resi) => setView({ name: "detail", resi });

  // Order ditemukan via server search — inject ke list lalu buka
  const openSearchedOrder = (order) => {
    setOrders((prev) => {
      const exists = prev.find((o) => o.resi === order.resi);
      return exists ? prev : [order, ...prev];
    });
    setView({ name: "detail", resi: order.resi });
  };
  const goDash = () => setView({ name: "dashboard", resi: null });
  const goReport = () => { window.location.href = '/report'; };
  const goRetur  = () => { window.location.href = '/retur'; };
  const goKeuangan = () => { window.location.href = '/keuangan'; };
  const goWebhook = () => { window.location.href = '/webhook'; };
  const goLogAktivitas = () => { window.location.href = '/log-aktivitas'; };

  const login = (u) => { setAuth(u); setView({ name: "dashboard", resi: null }); };
  const logout = () => { QC_API.logout(); setAuth(null); setOrders([]); setOrderPage(1); setOrderFilter("done"); };

  React.useEffect(() => {
    const onExpired = () => {
      setAuth(null);
      setOrders([]);
      push({ kind: "err", msg: "Session berakhir", sub: "Silakan login kembali" });
    };
    window.addEventListener('qc:session-expired', onExpired);
    return () => window.removeEventListener('qc:session-expired', onExpired);
  }, []);

  const saveOrder = async (resi, payload = {}) => {
    try {
      await QC_API.completeOrder(resi, { status: "done", ...payload });
      push({ kind: "ok", msg: "Data QC tersimpan", sub: resi });
      goDash();
      fetchOrders(orderPage, orderFilter);
    } catch (ex) {
      push({ kind: "err", msg: "Gagal menyimpan QC", sub: ex.message });
    }
  };

  const downloadOne = (order) => {
    downloadCSV(`QC_${order.order}_${order.resi}.csv`, ordersToCSV([order]));
    push({ kind: "ok", msg: "CSV diunduh", sub: order.order });
  };
  const downloadAll = async () => {
    // Selalu fetch ulang agar data yang diunduh adalah hari berjalan, bukan state stale
    try {
      const data = await QC_API.getOrders({ page: 1, filter: "done", limit: 100 });
      const done = (data.orders || []).filter((o) => o.status === "done" || o.status === "completed");
      if (!done.length) { push({ kind: "err", msg: "Tidak ada data selesai QC hari ini", sub: "" }); return; }
      const stamp = new Date().toISOString().slice(0, 10);
      downloadCSV(`QC_Selesai_${stamp}.csv`, ordersToCSV(done));
      push({ kind: "ok", msg: `${done.length} pesanan diekspor`, sub: "CSV" });
    } catch (ex) {
      push({ kind: "err", msg: "Gagal mengunduh CSV", sub: ex.message });
    }
  };

  const handleFilterChange = (f) => { setOrderFilter(f); setOrderPage(1); };
  const handlePageChange   = (p) => setOrderPage(p);

  const [syncing, setSyncing] = React.useState(false);
  const syncJubelio = async () => {
    if (syncing) return;
    setSyncing(true);
    try {
      const d = await QC_API.syncJubelio();
      if (d && d.ok) {
        push({ kind: "ok", msg: `Sync selesai (${d.elapsed}s)`, sub: `${d.inserted} baru · ${d.updated} update · ${d.skipped} skip` });
        fetchOrders(orderPage, orderFilter);
      } else {
        push({ kind: "err", msg: "Sync gagal", sub: d.error });
      }
    } catch (ex) {
      push({ kind: "err", msg: "Sync gagal", sub: ex.message });
    } finally {
      setSyncing(false);
    }
  };

  const current = view.name === "detail" ? orders.find((o) => o.resi === view.resi) : null;

  if (!auth) return <Login onLogin={login} />;

  return (
    <div className="qc-app">
      <TopBar clock={clock} pending={parseInt(counts.pending) || 0}
        user={auth} view={view.name} onNav={(n) => n === "report" ? goReport() : n === "retur" ? goRetur() : n === "keuangan" ? goKeuangan() : n === "log-aktivitas" ? goLogAktivitas() : n === "webhook" ? goWebhook() : goDash()} onLogout={logout} />
      <main className="qc-main">
        {view.name === "dashboard" && (
          <Dashboard orders={orders} counts={counts} pagination={pagination}
            filter={orderFilter} onFilterChange={handleFilterChange} onPageChange={handlePageChange}
            onOpen={openOrder} onSearchFound={openSearchedOrder} t={t}
            loading={loadingOrders} lastUpdated={lastUpdated} onRefresh={() => fetchOrders(orderPage, orderFilter)}
            onSyncJubelio={['admin','ADMIN','SUPER_ADMIN'].includes(auth?.role) ? syncJubelio : null} syncing={syncing} />
        )}
        {view.name === "detail" && current && (
          <QCDetail key={current.resi} order={current} onBack={goDash} onSave={saveOrder}
            onDownloadOne={downloadOne} push={push} t={t} />
        )}

      </main>
      <ToastStack toasts={toasts} />
      <footer className="qc-footer">
        QC Station <b>v{APP_VERSION}</b> &nbsp;·&nbsp; &copy; 2026
      </footer>

      <TweaksPanel>
        <TweakSection label="Layout layar QC" />
        <TweakRadio label="Tata letak" value={t.qcLayout}
          options={[{ value: "list", label: "List" }, { value: "split", label: "Split" }, { value: "focus", label: "Fokus" }]}
          onChange={(v) => setTweak("qcLayout", v)} />
        <div style={{ fontSize: 11.5, color: "#94a3b8", padding: "2px 2px 8px", lineHeight: 1.5 }}>
          List = daftar vertikal · Split = panel scan + grid · Fokus = pandu satu per satu
        </div>
        <TweakSection label="Tampilan" />
        <TweakColor label="Warna aksen" value={t.accent}
          options={Object.keys(ACCENTS)} onChange={(v) => setTweak("accent", v)} />
        <TweakRadio label="Kepadatan" value={t.density}
          options={["compact", "regular", "comfy"]} onChange={(v) => setTweak("density", v)} />
        <TweakSection label="Perilaku scanner" />
        <TweakToggle label="Bunyi beep" value={t.beep} onChange={(v) => setTweak("beep", v)} />
        <TweakToggle label="Simulator scanner (demo)" value={t.simulator} onChange={(v) => setTweak("simulator", v)} />
      </TweaksPanel>
    </div>
  );
}

function TopBar({ clock, pending, user, view, onNav, onLogout }) {
  const initials = user?.initial || (user?.name || "?").split(" ").map((w) => w[0]).join("").slice(0, 2).toUpperCase();
  return (
    <header className="qc-topbar">
      <div className="qc-topbar-left">
        <div className="qc-brand">
          <div className="qc-brand-mark"><Icon.pkgCheck size={20} stroke="#fff" /></div>
          <div className="qc-brand-txt">
            <div className="qc-brand-name">QC Station</div>
            <div className="qc-brand-sub">Quality Control System</div>
          </div>
        </div>
        <nav className="qc-nav">
          <button className="qc-nav-btn is-on" onClick={() => onNav("dashboard")}>
            <Icon.scan size={16} /> Antrian QC
          </button>
          <button className="qc-nav-btn" onClick={() => onNav("report")}>
            <Icon.list size={16} /> Laporan
          </button>
          <button className="qc-nav-btn" onClick={() => onNav("retur")}>
            <Icon.truck size={16} /> Retur
          </button>
          <button className="qc-nav-btn" onClick={() => onNav("keuangan")}>
            <Icon.wallet size={16} /> Keuangan
          </button>
          <button className="qc-nav-btn" onClick={() => onNav("log-aktivitas")}>
            <Icon.clock size={16} /> Log
          </button>
          <button className="qc-nav-btn" onClick={() => onNav("webhook")}>
            <Icon.webhook size={16} /> Webhook
          </button>
        </nav>
      </div>
      <div className="qc-topbar-right">
        <div className="qc-topchip"><span className="qc-livedot" /> Live</div>
        <div className="qc-topchip"><Icon.box size={15} stroke="var(--warn-ink)" /> {pending} antri</div>
        <div className="qc-topdiv" />
        <div className="qc-topclock"><Icon.clock size={15} stroke="rgba(255,255,255,.5)" /> {clock}</div>
        <div className="qc-operator-wrap">
          <div className="qc-operator" style={{ cursor: "default" }}>
            <div className="qc-operator-av">{initials}</div>
            <div className="qc-operator-txt">
              <div className="qc-operator-name">{user?.name || "Operator"}</div>
              <div className="qc-operator-st">{user?.role || "member"}</div>
            </div>
          </div>
        </div>
        <div className="qc-topdiv" />
        <button className="qc-nav-btn" onClick={onLogout} style={{ color: "var(--err, #ef4444)" }}>
          <Icon.back size={16} /> Keluar
        </button>
      </div>
    </header>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
