/* TaxFlow — page screens */
/* globals React, window, formatBaht, formatThaiDate, NumberCounter, AreaChart, Sparkline,
   Modal, Badge, Btn, IconBtn, I, cls, MonthPicker, toast */

const { useState, useEffect, useMemo } = React;

/* --------------------------- EXPORT HELPERS --------------------------- */

function attachUrl(key) {
  if (!key) return "";
  return window.location.origin + "/api/uploads/" + encodeURIComponent(key);
}

function exportPurchases(rows, suppliers, month) {
  const be = month.y + 543;
  const mn = (window.THAI_MONTH || [])[month.m - 1] || String(month.m);
  const data = rows.map(p => {
    const sup = suppliers.find(s => s.id === p.supplierId);
    return {
      "เลขที่ใบกำกับ":    p.invNo || "",
      "วันที่":           p.date,
      "ผู้ขาย":           sup?.name || "",
      "เลขผู้เสียภาษี":  sup?.taxId || "",
      "รายละเอียด":       p.detail || "",
      "ก่อน VAT":         p.preVat,
      "VAT 7%":           p.vat,
      "รวม":              +(p.preVat + p.vat).toFixed(2),
      "ขอคืน VAT":        p.credit ? "✓" : "",
      "ไฟล์แนบ":          attachUrl(p.attachmentKey),
    };
  });
  const ws = XLSX.utils.json_to_sheet(data);
  ws["!cols"] = [14,20,28,16,28,12,10,12,10,40].map(w => ({ wch: w }));
  const wb = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(wb, ws, "ภาษีซื้อ");
  XLSX.writeFile(wb, `ภาษีซื้อ_${mn}_${be}.xlsx`);
}

function exportSales(rows, month) {
  const be = month.y + 543;
  const mn = (window.THAI_MONTH || [])[month.m - 1] || String(month.m);
  const data = rows.map(s => ({
    "วันที่":      s.date,
    "ช่องทาง":     s.channel || "",
    "รายละเอียด":  s.detail || "",
    "ก่อน VAT":    s.preVat,
    "VAT 7%":      s.vat,
    "รวม":         +(s.preVat + s.vat).toFixed(2),
    "ไฟล์แนบ":     attachUrl(s.attachmentKey),
  }));
  const ws = XLSX.utils.json_to_sheet(data);
  ws["!cols"] = [12,14,32,12,10,12,40].map(w => ({ wch: w }));
  const wb = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(wb, ws, "ภาษีขาย");
  XLSX.writeFile(wb, `ภาษีขาย_${mn}_${be}.xlsx`);
}

/* --------------------------- DASHBOARD --------------------------- */

