/* ============ Income (ภาษีขาย) ============ */
function IncomePage({ role, toast, pShort, period }) {
  const canEdit = role === 'owner' || role === 'staff';
  const canDelete = role === 'owner'; // ลบได้เฉพาะเจ้าของกิจการ/ผู้ดูแลระบบ
  const isCurrent = period.m === CURRENT_PERIOD.m && period.y === CURRENT_PERIOD.y;
  const defaultISO = (period.y - 543) + '-' + String(period.m + 1).padStart(2, '0') + '-' + String(isCurrent ? new Date().getDate() : 1).padStart(2, '0');
  const [, setVer] = useState(0);
  const refresh = () => setVer((v) => v + 1);
  const [modal, setModal] = useState(null);   // null | 'new' | record(แก้ไข)
  const [delRow, setDelRow] = useState(null);  // record ที่จะลบ

  const handleSave = async (rec) => {
    const exists = D.income.some((x) => x.id === rec.id);
    const res = exists ? await API.updateIncome(rec) : await API.addIncome(rec);
    if (res.ok && res.data.ok) {
      const saved = res.data.record || rec;
      const i = D.income.findIndex((x) => x.id === saved.id);
      if (i >= 0) D.income[i] = saved; else D.income.push(saved);
      toast(exists ? 'แก้ไขรายรับเรียบร้อย' : 'บันทึกรายรับเรียบร้อย');
      setModal(null); refresh();
    } else {
      toast((res.data && (res.data.msg || res.data.error)) || 'บันทึกไม่สำเร็จ', 'warn');
    }
  };
  const handleDelete = async () => {
    const res = await API.deleteIncome(delRow.id);
    if (res.ok && res.data.ok) {
      const i = D.income.findIndex((x) => x.id === delRow.id);
      if (i >= 0) D.income.splice(i, 1);
      toast('ลบรายการแล้ว');
      setDelRow(null); refresh();
    } else {
      toast('ลบไม่สำเร็จ', 'warn');
    }
  };

  const rows = D.income.filter((r) => inPeriod(r.dateISO, period));
  const hasData = rows.length > 0;
  const t = rows.reduce((a, d) => ({ pre: a.pre + d.pre, vat: a.vat + d.vat, total: a.total + d.total, wht: a.wht + d.wht, ret: a.ret + d.retention, net: a.net + d.netReceived }), { pre: 0, vat: 0, total: 0, wht: 0, ret: 0, net: 0 });
  const byType = { vat7: 0, zero: 0, exempt: 0 };
  rows.forEach((r) => { byType[r.type === 'vat7' ? 'vat7' : r.type === 'zero' ? 'zero' : 'exempt'] += r.pre; });
  const govCount = rows.filter((r) => r.payer === 'gov').length;

  if (!hasData) return (
    <>
      <div className="page-head">
        <div><div className="pt">รายรับ · ภาษีขาย</div><div className="ps">ใบกำกับภาษีขาย / รายได้ประจำเดือน · {pShort}</div></div>
      </div>
      <Empty icon="calendar" title={'ยังไม่มีรายรับสำหรับ ' + pShort} sub="เลือกเดือนอื่นจากปฏิทินด้านบน หรือเพิ่มรายรับของรอบนี้" />
    </>
  );

  return (
    <>
      <div className="page-head">
        <div><div className="pt">รายรับ · ภาษีขาย</div><div className="ps">ใบกำกับภาษีขาย / รายได้ประจำเดือน · {pShort}</div></div>
        <div className="spacer"></div>
        <button className="btn btn-ghost"><Icon name="download" className="ic" />รายงานภาษีขาย</button>
        {canEdit && <button className="btn btn-primary" onClick={() => setModal('new')}><Icon name="plus" className="ic" />เพิ่มรายรับ</button>}
      </div>

      <div className="grid" style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(190px, 1fr))', marginBottom: 16 }}>
        <Stat label="ยอดขายรวม (ก่อน VAT)" icon="income" value={D.baht(t.pre, 0)} />
        <Stat label="ภาษีขายรวม" icon="vat" iconBg="var(--warn-bg)" iconColor="var(--warn)" value={D.baht(t.vat, 0)} />
        <Stat label="ถูกหัก ณ ที่จ่าย" icon="receipt" iconBg="var(--info-bg)" iconColor="var(--info)" value={D.baht(t.wht, 0)} sub="เครดิตภาษีได้" />
        <Stat label="เงินประกันผลงานถูกหัก" icon="lock" iconBg="var(--surface-2)" iconColor="var(--ink-2)" value={D.baht(t.ret, 0)} sub="รอคืนหลังประกัน" />
        <Stat label="ยอดรับเงินจริง" icon="bank" iconBg="var(--ok-bg)" iconColor="var(--ok)" value={D.baht(t.net, 0)} sub="หลังหักทุกอย่าง" />
      </div>

      {/* analysis callout for government work */}
      <div className="callout info" style={{ marginBottom: 14 }}>
        <Icon name="sparkle" className="ic" />
        <div>
          <b>วิเคราะห์งานราชการ ({govCount} งาน):</b> ภาษี<b>ถูกหัก ณ ที่จ่าย {D.baht(t.wht)}</b> — นำไปเป็น<u>เครดิตหักภาษีเงินได้นิติบุคคล (ภ.ง.ด.50)</u> ปลายปีได้ทั้งหมด อย่าลืมเก็บ<b>หนังสือรับรองการหัก ณ ที่จ่าย (50 ทวิ)</b>ทุกใบ ·
          เงิน<b>ประกันผลงาน {D.baht(t.ret)}</b> ที่ถูกหักไว้เป็นลูกหนี้ที่จะ<u>ได้คืนเมื่อพ้นระยะประกัน</u> — บันทึกไว้ในงบดุล ไม่ใช่ค่าใช้จ่าย
        </div>
      </div>

      <div className="card">
        <div className="card-head"><h3>ทะเบียนภาษีขาย</h3><span className="badge muted" style={{ marginLeft: 'auto' }}>{rows.length} รายการ</span></div>
        <div className="tbl-wrap">
          <table className="tbl">
            <thead><tr><th>วันที่</th><th>ลูกค้า</th><th>ผู้จ่าย</th><th>ประเภท</th><th className="r">ก่อน VAT</th><th className="r">VAT</th><th className="r">รวม</th><th className="r">หัก ณ ที่จ่าย</th><th className="r">ประกันผลงาน</th><th className="r">รับจริง</th><th>สถานะ</th>{canEdit && <th className="c sticky-act">จัดการ</th>}</tr></thead>
            <tbody>
              {rows.map((d) => (
                <tr key={d.id}>
                  <td className="num" style={{ whiteSpace: 'nowrap', color: 'var(--ink-2)' }}>{d.date}</td>
                  <td style={{ fontWeight: 500, minWidth: 150 }}>{d.customer}<div style={{ fontSize: 11, color: 'var(--ink-3)' }}>{d.project}</div></td>
                  <td><span className={'badge ' + D.payerInfo[d.payer].badge}>{D.payerInfo[d.payer].label}</span></td>
                  <td><span className={'badge ' + (d.type === 'vat7' ? 'ok' : d.type === 'zero' ? 'info' : 'muted')}>{d.type === 'vat7' ? 'VAT 7%' : d.type === 'zero' ? 'VAT 0%' : 'ยกเว้น'}</span></td>
                  <td className="r num">{D.fmt(d.pre)}</td>
                  <td className="r num">{d.vat > 0 ? D.fmt(d.vat) : '—'}</td>
                  <td className="r num" style={{ fontWeight: 600 }}>{D.fmt(d.total)}</td>
                  <td className="r num" style={{ color: d.wht > 0 ? 'var(--info)' : 'var(--ink-3)' }}>{d.wht > 0 ? '-' + D.fmt(d.wht) : '—'}<div style={{ fontSize: 10, color: 'var(--ink-3)' }}>{d.whtRate > 0 ? d.whtRate + '%' : ''}</div></td>
                  <td className="r num" style={{ color: d.retention > 0 ? 'var(--ink-2)' : 'var(--ink-3)' }}>{d.retention > 0 ? '-' + D.fmt(d.retention) : '—'}<div style={{ fontSize: 10, color: 'var(--ink-3)' }}>{d.retRate > 0 ? d.retRate + '%' : ''}</div></td>
                  <td className="r num" style={{ fontWeight: 700, color: 'var(--ok)' }}>{D.fmt(d.netReceived)}</td>
                  <td><Status status={d.status} /></td>
                  {canEdit && (
                    <td className="c sticky-act">
                      <div style={{ display: 'flex', gap: 2, justifyContent: 'center' }}>
                        <button className="x-btn" title="แก้ไข" onClick={() => setModal(d)}><Icon name="edit" size={16} /></button>
                        {canDelete && <button className="x-btn" title="ลบ" style={{ color: 'var(--danger)' }} onClick={() => setDelRow(d)}><Icon name="trash" size={16} /></button>}
                      </div>
                    </td>
                  )}
                </tr>
              ))}
              {rows.length === 0 && (
                <tr><td colSpan={canEdit ? 12 : 11} style={{ textAlign: 'center', color: 'var(--ink-3)', padding: '26px 12px' }}>ยังไม่มีรายการ — กด “เพิ่มรายรับ” เพื่อเริ่มบันทึก</td></tr>
              )}
            </tbody>
            <tfoot><tr style={{ background: 'var(--surface-2)', fontWeight: 700 }}>
              <td colSpan="4" style={{ padding: 12 }}>รวมทั้งสิ้น</td>
              <td className="r num" style={{ padding: 12 }}>{D.fmt(t.pre)}</td>
              <td className="r num" style={{ padding: 12 }}>{D.fmt(t.vat)}</td>
              <td className="r num" style={{ padding: 12 }}>{D.fmt(t.total)}</td>
              <td className="r num" style={{ padding: 12, color: 'var(--info)' }}>-{D.fmt(t.wht)}</td>
              <td className="r num" style={{ padding: 12, color: 'var(--ink-2)' }}>-{D.fmt(t.ret)}</td>
              <td className="r num" style={{ padding: 12, color: 'var(--ok)' }}>{D.fmt(t.net)}</td><td></td>{canEdit && <td className="sticky-act"></td>}
            </tr></tfoot>
          </table>
        </div>
      </div>

      {modal && <IncomeModal record={modal === 'new' ? null : modal} defaultISO={defaultISO} onClose={() => setModal(null)} onSave={handleSave} />}
      {delRow && (
        <Modal title="ยืนยันการลบรายการ" icon="trash" onClose={() => setDelRow(null)}
          footer={<><button className="btn btn-ghost" onClick={() => setDelRow(null)}>ยกเลิก</button><button className="btn btn-danger" onClick={handleDelete}><Icon name="trash" className="ic" />ลบรายการ</button></>}>
          <div style={{ fontSize: 14, lineHeight: 1.7 }}>
            ต้องการลบรายรับของ <b>{delRow.customer}</b> ({delRow.docNo}) ยอด <b>{D.baht(delRow.total)}</b> ใช่หรือไม่?
            <div style={{ marginTop: 10 }} className="callout warn">
              <Icon name="alert" className="ic" />การลบจะมีผลทันที และทำให้ยอดสรุป ภ.พ.30 ของเดือนนี้เปลี่ยนตาม
            </div>
          </div>
        </Modal>
      )}
    </>
  );
}