function ScreenDashboard({ store, setMonth, month, setPage }) {
  const [tab, setTab] = useState("summary");

  const monthRows = useMemo(() => store.purchases.filter(p => window.inMonth(p.date, month)), [store.purchases, month]);
  const totals    = useMemo(() => window.purchaseTotals(monthRows), [monthRows]);
  const salesRows = useMemo(() => store.sales.filter(s => window.inMonth(s.date, month)), [store.sales, month]);
  const salesTot  = useMemo(() => window.salesTotals(salesRows), [salesRows]);
  const series    = useMemo(() => window.monthlyVatSeries(store.purchases, month, 6), [store.purchases, month]);
  const recent    = useMemo(() => [...monthRows]
    .sort((a, b) => b.date.localeCompare(a.date)).slice(0, 5),
    [monthRows]);

  // Prev-month totals for trend deltas
  const prevM     = useMemo(() => window.prevMonth(month), [month]);
  const prevPRows = useMemo(() => store.purchases.filter(p => window.inMonth(p.date, prevM)), [store.purchases, prevM]);
  const prevSRows = useMemo(() => store.sales.filter(s => window.inMonth(s.date, prevM)),     [store.sales, prevM]);
  const prevPT    = useMemo(() => window.purchaseTotals(prevPRows), [prevPRows]);
  const prevST    = useMemo(() => window.salesTotals(prevSRows),     [prevSRows]);
  const dInputVat  = window.trendPct(totals.vat,    prevPT.vat);
  const dOutputVat = window.trendPct(salesTot.vat,  prevST.vat);
  const netVat     = Math.max(0, salesTot.vat - totals.creditVat);
  const prevNet    = Math.max(0, prevST.vat - prevPT.creditVat);
  const dNet       = window.trendPct(netVat, prevNet);

  return (
    <div className="page page-dashboard">
      {/* Tab toggle pill */}
      <div className="seg">
        <button className={cls("seg-i", tab === "summary" && "is-on")} onClick={() => setTab("summary")}>
          บันทึกแบบรายวัน <span className="seg-dim">(summary)</span>
        </button>
        <button className={cls("seg-i", tab === "invoice" && "is-on")} onClick={() => setTab("invoice")}>
          บันทึกแบบรายใบ <span className="seg-dim">(invoice)</span>
        </button>
        <span className="seg-r">บันทึกทุกใบกำกับภาษีแยกรายการ</span>
      </div>

      {/* Chart section header */}
      <section className="card glow-card">
        <div className="card-h">
          <div>
            <div className="card-eyebrow">VAT รายเดือน</div>
            <h2 className="card-title">สรุป VAT 6 เดือนล่าสุด</h2>
          </div>
          <MonthPicker value={month} onChange={setMonth}/>
        </div>
        <div className="dash-grid">
          <div className="dash-chart">
            <AreaChart data={series} height={300}/>
          </div>

          <div className="dash-stats">
            <Stat
              label="ภาษีขาย (Output Tax)"
              value={salesTot.vat} caption={`จากยอดขาย ${window.formatBaht(salesTot.total)}`}
              tone={salesTot.vat === 0 ? "muted" : "ok"}
              icon={<I.arrowUp width="18" height="18"/>}
              delta={dOutputVat}
              onAction={() => setPage("sales")}
            />
            <Stat
              label="ภาษีซื้อ (Input Tax)"
              value={totals.vat} caption={`จากยอดซื้อ ${window.formatBaht(totals.total)}`} tone="warn"
              icon={<I.arrowDown width="18" height="18"/>}
              delta={dInputVat}
              onAction={() => setPage("purchases")}
            />
            <Stat
              label="VAT ที่ต้องนำส่ง"
              value={netVat}
              caption={salesTot.vat - totals.creditVat < 0 ? `ขอคืนได้ ${window.formatBaht(totals.creditVat - salesTot.vat)}` : "ภ.พ.30"}
              tone="accent"
              icon={<I.doc width="18" height="18"/>}
              delta={dNet}
              cta="Export ภ.พ.30" onAction={() => setPage("vat")}
            />
          </div>
        </div>
      </section>

      {/* Recent transactions */}
      <section className="card">
        <div className="card-h">
          <h3 className="card-title">รายการล่าสุด</h3>
          <div className="row gap-8">
            <Btn variant="ghost"><I.filter width="14" height="14"/> แสดงรายการยกเลิก</Btn>
            <Btn variant="ghost"><I.download width="14" height="14"/> Export</Btn>
          </div>
        </div>
        <div className="tbl">
          <div className="thead row-7">
            <div>วันที่</div><div>รายละเอียด</div><div>ประเภท</div>
            <div className="r">ยอดเงิน</div><div className="r">ภาษี (VAT 7%)</div><div className="r">ยอดรวม</div><div>สถานะ</div>
          </div>
          {recent.map((p, i) => {
            const sup = window.SEED_SUPPLIERS.find(s => s.id === p.supplierId);
            return (
              <div className="trow row-7 stagger" style={{animationDelay: `${i*60}ms`}} key={p.id}>
                <div className="tabnum">{window.formatThaiDate(p.date)}</div>
                <div className="ellip" title={(sup?.name||"") + " · " + p.detail}>
                  <div className="t-pri">{sup?.name || <em className="dim">— ไม่ระบุผู้ขาย —</em>}</div>
                  <div className="t-sec">{p.detail}</div>
                </div>
                <div><Badge tone="amber">ภาษีซื้อ</Badge></div>
                <div className="r tabnum">{window.formatBaht(p.preVat)}</div>
                <div className="r tabnum">{window.formatBaht(p.vat)}</div>
                <div className="r tabnum strong">{window.formatBaht(p.preVat + p.vat)}</div>
                <div><Badge tone="ok">ปกติ</Badge></div>
              </div>
            );
          })}
        </div>
      </section>
    </div>
  );
}
window.ScreenDashboard = ScreenDashboard;

function Stat({ label, value, caption, tone, icon, cta, onAction, delta }) {
  const deltaTone = delta == null ? null : delta > 0 ? "up" : delta < 0 ? "down" : "flat";
  return (
    <div className={cls("stat", `stat-${tone}`)} onClick={onAction} role="button" tabIndex={0}>
      <div className="stat-h">
        <span className="stat-lb">{label}</span>
        <span className="stat-ic">{icon}</span>
      </div>
      <div className="stat-v"><NumberCounter value={value}/></div>
      <div className="stat-foot">
        <span className="stat-cap">{caption}</span>
        {delta != null && (
          <span className={cls("stat-delta", `delta-${deltaTone}`)}>
            {delta > 0 ? <I.arrowUp width="12" height="12"/> : delta < 0 ? <I.arrowDown width="12" height="12"/> : null}
            {Math.abs(delta).toFixed(1)}%
          </span>
        )}
      </div>
      {cta && (
        <button className="stat-cta" onClick={(e) => { e.stopPropagation(); onAction && onAction(); }}>
          <I.download width="14" height="14"/> {cta}
        </button>
      )}
    </div>
  );
}

/* --------------------------- P&L --------------------------- */

function ScreenPL({ store, month, setMonth }) {
  const purchRows = useMemo(() => store.purchases.filter(p => window.inMonth(p.date, month)), [store.purchases, month]);
  const saleRows  = useMemo(() => store.sales.filter(s => window.inMonth(s.date, month)),     [store.sales, month]);
  const pT = useMemo(() => window.purchaseTotals(purchRows), [purchRows]);
  const sT = useMemo(() => window.salesTotals(saleRows),     [saleRows]);
  const pretax    = sT.preVat - pT.preVat;  // กำไร/ขาดทุน ก่อน VAT
  const aftertax  = sT.total  - pT.total;   // กำไร/ขาดทุน รวม VAT
  const netVat    = sT.vat - pT.creditVat;  // VAT ที่ต้องนำส่ง (-)=ขอคืน
  const isLoss = pretax < 0;
  return (
    <div className="page page-pl">
      <div className="row-wrap row-jb">
        <div>
          <div className="card-eyebrow">สรุปผลประกอบการรายเดือน</div>
          <h2 className="card-title big">{window.THAI_MONTH[month.m - 1]} {month.y + 543}</h2>
        </div>
        <PeriodBar value={month} onChange={setMonth}/>
      </div>

      <div className="grid-2">
        <PLCard
          label="กำไร / ขาดทุน (ก่อน VAT)"
          amount={pretax}
          caption={`${isLoss ? "ขาดทุน" : pretax === 0 ? "ไม่มีรายการ" : "กำไร"} ประจำเดือน ${window.THAI_MONTH[month.m - 1]} ${month.y + 543}`}
          spark={[1200, 980, 1500, 1300, -200, -2400, pretax]}
        />
        <PLCard
          label="กำไร / ขาดทุน (รวม VAT)"
          amount={aftertax}
          caption={`${aftertax < 0 ? "ขาดทุน" : aftertax === 0 ? "ไม่มีรายการ" : "กำไร"} ประจำเดือน ${window.THAI_MONTH[month.m - 1]} ${month.y + 543}`}
          spark={[1100, 1020, 1480, 1240, -300, -2540, aftertax]}
        />
      </div>

      <div className="grid-2">
        <div className="card">
          <div className="card-h"><h3 className="card-title">รายได้จากการขาย</h3></div>
          <Row label="มูลค่าก่อน VAT" value={sT.preVat}/>
          <Row label="VAT ขาย (Output Tax)" value={sT.vat}/>
          <RowTotal label="รวมทั้งสิ้น" value={sT.total} note={`${sT.count} รายการ`}/>
        </div>
        <div className="card">
          <div className="card-h"><h3 className="card-title">ต้นทุนจากการซื้อ</h3></div>
          <Row label="มูลค่าก่อน VAT" value={pT.preVat}/>
          <Row label="VAT ซื้อ (Input Tax)" value={pT.vat}/>
          <Row label={`ขอคืนได้ (${pT.creditCount} ใบ)`} value={pT.creditVat} tone="ok"/>
          <RowTotal label="รวมทั้งสิ้น" value={pT.total} note={`${pT.count} รายการ`}/>
        </div>
      </div>

      <div className="card">
        <div className="card-h"><h3 className="card-title">สรุป VAT</h3></div>
        <div className="vat-summary">
          <div className="vs-cell">
            <div className="vs-lb">Output Tax (ขาย)</div>
            <div className="vs-v"><NumberCounter value={sT.vat}/></div>
          </div>
          <div className="vs-cell">
            <div className="vs-lb">Input Tax (ขอคืนได้)</div>
            <div className="vs-v amber"><NumberCounter value={pT.creditVat}/></div>
          </div>
          <div className="vs-cell">
            <div className="vs-lb">VAT ที่ต้องนำส่ง</div>
            <div className={cls("vs-v", netVat <= 0 ? "ok" : "")}><NumberCounter value={Math.abs(netVat)}/></div>
            <div className="vs-cap">{netVat <= 0 ? "ขอคืนได้" : "นำส่ง"}</div>
          </div>
        </div>
      </div>
    </div>
  );
}
window.ScreenPL = ScreenPL;