function IncomeModal({ record, defaultISO, onClose, onSave }) {
  const r = record || {};
  const [dateISO, setDateISO] = useState(r.dateISO || defaultISO || new Date().toISOString().slice(0, 10));
  const [docNo, setDocNo] = useState(r.docNo || '');
  const [customer, setCustomer] = useState(r.customer || '');
  const [custTax, setCustTax] = useState(r.custTax && r.custTax !== '—' ? r.custTax : '');
  const [project, setProject] = useState(r.project || '');
  const [contractNo, setContractNo] = useState(r.contractNo || '');
  const [payer, setPayer] = useState(r.payer || 'gov');
  const [pre, setPre] = useState(r.pre != null ? String(r.pre) : '');
  const [taxType, setTaxType] = useState(r.type || 'vat7');
  const [status, setStatus] = useState(r.status || 'pending');
  const [err, setErr] = useState('');

  const r2 = (n) => Math.round(n * 100) / 100;
  const preN = parseFloat(pre) || 0;
  const vat = taxType === 'vat7' ? r2(preN * 0.07) : 0;
  const total = preN + vat;
  const whtRate = payer === 'gov' ? 1 : payer === 'company' ? 3 : 0;
  const retRate = payer === 'gov' ? 5 : 0;
  const wht = r2(preN * whtRate / 100);
  const ret = r2(preN * retRate / 100);
  const net = total - wht - ret;

  // ===== customer autocomplete (จากลูกค้าที่เคยบันทึก) =====
  const [sugFor, setSugFor] = useState(null); // 'name' | 'tax' | null
  const customerBook = React.useMemo(() => {
    const map = new Map();
    (D.income || []).forEach((x) => { if (x.customer && !map.has(x.customer)) map.set(x.customer, { customer: x.customer, custTax: x.custTax, payer: x.payer }); });
    (D.receivables || []).forEach((x) => { if (x.customer && !map.has(x.customer)) map.set(x.customer, { customer: x.customer, custTax: '—', payer: x.payer }); });
    return [...map.values()];
  }, []);
  const sugQuery = (sugFor === 'tax' ? custTax : customer).trim().toLowerCase();
  const suggestions = (sugQuery
    ? customerBook.filter((c) => c.customer.toLowerCase().includes(sugQuery) || (c.custTax || '').toLowerCase().includes(sugQuery))
    : customerBook).slice(0, 6);
  const pickCustomer = (c) => { setCustomer(c.customer); setCustTax(c.custTax && c.custTax !== '—' ? c.custTax : ''); if (c.payer) setPayer(c.payer); setSugFor(null); };

  const fmtThai = (iso) => { const d = new Date(iso); if (isNaN(d)) return iso; return d.getDate() + ' ' + D.thMonthsShort[d.getMonth()] + ' ' + String((d.getFullYear() + 543) % 100).padStart(2, '0'); };

  const save = () => {
    if (!customer.trim()) { setErr('กรุณากรอกชื่อลูกค้า'); return; }
    if (preN <= 0) { setErr('กรุณากรอกยอดก่อน VAT ให้มากกว่า 0'); return; }
    onSave({
      id: r.id || ('S' + Date.now()),
      docNo: docNo.trim() || '—',
      date: fmtThai(dateISO), dateISO,
      customer: customer.trim(), custTax: custTax.trim() || '—',
      payer, type: taxType,
      pre: preN, vat, total, project: project.trim(), contractNo: contractNo.trim(),
      whtRate, retRate, wht, retention: ret, netReceived: net,
      status,
    });
  };

  return (
    <Modal title={record ? 'แก้ไขรายรับ' : 'เพิ่มรายรับ / ใบกำกับภาษีขาย'} icon="income" onClose={onClose} wide
      footer={<><button className="btn btn-ghost" onClick={onClose}>ยกเลิก</button><button className="btn btn-primary" onClick={save}><Icon name="check" className="ic" />{record ? 'บันทึกการแก้ไข' : 'บันทึก'}</button></>}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 13 }}>
        {err && <div className="callout warn" style={{ padding: '9px 12px' }}><Icon name="alert" className="ic" />{err}</div>}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <Field label="วันที่"><ThaiDatePicker value={dateISO} onChange={setDateISO} /></Field>
          <Field label="เลขที่ใบกำกับ"><input className="input" value={docNo} onChange={(e) => setDocNo(e.target.value)} placeholder="TX68-05-005" /></Field>
        </div>
        <div style={{ position: 'relative' }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 12 }}>
            <Field label="ลูกค้า"><input className="input" value={customer} onFocus={() => setSugFor('name')} onChange={(e) => { setCustomer(e.target.value); setSugFor('name'); }} onBlur={() => setTimeout(() => setSugFor(null), 160)} placeholder="พิมพ์ชื่อเพื่อค้นหา / ผู้ซื้อ" /></Field>
            <Field label="เลขผู้เสียภาษีลูกค้า"><input className="input mono" value={custTax} onFocus={() => setSugFor('tax')} onChange={(e) => { setCustTax(e.target.value); setSugFor('tax'); }} onBlur={() => setTimeout(() => setSugFor(null), 160)} placeholder="ค้นหา/พิมพ์ 13 หลัก" /></Field>
          </div>
          {sugFor && suggestions.length > 0 && (
            <div className="card" style={{ position: 'absolute', top: '100%', left: 0, right: 0, zIndex: 6, marginTop: 4, boxShadow: 'var(--shadow-lg)', maxHeight: 250, overflowY: 'auto', padding: 4 }}>
              <div style={{ fontSize: 11, color: 'var(--ink-3)', padding: '6px 10px 4px', display: 'flex', alignItems: 'center', gap: 6 }}><Icon name="search" size={12} />ลูกค้าที่เคยบันทึก — กดเพื่อเติมอัตโนมัติ</div>
              {suggestions.map((c, i) => (
                <button type="button" key={i} onMouseDown={(e) => { e.preventDefault(); pickCustomer(c); }}
                  style={{ display: 'flex', alignItems: 'center', gap: 10, width: '100%', textAlign: 'left', padding: '8px 10px', borderRadius: 8 }}
                  onMouseEnter={(e) => e.currentTarget.style.background = 'var(--surface-2)'} onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontWeight: 600, fontSize: 13 }}>{c.customer}</div>
                    <div className="mono" style={{ fontSize: 11.5, color: 'var(--ink-3)' }}>{c.custTax || '—'}</div>
                  </div>
                  {c.payer && <span className={'badge ' + D.payerInfo[c.payer].badge} style={{ fontSize: 10 }}>{D.payerInfo[c.payer].label}</span>}
                </button>
              ))}
            </div>
          )}
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 12 }}>
          <Field label="โครงการ/งาน"><input className="input" value={project} onChange={(e) => setProject(e.target.value)} placeholder="เช่น งานถนน คสล. โครงการ B" /></Field>
          <Field label="เลขที่สัญญา/PO (งานงวด ใส่เลขเดียวกัน)"><input className="input mono" value={contractNo} onChange={(e) => setContractNo(e.target.value)} placeholder="เช่น จ.12/2568" /></Field>
        </div>

        <Field label="ประเภทผู้จ่ายเงิน (กำหนดการหัก ณ ที่จ่าย & เงินประกัน)">
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 8 }}>
            {[['gov', 'ราชการ', 'WHT 1% + ประกัน 5%'], ['company', 'นิติบุคคล', 'WHT 3%'], ['individual', 'บุคคล', 'ไม่มีหัก']].map(([k, l, s]) => (
              <button key={k} onClick={() => setPayer(k)} style={{ padding: '10px 8px', borderRadius: 10, border: '1px solid ' + (payer === k ? 'var(--primary)' : 'var(--line)'), background: payer === k ? 'var(--primary-tint)' : 'var(--surface)', textAlign: 'left' }}>
                <div style={{ fontWeight: 600, fontSize: 13 }}>{l}</div><div style={{ fontSize: 10.5, color: 'var(--ink-3)' }}>{s}</div>
              </button>
            ))}
          </div>
        </Field>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
          <Field label="ยอดก่อน VAT"><input className="input right mono" value={pre} onChange={(e) => setPre(e.target.value)} placeholder="0.00" /></Field>
          <Field label="ประเภทภาษี"><select className="select" value={taxType} onChange={(e) => setTaxType(e.target.value)}><option value="vat7">VAT 7%</option><option value="zero">VAT 0%</option><option value="exempt">ยกเว้น VAT</option></select></Field>
          <Field label="สถานะ"><select className="select" value={status} onChange={(e) => setStatus(e.target.value)}>{Object.entries(D.statusInfo).map(([k, v]) => <option key={k} value={k}>{v.label}</option>)}</select></Field>
        </div>

        {/* live computed breakdown */}
        <div style={{ background: 'var(--surface-2)', borderRadius: 11, padding: 14, display: 'flex', flexDirection: 'column', gap: 7, fontSize: 13.5 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between' }}><span style={{ color: 'var(--ink-2)' }}>VAT ({taxType === 'vat7' ? '7%' : '0%'})</span><span className="num">{D.fmt(vat)}</span></div>
          <div style={{ display: 'flex', justifyContent: 'space-between', fontWeight: 600 }}><span>ยอดรวมในใบกำกับ</span><span className="num">{D.fmt(total)}</span></div>
          <div className="divider" style={{ margin: '3px 0' }}></div>
          <div style={{ display: 'flex', justifyContent: 'space-between', color: 'var(--info)' }}><span>หัก ณ ที่จ่าย ({whtRate}%)</span><span className="num">-{D.fmt(wht)}</span></div>
          {retRate > 0 && <div style={{ display: 'flex', justifyContent: 'space-between', color: 'var(--ink-2)' }}><span>เงินประกันผลงาน ({retRate}%)</span><span className="num">-{D.fmt(ret)}</span></div>}
          <div className="divider" style={{ margin: '3px 0' }}></div>
          <div style={{ display: 'flex', justifyContent: 'space-between', fontWeight: 700, fontSize: 15 }}><span>ยอดรับเงินจริง</span><span className="num" style={{ color: 'var(--ok)' }}>{D.fmt(net)}</span></div>
        </div>
        {whtRate > 0 && <div className="callout info" style={{ padding: '9px 12px' }}><Icon name="info" className="ic" />ภาษีหัก ณ ที่จ่าย {D.fmt(wht)} บาท นำไปเครดิตภาษีเงินได้ปลายปีได้ — เก็บหนังสือรับรอง 50 ทวิ ไว้ด้วย</div>}
      </div>
    </Modal>
  );
}