function PLCard({ label, amount, caption, spark }) {
  const loss = amount < 0;
  return (
    <div className={cls("pl-card", loss ? "pl-loss" : "pl-gain")}>
      <div className="pl-lb">{label}</div>
      <div className="pl-row">
        <div className="pl-v"><NumberCounter value={Math.abs(amount)}/></div>
        <div className="pl-arrow">
          {loss ? <I.arrowDown width="28" height="28"/> : <I.arrowUp width="28" height="28"/>}
        </div>
      </div>
      <div className="pl-cap">{caption}</div>
      <div className="pl-spark"><Sparkline data={spark} width={240} height={44}/></div>
    </div>
  );
}

function Row({ label, value, tone, unit }) {
  return (
    <div className={cls("kv-row", tone === "ok" && "ok")}>
      <div className="kv-l">{label}</div>
      <div className="kv-r tabnum">
        {tone === "plain"
          ? <>{value.toLocaleString()}{unit ? <span className="dim"> {unit}</span> : null}</>
          : window.formatBaht(value)}
      </div>
    </div>
  );
}
function RowTotal({ label, value, note }) {
  return (
    <div className="kv-row kv-total">
      <div>
        <div className="kv-l strong">{label}</div>
        {note && <div className="kv-n">{note}</div>}
      </div>
      <div className="kv-r tabnum big">{window.formatBaht(value)}</div>
    </div>
  );
}

/* --------------------------- VAT REPORT --------------------------- */

function ScreenVAT({ store, month, setMonth }) {
  const purchRows = useMemo(() => store.purchases.filter(p => window.inMonth(p.date, month)), [store.purchases, month]);
  const saleRows  = useMemo(() => store.sales.filter(s => window.inMonth(s.date, month)),     [store.sales, month]);
  const T  = useMemo(() => window.purchaseTotals(purchRows), [purchRows]);
  const ST = useMemo(() => window.salesTotals(saleRows),     [saleRows]);
  const netVat = ST.vat - T.creditVat;
  const refund = netVat < 0;
  return (
    <div className="page page-vat">
      <div className="row-wrap row-jb">
        <PeriodBar value={month} onChange={setMonth}/>
        <div className="row gap-8">
          <Btn variant="ghost" onClick={() => toast("กำลังเตรียมไฟล์ ภาษีขาย.xlsx")}><I.download width="14" height="14"/> ภาษีขาย .xlsx</Btn>
          <Btn variant="ghost" onClick={() => toast("กำลังเตรียมไฟล์ ภาษีซื้อ.xlsx")}><I.download width="14" height="14"/> ภาษีซื้อ .xlsx</Btn>
          <Btn variant="primary" onClick={() => toast("กำลังเตรียม ภ.พ.30 PDF")}><I.download width="14" height="14"/> ดาวน์โหลด ภ.พ.30</Btn>
        </div>
      </div>

      <div className={cls("hero-card", refund ? "hero-refund" : "hero-pay")}>
        <div className="hero-l">
          <div className="hero-ic"><I.sparkle width="22" height="22"/></div>
          <div>
            <div className="hero-lb">{refund ? "VAT เครดิตคืน" : netVat === 0 ? "ไม่มียอด VAT" : "VAT ที่ต้องนำส่ง"}</div>
            <div className="hero-v"><NumberCounter value={Math.abs(netVat)}/></div>
            <div className="hero-cap">
              ประจำเดือน {window.THAI_MONTH[month.m - 1]} {month.y + 543} ·
              ภาษีขาย <b>{window.formatBaht(ST.vat)}</b> – ภาษีซื้อ <b>{window.formatBaht(T.creditVat)}</b>
            </div>
          </div>
        </div>
        <div className="hero-r">
          <div className="ring">
            <svg viewBox="0 0 120 120" width="120" height="120">
              <circle cx="60" cy="60" r="48" fill="none" stroke="var(--line-soft)" strokeWidth="10"/>
              <circle cx="60" cy="60" r="48" fill="none" stroke="var(--accent)" strokeWidth="10"
                      strokeLinecap="round" strokeDasharray="301.6"
                      strokeDashoffset={T.count > 0 ? 301.6 * (1 - T.creditCount / T.count) : 301.6}
                      transform="rotate(-90 60 60)" className="ring-anim"/>
            </svg>
            <div className="ring-c">
              <div className="ring-n">{T.creditCount}</div>
              <div className="ring-l">/ {T.count} ใบ</div>
            </div>
          </div>
        </div>
      </div>

      <div className="grid-2">
        <div className="card">
          <div className="card-h"><h3 className="card-title"><I.arrowUp width="16" height="16"/> ภาษีขาย (Output Tax)</h3></div>
          <Row label="จำนวนใบกำกับ" value={ST.count} tone="plain" unit="ฉบับ"/>
          <Row label="มูลค่าก่อน VAT" value={ST.preVat}/>
          <Row label="VAT 7%" value={ST.vat}/>
          <RowTotal label="มูลค่ารวม" value={ST.total}/>
        </div>
        <div className="card">
          <div className="card-h"><h3 className="card-title"><I.arrowDown width="16" height="16"/> ภาษีซื้อ (Input Tax)</h3></div>
          <Row label="จำนวนใบกำกับ (ทั้งหมด)" value={T.count} tone="plain" unit="ฉบับ"/>
          <Row label="มูลค่าก่อน VAT (ทั้งหมด)" value={T.preVat}/>
          <RowTotal label="มูลค่ารวม (ทั้งหมด)" value={T.total}/>
          <div className="kv-row mt-12">
            <div className="kv-l">ใบขอเครดิต VAT คืน ({T.creditCount} ฉบับ)</div>
            <div className="kv-r tabnum">{window.formatBaht(T.creditVat)}</div>
          </div>
          <div className="hint">* นับเฉพาะใบที่ระบุ "นำ VAT ไปขอเครดิตคืนได้"</div>
        </div>
      </div>
    </div>
  );
}
window.ScreenVAT = ScreenVAT;

/* --------------------------- SALES --------------------------- */