/* ============ Expense (ภาษีซื้อ) ============ */
function ExpensePage({ onNav, pShort, period }) {
  const docs = D.docs.filter((d) => d.status !== 'deleted' && inPeriod(d.docDateISO, period));
  const hasData = docs.length > 0;
  const t = docs.reduce((a, d) => ({ pre: a.pre + d.pre, total: a.total + d.total, vatAll: a.vatAll + d.vat, vatCred: a.vatCred + (d.creditable ? d.vat : 0) }), { pre: 0, total: 0, vatAll: 0, vatCred: 0 });
  const byCat = {};
  docs.forEach((d) => { byCat[d.cat] = (byCat[d.cat] || { pre: 0, vat: 0, count: 0 }); byCat[d.cat].pre += d.pre; byCat[d.cat].vat += d.creditable ? d.vat : 0; byCat[d.cat].count++; });
  const cats = Object.entries(byCat).map(([id, v]) => ({ id, ...v })).sort((a, b) => b.pre - a.pre);
  const maxPre = Math.max(...cats.map((c) => c.pre), 1);

  if (!hasData) return (
    <>
      <div className="page-head">
        <div><div className="pt">รายจ่าย · ภาษีซื้อ</div><div className="ps">สรุปรายจ่ายตามหมวด และ VAT ซื้อที่ใช้เครดิตได้ · {pShort}</div></div>
      </div>
      <Empty icon="calendar" title={'ยังไม่มีรายจ่ายสำหรับ ' + pShort} sub="เลือกเดือนอื่นจากปฏิทินด้านบน หรือสแกนใบเสร็จของรอบนี้" action={<button className="btn btn-primary" onClick={() => onNav('scan')}><Icon name="scan" className="ic" />สแกนใบเสร็จ</button>} />
    </>
  );

  return (
    <>
      <div className="page-head">
        <div><div className="pt">รายจ่าย · ภาษีซื้อ</div><div className="ps">สรุปรายจ่ายตามหมวด และ VAT ซื้อที่ใช้เครดิตได้ · {pShort}</div></div>
        <div className="spacer"></div>
        <button className="btn btn-ghost"><Icon name="download" className="ic" />รายงานภาษีซื้อ</button>
        <button className="btn btn-primary" onClick={() => onNav('scan')}><Icon name="plus" className="ic" />เพิ่มรายจ่าย</button>
      </div>

      <div className="grid" style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', marginBottom: 16 }}>
        <Stat label="รายจ่ายรวม (ก่อน VAT)" icon="expense" value={D.baht(t.pre, 0)} />
        <Stat label="VAT ซื้อทั้งหมด" icon="vat" iconBg="var(--surface-2)" iconColor="var(--ink-2)" value={D.baht(t.vatAll, 0)} />
        <Stat label="VAT ซื้อ (เครดิตได้)" icon="checkCircle" iconBg="var(--ok-bg)" iconColor="var(--ok)" value={D.baht(t.vatCred, 0)} sub="ใบกำกับเต็มรูป" />
        <Stat label="VAT ซื้อ (เครดิตไม่ได้)" icon="alert" iconBg="var(--warn-bg)" iconColor="var(--warn)" value={D.baht(t.vatAll - t.vatCred, 0)} />
      </div>

      <div className="card">
        <div className="card-head"><h3>รายจ่ายแยกตามหมวด</h3><button className="btn btn-sm btn-soft" style={{ marginLeft: 'auto' }} onClick={() => onNav('docs')}>ดูรายการทั้งหมด</button></div>
        <div className="card-pad" style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          {cats.map((c) => (
            <div key={c.id} className="row-link" onClick={() => onNav('docs')}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 6 }}>
                <span style={{ width: 11, height: 11, borderRadius: 3, background: D.catColor(c.id) }}></span>
                <span style={{ fontWeight: 600, fontSize: 13.5 }}>{D.catLabel(c.id)}</span>
                <span className="badge muted" style={{ fontSize: 10.5 }}>{c.count} ใบ</span>
                <div style={{ flex: 1 }}></div>
                <span className="num" style={{ fontWeight: 700, fontSize: 14 }}>{D.baht(c.pre, 0)}</span>
                <span className="num" style={{ fontSize: 12, color: 'var(--ink-3)', width: 90, textAlign: 'right' }}>VAT {D.fmt0(c.vat)}</span>
              </div>
              <div className="bar-track"><div className="bar-fill" style={{ width: (c.pre / maxPre * 100) + '%', background: D.catColor(c.id) }}></div></div>
            </div>
          ))}
        </div>
      </div>
    </>
  );
}