function ScreenSales({ store, dispatch, month, setMonth, search, setSearch, onAdd, onEdit }) {
  const monthRows = useMemo(() => store.sales.filter(s => window.inMonth(s.date, month)), [store.sales, month]);
  const totals    = useMemo(() => window.salesTotals(monthRows), [monthRows]);
  const items = useMemo(() => {
    const q = search.trim().toLowerCase();
    if (!q) return monthRows;
    return monthRows.filter(s => [s.channel, s.detail].some(v => (v||"").toLowerCase().includes(q)));
  }, [monthRows, search]);

  return (
    <div className="page page-sales">
      <div className="row-wrap row-jb">
        <PeriodBar value={month} onChange={setMonth}/>
        <Btn variant="ghost" onClick={() => exportSales(monthRows, month)}><I.download width="14" height="14"/> Export .xlsx</Btn>
      </div>

      <div className="kpi-row">
        <KPI label="รายการทั้งหมด" value={totals.count} unit="ฉบับ" raw/>
        <KPI label="มูลค่าก่อน VAT" value={totals.preVat}/>
        <KPI label="VAT 7% (ภาษีขาย)" value={totals.vat} tone="accent"/>
        <KPI label="มูลค่ารวม" value={totals.total}/>
      </div>

      {totals.count === 0 ? (
        <EmptyState
          icon={<I.bag width="36" height="36"/>}
          title="ยังไม่มีรายการ"
          message="เริ่มบันทึกใบกำกับภาษีขายเพื่อเก็บเป็น Output Tax"
          cta="เพิ่มใบกำกับภาษีขาย" onCta={onAdd}
        />
      ) : (
        <div className="card no-pad">
          <div className="tbl">
            <div className="thead row-sales">
              <div>วันที่</div><div>ช่องทาง</div><div>รายละเอียด</div>
              <div className="r">ก่อน VAT</div><div className="r">VAT 7%</div><div className="r">รวม</div><div className="c"></div>
            </div>
            {items.map((s, i) => (
              <div className="trow row-sales stagger" style={{animationDelay:`${i*30}ms`}} key={s.id}>
                <div className="tabnum">{window.formatThaiDate(s.date)}</div>
                <div><Badge tone="neutral">{s.channel}</Badge></div>
                <div className="ellip">{s.detail || <span className="dim">—</span>}</div>
                <div className="r tabnum">{window.formatBaht(s.preVat)}</div>
                <div className={cls("r tabnum", s.vat === 0 && "dim")}>{window.formatBaht(s.vat)}</div>
                <div className="r tabnum strong">{window.formatBaht(s.preVat + s.vat)}</div>
                <div className="row-actions reveal">
                  <IconBtn title="แก้ไข" onClick={() => onEdit(s)}><I.edit width="15" height="15"/></IconBtn>
                  <IconBtn title="ลบ" onClick={() => { dispatch({type:"deleteSale", id: s.id}); toast("ย้ายไปถังขยะแล้ว"); }}>
                    <I.x width="15" height="15"/>
                  </IconBtn>
                </div>
              </div>
            ))}
            {items.length === 0 && (
              <div className="empty-row">ไม่พบรายการที่ตรงกับ "<b>{search}</b>"</div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}
window.ScreenSales = ScreenSales;

/* --------------------------- PURCHASES --------------------------- */

function ScreenPurchases({ store, dispatch, month, setMonth, search, setSearch, onAdd, onEdit }) {
  const monthRows = useMemo(() => store.purchases.filter(p => window.inMonth(p.date, month)), [store.purchases, month]);
  const totals    = useMemo(() => window.purchaseTotals(monthRows), [monthRows]);
  const items = useMemo(() => {
    const q = search.trim().toLowerCase();
    const rows = monthRows;
    if (!q) return rows;
    return rows.filter((p) => {
      const sup = window.SEED_SUPPLIERS.find(s => s.id === p.supplierId);
      return [p.invNo, p.detail, sup?.name, sup?.taxId].some(v => (v||"").toLowerCase().includes(q));
    });
  }, [monthRows, search]);

  return (
    <div className="page page-purchases">
      <div className="row-wrap row-jb">
        <PeriodBar value={month} onChange={setMonth}/>
        <Btn variant="ghost" onClick={() => exportPurchases(monthRows, store.suppliers, month)}><I.download width="14" height="14"/> Export .xlsx</Btn>
      </div>

      <div className="kpi-row">
        <KPI label="รายการทั้งหมด" value={totals.count} unit="ฉบับ" raw/>
        <KPI label="มูลค่าก่อน VAT" value={totals.preVat}/>
        <KPI label="VAT 7% (ภาษีซื้อ)" value={totals.vat} tone="accent"/>
        <KPI label="มูลค่ารวม" value={totals.total}/>
      </div>

      <div className="card no-pad">
        <div className="tbl">
          <div className="thead row-purch">
            <div>เลขที่ใบกำกับ</div><div>ผู้ขาย</div><div>รายละเอียด</div>
            <div className="r">ก่อน VAT</div><div className="r">VAT 7%</div><div className="r">รวม</div>
            <div className="c">ขอคืน<br/>VAT</div><div className="c"></div>
          </div>
          {(() => {
            // Group rows by date, sorted desc
            const sorted = [...items].sort((a, b) => b.date.localeCompare(a.date));
            const groups = [];
            let curDate = null, curGroup = null;
            for (const p of sorted) {
              if (p.date !== curDate) { curDate = p.date; curGroup = { date: p.date, rows: [] }; groups.push(curGroup); }
              curGroup.rows.push(p);
            }
            let i = 0;
            return groups.map((g) => (
              <React.Fragment key={g.date}>
                <div className="date-divider">
                  <span className="date-divider-lb">{window.formatThaiDate(g.date)}</span>
                  <span className="date-divider-rt">
                    <span className="dim">{g.rows.length} รายการ</span>
                    <span className="tabnum strong">
                      {window.formatBaht(g.rows.reduce((s, r) => s + r.preVat + r.vat, 0))}
                    </span>
                  </span>
                </div>
                {g.rows.map((p) => {
                  const sup = window.SEED_SUPPLIERS.find(s => s.id === p.supplierId);
                  const idx = i++;
                  return (
                    <div className="trow row-purch stagger" style={{animationDelay: `${idx*20}ms`}} key={p.id}>
                      <div className="mono accent">{p.invNo || <span className="dim">—</span>}</div>
                      <div className="ellip">{sup?.name || <span className="dim">—</span>}</div>
                      <div className="ellip">{p.detail}</div>
                      <div className="r tabnum">{window.formatBaht(p.preVat)}</div>
                      <div className={cls("r tabnum", p.vat === 0 && "dim")}>{window.formatBaht(p.vat)}</div>
                      <div className="r tabnum strong">{window.formatBaht(p.preVat + p.vat)}</div>
                      <div className="c">
                        {p.credit ? <span className="check-ok"><I.check width="16" height="16"/></span> : <span className="dim">—</span>}
                      </div>
                      <div className="row-actions reveal">
                        {p.attachmentKey && (
                          <a href={`/api/uploads/${encodeURIComponent(p.attachmentKey)}`} target="_blank" rel="noreferrer">
                            <IconBtn title="แนบเอกสาร"><I.clip width="15" height="15"/></IconBtn>
                          </a>
                        )}
                        <IconBtn title="แก้ไข" onClick={() => onEdit(p)}><I.edit width="15" height="15"/></IconBtn>
                        <IconBtn title="ลบ" onClick={() => { dispatch({type:"deletePurchase", id: p.id}); toast("ย้ายไปถังขยะแล้ว"); }}>
                          <I.x width="15" height="15"/>
                        </IconBtn>
                      </div>
                    </div>
                  );
                })}
              </React.Fragment>
            ));
          })()}
          {items.length === 0 && (
            <div className="empty-row">
              {search.trim() ? <>ไม่พบรายการที่ตรงกับ "<b>{search}</b>"</> : <>ยังไม่มีรายการในเดือน {window.THAI_MONTH[month.m - 1]} {month.y + 543}</>}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
window.ScreenPurchases = ScreenPurchases;

/* --------------------------- SUPPLIERS --------------------------- */

function ScreenSuppliers({ store, dispatch, search, setSearch, onAdd, onEdit }) {
  const items = useMemo(() => {
    const q = search.trim().toLowerCase();
    if (!q) return store.suppliers;
    return store.suppliers.filter(s => [s.name, s.taxId].some(v => (v||"").toLowerCase().includes(q)));
  }, [store.suppliers, search]);

  return (
    <div className="page page-suppliers">
      <div className="row-wrap row-jb">
        <div className="dim">{items.length} รายการ</div>
      </div>

      <div className="card no-pad">
        <div className="tbl">
          <div className="thead row-sup">
            <div>#</div><div>ชื่อผู้ขาย / ซัพพลายเออร์</div><div>เลขผู้เสียภาษี</div><div className="c"></div>
          </div>
          {items.map((s, i) => (
            <div className="trow row-sup stagger" style={{animationDelay: `${i*40}ms`}} key={s.id}>
              <div className="dim tabnum">{i + 1}</div>
              <div className="row gap-12 ai-c">
                <div className="avatar-sm" style={{background: avatarColor(s.name)}}>
                  {(s.name||"?").trim().charAt(0).toUpperCase()}
                </div>
                <span>{s.name}</span>
              </div>
              <div className="mono tabnum">{s.taxId}</div>
              <div className="row-actions reveal">
                <IconBtn title="แก้ไข" onClick={() => onEdit(s)}><I.edit width="15" height="15"/></IconBtn>
                <IconBtn title="ลบ" onClick={() => { dispatch({type:"deleteSupplier", id: s.id}); toast("ลบผู้ขายแล้ว"); }}>
                  <I.x width="15" height="15"/>
                </IconBtn>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}
window.ScreenSuppliers = ScreenSuppliers;

function avatarColor(s) {
  let h = 0; for (const c of (s||"")) h = (h*31 + c.charCodeAt(0)) % 360;
  return `oklch(0.85 0.08 ${h})`;
}

/* --------------------------- AUDIT LOG --------------------------- */

function ScreenAudit({ store, search, setSearch }) {
  const all = store.audit || [];
  const items = useMemo(() => {
    const q = search.trim().toLowerCase();
    if (!q) return all;
    return all.filter(a => [a.kind, a.ref, a.actor, a.action].some(v => (v||"").toLowerCase().includes(q)));
  }, [all, search]);
  return (
    <div className="page page-audit">
      <div className="card">
        <div className="card-h">
          <div>
            <h3 className="card-title">ประวัติการแก้ไขทั้งหมด</h3>
            <div className="card-sub">บันทึกทุกการสร้าง แก้ไข และยกเลิกรายการ</div>
          </div>
        </div>
        <div className="tbl">
          <div className="thead row-aud">
            <div>วันเวลา</div><div>ประเภท</div><div>รหัสเอกสาร</div><div>การดำเนินการ</div><div>ผู้ดำเนินการ</div><div>หมายเหตุ</div>
          </div>
          {items.map((a, i) => (
            <div className="trow row-aud stagger" style={{animationDelay: `${i*25}ms`}} key={a.id}>
              <div className="tabnum">{window.formatThaiDate(a.time, {withTime: true})}</div>
              <div>{a.kind}</div>
              <div className="mono accent">{a.ref}</div>
              <div>
                <Badge tone={a.action === "ยกเลิก" ? "danger" : a.action === "แก้ไข" ? "amber" : "ok"}>
                  {a.action}
                </Badge>
              </div>
              <div>{a.actor}</div>
              <div className="dim">—</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}
window.ScreenAudit = ScreenAudit;

/* --------------------------- TRASH --------------------------- */

function ScreenTrash({ store, onRestore }) {
  const [tab, setTab] = useState("sales");
  const sales = store.trashSales;
  const purchases = store.trashPurchases;
  const items = tab === "sales" ? sales : purchases;

  return (
    <div className="page page-trash">
      <div className="card">
        <div className="card-h">
          <div>
            <h3 className="card-title">ถังขยะ</h3>
            <div className="card-sub">รายการที่ถูกยกเลิกจะแสดงที่นี่ คุณสามารถกู้คืนได้ตลอดเวลา</div>
          </div>
        </div>
        <div className="seg-inline">
          <button className={cls("seg-i", tab === "sales" && "is-on")} onClick={() => setTab("sales")}>
            ภาษีขาย <span className="seg-dim">({sales.length})</span>
          </button>
          <button className={cls("seg-i", tab === "purchases" && "is-on")} onClick={() => setTab("purchases")}>
            ภาษีซื้อ <span className="seg-dim">({purchases.length})</span>
          </button>
        </div>

        <div className="tbl">
          <div className="thead row-trash">
            <div>เลขที่ใบกำกับ</div><div>วันที่</div><div>ลูกค้า</div>
            <div className="r">ยอดรวม</div><div>เหตุผลยกเลิก</div><div className="c"></div>
          </div>
          {items.length === 0 ? (
            <div className="empty-row">ไม่มีรายการ</div>
          ) : items.map((t, i) => (
            <div className="trow row-trash stagger" style={{animationDelay: `${i*40}ms`}} key={t.id}>
              <div className="mono accent">{t.invNo || <span className="dim">—</span>}</div>
              <div className="tabnum">{window.formatThaiDate(t.date)}</div>
              <div className="dim">{t.customer || "—"}</div>
              <div className="r tabnum strong">{window.formatBaht(t.total)}</div>
              <div className="dim">{t.reason || "—"}</div>
              <div className="r">
                <Btn variant="ghost" onClick={() => onRestore(t.id, tab)}>
                  <I.restore width="14" height="14"/> กู้คืน
                </Btn>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}
window.ScreenTrash = ScreenTrash;

/* --------------------------- SHARED MICRO --------------------------- */

function KPI({ label, value, tone, unit, raw }) {
  return (
    <div className={cls("kpi", tone && `kpi-${tone}`)}>
      <div className="kpi-lb">{label}</div>
      <div className="kpi-v">
        {raw
          ? <span className="tabnum">{value.toLocaleString()}</span>
          : <NumberCounter value={value}/>
        }
        {unit && <span className="kpi-u">{unit}</span>}
      </div>
    </div>
  );
}
window.KPI = KPI;

function EmptyState({ icon, title, message, cta, onCta }) {
  return (
    <div className="empty">
      <div className="empty-ic">{icon}</div>
      <div className="empty-t">{title}</div>
      <div className="empty-m">{message}</div>
      {cta && <Btn variant="primary" onClick={onCta}><I.plus width="14" height="14"/> {cta}</Btn>}
    </div>
  );
}
window.EmptyState = EmptyState;