/* ============ VAT ภ.พ.30 ============ */
function VatPage({ toast, period, setPeriod, pShort, pLong }) {
  const carryKey = 'bt_vatcarry_' + period.y + '_' + period.m;
  const [carryStr, setCarryStr] = useState('');
  useEffect(() => { const v = localStorage.getItem(carryKey); setCarryStr(v != null ? v : ''); }, [carryKey]);
  const setCarry = (val) => { setCarryStr(val); localStorage.setItem(carryKey, val); };

  const docs = D.docs.filter((d) => d.status !== 'deleted' && inPeriod(d.docDateISO, period));
  const incRows = D.income.filter((d) => inPeriod(d.dateISO, period));
  const hasData = docs.length > 0 || incRows.length > 0;
  const vatSales = incRows.reduce((a, d) => a + d.vat, 0);
  const saleVat7 = incRows.filter((d) => d.type === 'vat7').reduce((a, d) => a + d.pre, 0);
  const saleZero = incRows.filter((d) => d.type === 'zero').reduce((a, d) => a + d.pre, 0);
  const saleExempt = incRows.filter((d) => d.type === 'exempt').reduce((a, d) => a + d.pre, 0);
  const purchaseCred = docs.filter((d) => d.creditable).reduce((a, d) => a + d.pre, 0);
  const vatPurchase = docs.filter((d) => d.creditable).reduce((a, d) => a + d.vat, 0);
  const saleTotal = saleVat7 + saleZero + saleExempt;
  const purchaseAll = docs.reduce((a, d) => a + d.pre, 0);
  const carry = hasData ? (parseFloat(carryStr) || 0) : 0;
  const netBefore = vatSales - vatPurchase;
  const net = netBefore - carry;
  const payable = net > 0 ? net : 0;
  const creditFwd = net < 0 ? -net : 0;

  const printVat = () => {
    const c = D.company || {};
    const f = (n) => D.fmt(n || 0);
    const line = (label, val, opt = {}) =>
      `<tr${opt.strong ? ' class="strong"' : ''}${opt.hl ? ' class="hl"' : ''}><td>${label}</td><td class="num">${val < 0 ? '(' + f(-val) + ')' : f(val)}</td></tr>`;
    const html = `<!DOCTYPE html><html lang="th"><head><meta charset="utf-8">
<title>ภ.พ.30 ${pLong}</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Sans+Thai:wght@400;600;700&display=swap">
<style>
  * { box-sizing: border-box; }
  body { font-family: 'Noto Sans Thai', sans-serif; color: #1a1a1a; margin: 0; padding: 28px 34px; font-size: 13.5px; }
  h1 { font-size: 18px; margin: 0; }
  .sub { color: #666; font-size: 12px; margin-top: 2px; }
  .head { border-bottom: 2px solid #1f6f54; padding-bottom: 12px; margin-bottom: 16px; display:flex; justify-content:space-between; align-items:flex-end; }
  .biz { margin-bottom: 16px; line-height: 1.7; }
  .biz b { display:inline-block; min-width: 130px; color:#444; font-weight:600; }
  table { width: 100%; border-collapse: collapse; margin-bottom: 16px; }
  th { background:#eef4f1; text-align:left; padding:7px 12px; font-size:12px; border:1px solid #cdd9d4; }
  td { padding:7px 12px; border:1px solid #e2e8e5; }
  td.num { text-align:right; font-variant-numeric: tabular-nums; }
  tr.strong td { font-weight:700; background:#f6faf8; }
  tr.hl td { font-weight:700; background:#e7f3ec; font-size:15px; }
  .note { font-size:11px; color:#888; margin-top:8px; line-height:1.6; }
  .sign { display:flex; justify-content:space-between; margin-top:42px; }
  .sign div { text-align:center; width:45%; }
  .sign .ln { border-top:1px dotted #888; margin-top:40px; padding-top:6px; font-size:12px; color:#555; }
  @media print { body { padding: 0; } button { display:none; } }
</style></head><body>
<div class="head">
  <div><h1>แบบสรุป ภ.พ.30 — ภาษีมูลค่าเพิ่ม</h1><div class="sub">ประจำเดือนภาษี ${pLong}</div></div>
  <div style="text-align:right;font-size:12px;color:#555">พิมพ์เมื่อ ${new Date().toLocaleString('th-TH')}</div>
</div>
<div class="biz">
  <div><b>ผู้ประกอบการ</b> ${c.name || '-'}</div>
  <div><b>เลขประจำตัวผู้เสียภาษี</b> ${c.taxId || '-'} &nbsp;&nbsp; <b style="min-width:50px">สาขา</b> ${c.branch || '-'}</div>
  <div><b>ที่อยู่</b> ${c.address || '-'}</div>
  <div><b>โทรศัพท์</b> ${c.phone || '-'}</div>
</div>
<table>
  <thead><tr><th>รายการที่ 1 — ภาษีขาย (Output VAT)</th><th class="num" style="width:180px">บาท</th></tr></thead>
  <tbody>
    ${line('ยอดขายรวมทั้งเดือนนี้', saleTotal)}
    ${line('หัก ยอดขายที่ได้รับยกเว้น VAT', saleExempt)}
    ${line('หัก ยอดขายที่เสียภาษีอัตรา 0%', saleZero)}
    ${line('ยอดขายที่ต้องเสียภาษี (7%)', saleVat7, { strong: true })}
    ${line('ภาษีขายเดือนนี้', vatSales, { hl: true })}
  </tbody>
</table>
<table>
  <thead><tr><th>รายการที่ 2 — ภาษีซื้อ (Input VAT)</th><th class="num" style="width:180px">บาท</th></tr></thead>
  <tbody>
    ${line('ยอดซื้อที่มีสิทธินำภาษีซื้อมาหัก', purchaseCred, { strong: true })}
    ${line('ภาษีซื้อเดือนนี้ (เครดิตได้)', vatPurchase, { hl: true })}
  </tbody>
</table>
<table>
  <thead><tr><th>รายการที่ 3 — การคำนวณภาษี</th><th class="num" style="width:180px">บาท</th></tr></thead>
  <tbody>
    ${line('ภาษีขาย', vatSales)}
    ${line('หัก ภาษีซื้อ', -vatPurchase)}
    ${line('ภาษีก่อนหักเครดิตยกมา', netBefore, { strong: true })}
    ${line('หัก เครดิตภาษียกมาเดือนก่อน', -carry)}
    ${payable > 0
      ? line('ภาษีที่ต้องชำระสุทธิ', payable, { hl: true })
      : line('เครดิตภาษีที่เหลือยกไปเดือนถัดไป', creditFwd, { hl: true })}
  </tbody>
</table>
<div class="note">⚠️ เอกสารนี้เป็น <b>สรุปช่วยจัดเตรียม</b> สร้างจากระบบบัญชี·ภาษี — ไม่ใช่แบบยื่นจริงของกรมสรรพากร โปรดตรวจสอบกับสำนักงานบัญชี/ผู้สอบบัญชีก่อนยื่น · กำหนดยื่นภายในวันที่ 15 ของเดือนถัดไป (กระดาษ) หรือ 23 (e-Filing)</div>
<div class="sign">
  <div><div class="ln">ผู้จัดทำ / วันที่</div></div>
  <div><div class="ln">ผู้มีอำนาจลงนาม / วันที่</div></div>
</div>
<script>window.onload=function(){setTimeout(function(){window.print();},300);};</script>
</body></html>`;
    const w = window.open('', '_blank');
    if (!w) { toast('เบราว์เซอร์บล็อกหน้าต่างใหม่ — อนุญาต popup แล้วลองใหม่', 'warn'); return; }
    w.document.write(html);
    w.document.close();
    toast('เปิดแบบ ภ.พ.30 — กดพิมพ์หรือบันทึกเป็น PDF ได้เลย');
  };

  const Row = ({ label, value, strong, hl, indent }) => (
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: strong ? '13px 16px' : '9px 16px', paddingLeft: indent ? 34 : 16, background: hl ? 'var(--primary-tint)' : 'transparent', borderRadius: hl ? 9 : 0, fontSize: strong ? 15 : 13.5, fontWeight: strong ? 700 : 500 }}>
      <span style={{ color: strong ? 'var(--ink)' : 'var(--ink-2)' }}>{label}</span>
      <span className="num" style={{ fontWeight: strong ? 700 : 600, fontSize: strong ? 16 : 13.5 }}>{value}</span>
    </div>
  );

  return (
    <>
      <div className="page-head">
        <div><div className="pt">ภ.พ.30 รายเดือน</div><div className="ps">แบบแสดงรายการภาษีมูลค่าเพิ่ม · ประจำเดือน {pLong}</div></div>
        <div className="spacer"></div>
        <div className="seg">
          {[-1, 0, 1].map((off) => {
            let m = period.m + off, y = period.y;
            if (m < 0) { m = 11; y--; } if (m > 11) { m = 0; y++; }
            return <button key={off} className={off === 0 ? 'on' : ''} onClick={() => setPeriod({ m, y })}>{D.thMonthsShort[m]}</button>;
          })}
        </div>
        <button className="btn btn-primary" onClick={printVat} disabled={!hasData}><Icon name="download" className="ic" />ดาวน์โหลด ภ.พ.30</button>
      </div>

      {!hasData && <Empty icon="calendar" title={'ยังไม่มีข้อมูล ภ.พ.30 สำหรับ ' + pShort} sub="เลือกเดือนที่มีรายการ หรือบันทึกรายรับ-รายจ่ายของรอบนี้ก่อน" />}
      {hasData && (
      <>

      {/* ===== สรุปยอดสำหรับยื่น ภ.พ.30 ===== */}
      <div className="card" style={{ marginBottom: 16, overflow: 'hidden' }}>
        <div className="card-head"><h3>สรุปยอดสำหรับยื่น ภ.พ.30</h3><span className="sub" style={{ marginLeft: 'auto' }}>ประจำเดือน {pLong}</span></div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))' }}>
          {[
            { lbl: 'ยอดขายรวม', val: saleTotal, sub: 'ก่อน VAT', color: 'var(--ink)' },
            { lbl: 'ภาษีขาย', val: vatSales, sub: 'Output VAT', color: 'var(--ink)' },
            { lbl: 'ยอดซื้อรวม', val: purchaseAll, sub: 'เครดิตได้ ' + D.fmt0(purchaseCred), color: 'var(--ink)' },
            { lbl: 'ภาษีซื้อ', val: vatPurchase, sub: 'Input VAT (เครดิต)', color: 'var(--ink)' },
          ].map((c, i) => (
            <div key={c.lbl} style={{ padding: '15px 18px', borderRight: '1px solid var(--line-2)', borderTop: i >= 0 ? 'none' : 'none' }}>
              <div style={{ fontSize: 12, color: 'var(--ink-3)', fontWeight: 500 }}>{c.lbl}</div>
              <div className="num" style={{ fontSize: 21, fontWeight: 700, marginTop: 5, color: c.color }}>{D.baht(c.val, 0)}</div>
              <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 2 }}>{c.sub}</div>
            </div>
          ))}
          <div style={{ padding: '15px 18px', background: payable > 0 ? 'var(--warn-bg)' : 'var(--ok-bg)' }}>
            <div style={{ fontSize: 12, color: payable > 0 ? 'oklch(0.45 0.1 65)' : 'var(--ok)', fontWeight: 600 }}>{payable > 0 ? 'ยอดที่ต้องยื่น/ชำระ' : 'เครดิตยกไปเดือนหน้า'}</div>
            <div className="num" style={{ fontSize: 23, fontWeight: 700, marginTop: 4, color: payable > 0 ? 'var(--warn)' : 'var(--ok)' }}>{D.baht(payable > 0 ? payable : creditFwd, 0)}</div>
            <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 2 }}>{carry > 0 ? 'หลังหักเครดิตยกมา ' + D.fmt0(carry) : 'ภาษีขาย − ภาษีซื้อ'}</div>
          </div>
        </div>
      </div>

      <div className="grid" style={{ gridTemplateColumns: 'minmax(0, 1fr) 340px', alignItems: 'start', gap: 16 }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          {/* sales section */}
          <div className="card">
            <div className="card-head" style={{ background: 'var(--surface-2)' }}><div className="stat-ic" style={{ background: 'var(--primary-tint)', color: 'var(--primary)', width: 30, height: 30 }}><Icon name="income" size={16} /></div><h3>ภาษีขาย (Output VAT)</h3></div>
            <div style={{ padding: '8px 4px' }}>
              <Row label="ยอดขายที่ต้องเสีย VAT (7%)" value={D.fmt(saleVat7)} indent />
              <Row label="ยอดขาย VAT 0%" value={D.fmt(saleZero)} indent />
              <Row label="ยอดขายยกเว้น VAT" value={D.fmt(saleExempt)} indent />
              <div className="divider" style={{ margin: '6px 16px' }}></div>
              <Row label="ยอดขายรวมเดือนนี้" value={D.fmt(saleVat7 + saleZero + saleExempt)} />
              <Row label="ภาษีขาย" value={D.fmt(vatSales)} strong hl />
            </div>
          </div>

          {/* purchase section */}
          <div className="card">
            <div className="card-head" style={{ background: 'var(--surface-2)' }}><div className="stat-ic" style={{ background: 'var(--info-bg)', color: 'var(--info)', width: 30, height: 30 }}><Icon name="expense" size={16} /></div><h3>ภาษีซื้อ (Input VAT)</h3></div>
            <div style={{ padding: '8px 4px' }}>
              <Row label="ยอดซื้อที่ใช้เครดิตภาษีได้" value={D.fmt(purchaseCred)} indent />
              <Row label="ภาษีซื้อ (เครดิตได้)" value={D.fmt(vatPurchase)} strong hl />
            </div>
          </div>
        </div>

        {/* net calc */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16, position: 'sticky', top: 78 }}>
          <div className="card">
            <div className="card-head"><h3>สรุปภาษีสุทธิ</h3></div>
            <div style={{ padding: '10px 4px' }}>
              <Row label="ภาษีขาย" value={D.fmt(vatSales)} />
              <Row label="หัก ภาษีซื้อ" value={'(' + D.fmt(vatPurchase) + ')'} />
              <div className="divider" style={{ margin: '4px 16px' }}></div>
              <Row label="ภาษีก่อนเครดิตยกมา" value={D.fmt(netBefore)} />
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '9px 16px' }}>
                <span style={{ color: 'var(--ink-2)', fontSize: 13.5, fontWeight: 500 }}>หัก เครดิตยกมาเดือนก่อน</span>
                <div style={{ display: 'flex', alignItems: 'center', gap: 4, color: 'var(--ink-3)' }}>
                  (<input className="input right mono" style={{ width: 116, padding: '5px 9px', fontSize: 13 }} value={carryStr} onChange={(e) => setCarry(e.target.value)} placeholder="0.00" inputMode="decimal" />)
                </div>
              </div>
            </div>
            <div style={{ padding: 16, borderTop: '1px solid var(--line-2)' }}>
              <div style={{ borderRadius: 12, padding: 16, background: payable > 0 ? 'var(--warn-bg)' : 'var(--ok-bg)', textAlign: 'center' }}>
                <div style={{ fontSize: 13, fontWeight: 600, color: payable > 0 ? 'oklch(0.45 0.1 65)' : 'var(--ok)' }}>{payable > 0 ? 'ภาษีที่ต้องชำระสุทธิ' : 'เครดิตภาษียกไปเดือนถัดไป'}</div>
                <div className="num" style={{ fontSize: 30, fontWeight: 700, marginTop: 4, color: payable > 0 ? 'var(--warn)' : 'var(--ok)' }}>{D.baht(payable > 0 ? payable : creditFwd)}</div>
              </div>
              {payable > 0
                ? <button className="btn btn-primary btn-block" style={{ marginTop: 12 }} onClick={() => toast('ทำเครื่องหมายชำระแล้ว')}><Icon name="check" className="ic" />บันทึกการชำระ</button>
                : <div className="callout info" style={{ marginTop: 12, padding: '9px 12px' }}><Icon name="info" className="ic" />เครดิตนี้จะยกไปหักในเดือน มิ.ย. 2568 อัตโนมัติ</div>}
            </div>
          </div>
          <div className="callout warn"><Icon name="calendar" className="ic" /><div>กำหนดยื่น ภ.พ.30 ภายในวันที่ 15 ของเดือนถัดไป (ยื่นกระดาษ) หรือวันที่ 23 (ยื่นออนไลน์ผ่าน e-Filing)</div></div>
        </div>
      </div>
      </>
      )}
    </>
  );
}

window.IncomePage = IncomePage;
window.ExpensePage = ExpensePage;
window.VatPage = VatPage;
