/* =========================================================================
   screens-tax.jsx — "ภาษีค่าแรง" (Payroll Tax)
   - สรุปค่าแรงสะสมรายเดือน / รายปี ต่อคน (อ่านจาก attendance เดิม ไม่แตะข้อมูล)
   - แก้ไข (แต่ง) ตัวเลขรายเดือนได้ — เก็บแยกในตาราง adjustments (kind='taxadj',
     period='tm-YYYY-MM') จึงไม่กระทบงวดจ่าย/สลิปเดิม
   - ปุ่มสรุปรายเดือน + ออกใบสำคัญจ่าย (PV) / ใบเสร็จยอดเดือน
   - เอกสารสรรพากร: ใบสำคัญจ่าย, หนังสือรับรองหัก ณ ที่จ่าย (50 ทวิ), สรุปลูกจ้างรายปี
   ========================================================================= */
const { useState:txS, useMemo:txM } = React;

/* ---------- period key สำหรับ override รายเดือน (ไม่ชนกับงวดจ่ายซึ่งเป็นวันที่) ---------- */
const TMKEY = (y, m) => `tm-${y}-${String(m).padStart(2, '0')}`;

/* ---------- ค่าแรงรวมของ "เดือนปฏิทิน" (อ่านจาก attendance อย่างเดียว) ---------- */
function wageForMonth(db, workerId, year, month) {
  const w = db.workers.find(x => x.id === workerId);
  const blank = { base: 0, ot: 0, gross: 0, dayUnits: 0, advance: 0, atts: [] };
  if (!w) return blank;
  const prefix = `${year}-${String(month).padStart(2, '0')}`;
  const atts = db.attendance.filter(a => a.workerId === workerId && a.date.startsWith(prefix));
  let dayUnits = 0, ot = 0, advance = 0;
  for (const a of atts) {
    const v = STATUS[a.status]?.val ?? 0;
    dayUnits += v;
    ot += (Number(a.otHours) || 0) * (Number(w.otRate) || 0) + (Number(a.otFlat) || 0);
    advance += Number(a.advance) || 0;
  }
  const base = w.type === 'daily' ? dayUnits * (Number(w.dailyRate) || 0) : (Number(w.monthlyRate) || 0);
  return { base, ot, gross: base + ot, dayUnits, advance, atts };
}

/* ---------- override รายเดือน (ตัวเลขที่ผู้ใช้แก้เอง) ---------- */
function monthOverride(db, workerId, y, m) {
  return db.adjustments.find(a => a.workerId === workerId && a.period === TMKEY(y, m) && a.kind === 'taxadj') || null;
}
/* ค่าแรงรายเดือนที่ "ใช้จริง" — ถ้ามี override ใช้ค่านั้น ไม่งั้นใช้ที่คำนวณ */
function effMonth(db, workerId, y, m) {
  const calc = wageForMonth(db, workerId, y, m);
  const o = monthOverride(db, workerId, y, m);
  if (o) return { ...calc, gross: Number(o.amount) || 0, overridden: true, note: o.label || '' };
  return { ...calc, overridden: false, note: '' };
}
/* ค่าแรงทั้งปีต่อคน */
function yearWage(db, workerId, year) {
  const months = [];
  let total = 0, dayUnits = 0, ot = 0;
  for (let m = 1; m <= 12; m++) {
    const e = effMonth(db, workerId, year, m);
    months.push(e); total += e.gross; dayUnits += e.dayUnits; ot += e.ot;
  }
  return { months, total, dayUnits, ot };
}

/* ---------- ภาษีเงินได้บุคคลธรรมดา 40(1) เงินเดือน/ค่าจ้าง (อัตราก้าวหน้า) ---------- */
function pitProgressive(netIncome) {
  const brackets = [
    [150000, 0], [300000, 0.05], [500000, 0.10], [750000, 0.15],
    [1000000, 0.20], [2000000, 0.25], [5000000, 0.30], [Infinity, 0.35],
  ];
  let tax = 0, prev = 0;
  for (const [cap, rate] of brackets) {
    if (netIncome > prev) { tax += (Math.min(netIncome, cap) - prev) * rate; prev = cap; }
    else break;
  }
  return Math.max(0, Math.round(tax));
}
/* ภาษีหัก ณ ที่จ่ายทั้งปี: รายได้ - ค่าใช้จ่าย(50% สูงสุด 100,000) - ลดหย่อนส่วนตัว 60,000 - ปกส.(สูงสุด 9,000) */
function withholdingYear(annualGross, ssoPaid = 0) {
  const expense = Math.min(annualGross * 0.5, 100000);
  const personal = 60000;
  const sso = Math.min(ssoPaid, 9000);
  const net = Math.max(0, annualGross - expense - personal - sso);
  return { expense, personal, sso, net, tax: pitProgressive(net) };
}
/* ประกันสังคมรายเดือน 5% เพดานตามตั้งค่า (default 750) */
function ssoMonth(gross, settings) {
  const rate = settings?.ssRate ?? 0.05;
  const cap = settings?.ssCap ?? 750;
  return Math.min(Math.round(gross * rate), cap);
}

/* ---------- พิมพ์เอกสาร (เรนเดอร์ React element → iframe → print) ---------- */
function printElement(el, page = 'A4') {
  const holder = document.createElement('div');
  holder.style.cssText = 'position:fixed;left:-99999px;top:0;width:820px;';
  document.body.appendChild(holder);
  const root = ReactDOM.createRoot(holder);
  root.render(el);
  requestAnimationFrame(() => requestAnimationFrame(() => {
    try {
      const html = holder.innerHTML;
      let css = '';
      document.querySelectorAll('style').forEach(s => { css += s.textContent + '\n'; });
      const old = document.getElementById('print-frame'); if (old) old.remove();
      const f = document.createElement('iframe');
      f.id = 'print-frame';
      f.setAttribute('aria-hidden', 'true');
      f.style.cssText = 'position:fixed;right:0;bottom:0;width:0;height:0;border:0;visibility:hidden;';
      document.body.appendChild(f);
      const idoc = f.contentWindow.document;
      idoc.open();
      idoc.write(
        '<!DOCTYPE html><html lang="th"><head><meta charset="utf-8"/>'
        + '<link href="https://fonts.googleapis.com/css2?family=Kanit:wght@400;500;600;700;800&family=IBM+Plex+Sans+Thai:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet"/>'
        + '<style>' + css
        + ` @page{size:${page};margin:10mm;} html,body{background:#fff;margin:0;padding:0;}`
        + ' body{-webkit-print-color-adjust:exact;print-color-adjust:exact;}'
        + ' @media print{ body, body *{ visibility:visible !important; } }'
        + '</style></head><body>' + html + '</body></html>'
      );
      idoc.close();
      const cleanup = () => { const x = document.getElementById('print-frame'); if (x) x.remove(); try { root.unmount(); } catch (_) {} if (holder.parentNode) holder.parentNode.removeChild(holder); };
      setTimeout(() => {
        try { f.contentWindow.focus(); f.contentWindow.print(); } catch (e) { window.print(); }
        setTimeout(cleanup, 1500);
      }, 450);
    } catch (e) {
      if (holder.parentNode) holder.parentNode.removeChild(holder);
      try { window.print(); } catch (_) { alert('พิมพ์ไม่สำเร็จ: ' + e.message + ' — ลองกด Ctrl+P'); }
    }
  }));
}

/* ---------- ดาวน์โหลดเอกสารเป็นไฟล์ HTML แก้ไขได้ (เปิดในเบราว์เซอร์ไหนก็ได้ คลิกแก้ + พิมพ์ได้ ไม่ต้องพึ่งระบบ) ---------- */
function downloadElement(el, filename) {
  const holder = document.createElement('div');
  holder.style.cssText = 'position:fixed;left:-99999px;top:0;width:820px;';
  document.body.appendChild(holder);
  const root = ReactDOM.createRoot(holder);
  root.render(el);
  requestAnimationFrame(() => requestAnimationFrame(() => {
    try {
      const inner = holder.innerHTML;
      let css = ''; document.querySelectorAll('style').forEach(s => { css += s.textContent + '\n'; });
      const fonts = 'https://fonts.googleapis.com/css2?family=Kanit:wght@400;500;600;700;800&family=IBM+Plex+Sans+Thai:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap';
      const html = '<!DOCTYPE html><html lang="th"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>' + filename + '</title>'
        + '<link href="' + fonts + '" rel="stylesheet"/>'
        + '<style>' + css
        + " @page{size:A5;margin:7mm;} body{background:#e9e9e9;margin:0;padding:16px;font-family:'IBM Plex Sans Thai',sans-serif;}"
        + ' .sheet{background:#fff;max-width:660px;margin:0 auto;box-shadow:0 4px 20px rgba(0,0,0,.25);}'
        + ' .bar{max-width:660px;margin:0 auto 12px;display:flex;gap:8px;align-items:center;flex-wrap:wrap;}'
        + ' .bar button{padding:8px 16px;border:0;border-radius:8px;background:#E8852B;color:#fff;font-weight:700;cursor:pointer;font-family:inherit;}'
        + ' .bar .hint{font-size:12.5px;color:#555;}'
        + ' [contenteditable]:focus{outline:2px solid #E8852B55;border-radius:3px;}'
        + ' @media print{ .bar{display:none!important;} body{background:#fff;padding:0;} .sheet{box-shadow:none;} }'
        + '</style></head><body>'
        + '<div class="bar"><button onclick="window.print()">🖨️ พิมพ์ / บันทึก PDF</button><span class="hint">คลิกที่ตัวเลข/ข้อความเพื่อแก้ไข แล้วกดพิมพ์</span></div>'
        + '<div class="sheet" contenteditable="true">' + inner + '</div></body></html>';
      const blob = new Blob([html], { type: 'text/html;charset=utf-8' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a'); a.href = url; a.download = filename + '.html';
      document.body.appendChild(a); a.click(); a.remove();
      setTimeout(() => URL.revokeObjectURL(url), 3000);
    } catch (e) { alert('สร้างไฟล์ไม่สำเร็จ: ' + e.message); }
    finally { try { root.unmount(); } catch (_) {} if (holder.parentNode) holder.parentNode.removeChild(holder); }
  }));
}

/* ---------- หัวเอกสาร (ใช้ชื่อ/ที่อยู่สำหรับเอกสารราชการ แยกจากสลิป ถ้ากรอกไว้) ---------- */
function docSettings(db) {
  const s = db.settings || {};
  return { ...s, company: (s.docCompany || '').trim() || s.company, address: (s.docAddress || '').trim() || s.address };
}

/* ---------- บาทเป็นตัวอักษรไทย (สำหรับใบสำคัญจ่าย) ---------- */
function bahtText(amount) {
  amount = Math.round((Number(amount) || 0) * 100) / 100;
  const num = ['ศูนย์', 'หนึ่ง', 'สอง', 'สาม', 'สี่', 'ห้า', 'หก', 'เจ็ด', 'แปด', 'เก้า'];
  const pos = ['', 'สิบ', 'ร้อย', 'พัน', 'หมื่น', 'แสน', 'ล้าน'];
  function readInt(s) {
    s = String(parseInt(s, 10) || 0);
    if (s === '0') return 'ศูนย์';
    let out = '';
    const len = s.length;
    for (let i = 0; i < len; i++) {
      const d = +s[i];
      const p = (len - i - 1) % 6;
      const isMillion = (len - i - 1) >= 6 && (len - i - 1) % 6 === 0;
      if (d !== 0) {
        if (p === 1 && d === 1) out += 'สิบ';
        else if (p === 1 && d === 2) out += 'ยี่' + pos[p];
        else if (p === 0 && d === 1 && out !== '' && len > 1) out += 'เอ็ด';
        else out += num[d] + pos[p];
      }
      if (isMillion) out += 'ล้าน';
    }
    return out;
  }
  const baht = Math.floor(amount);
  const satang = Math.round((amount - baht) * 100);
  let txt = readInt(baht) + 'บาท';
  if (satang > 0) txt += readInt(satang) + 'สตางค์';
  else txt += 'ถ้วน';
  return txt;
}

/* =========================================================================
   เอกสาร: ใบสำคัญจ่าย (Payment Voucher)
   ========================================================================= */
function PaymentVoucherDoc({ settings, no, dateStr, payee, items, deductions = [], net, payMethod = '' }) {
  const fmt = s => s ? thaiDate(s) : '';
  const payLabel = payMethod === 'cash' ? 'เงินสด' : payMethod === 'transfer' ? 'เงินโอน' : payMethod === 'cheque' ? 'เช็คธนาคาร' : 'เงินสด / โอน';
  const drTotal = items.reduce((t, x) => t + (Number(x.amount) || 0), 0); // ค่าจ้าง (เดบิต)
  const crLines = [
    ...deductions.filter(d => (Number(d.amount) || 0) > 0).map(d => [d.label, Number(d.amount) || 0, /ภาษี/.test(d.label) ? 'WHT' : '', d.bill || '']),
    [payLabel, net, '', ''],
  ];
  const crTotal = crLines.reduce((t, x) => t + (Number(x[1]) || 0), 0);
  const bodyRows = Math.max(items.length + crLines.length, 6);
  const blanks = bodyRows - items.length - crLines.length;
  const cell = 'border border-[#bbb] py-1.5 px-2';
  return (
    <div className="bg-white text-[#1a1a1a] w-full" style={{ fontFamily: "'IBM Plex Sans Thai', sans-serif" }}>
      {/* หัวเอกสาร: ชื่อบริษัทบนสุด */}
      <div className="px-8 pt-6 pb-1 text-center">
        <div className="font-display font-extrabold text-lg leading-tight" style={{ color: '#92500f' }}>{settings.company}</div>
        <div className="text-[11px] text-[#555] leading-snug">{settings.address}</div>
        <div className="text-[11px] text-[#555] num">เลขประจำตัวผู้เสียภาษี {settings.taxId} · โทร {settings.phone}</div>
      </div>

      {/* ชื่อเอกสาร (ซ้าย) + เลขที่/วันที่ (ขวา) */}
      <div className="px-8 pt-2 pb-2 flex items-end justify-between border-b-2 border-[#1a1a1a]">
        <div>
          <div className="font-display font-bold text-xl leading-none">ใบสำคัญจ่าย</div>
          <div className="text-[10px] text-[#777] tracking-wide">PAYMENT VOUCHER</div>
        </div>
        <div className="text-[12px] text-right">
          <div><span className="text-[#777]">เลขที่ </span><span className="num font-semibold">{no}</span></div>
          <div><span className="text-[#777]">วันที่ </span><span className="num font-semibold">{fmt(dateStr)}</span></div>
        </div>
      </div>

      <div className="px-8 pt-2.5 pb-1 text-[13px]">
        <span className="text-[#777]">จ่ายให้แก่ </span>
        <span className="font-semibold">{payee}</span>
      </div>

      {/* วิธีจ่าย */}
      <div className="px-8 py-1 flex flex-wrap items-center gap-x-5 gap-y-1 text-[11.5px] text-[#444]">
        <span>{payMethod === 'cash' ? '☑' : '☐'} เงินสด</span><span>{payMethod === 'transfer' ? '☑' : '☐'} โอนเข้าบัญชี</span><span>{payMethod === 'cheque' ? '☑' : '☐'} เช็คธนาคาร</span>
        <span className="text-[#999]">เลขที่เช็ค ............</span>
        <span className="text-[#999]">ลงวันที่ ............</span>
      </div>

      {/* จำนวนเงินตัวอักษร (เหนือตาราง ตามฟอร์ม) */}
      <div className="px-8 py-1.5 text-[12px]">
        <span className="text-[#777]">จำนวนเงิน (ตัวอักษร) </span>
        <span className="font-semibold">({bahtText(net)})</span>
      </div>

      {/* ตารางบัญชี DR / CR */}
      <div className="px-8 pt-1">
        <table className="w-full text-[12px] border-collapse">
          <thead>
            <tr className="bg-[#f0f0f0] text-[#444]">
              <th className={cell + ' text-left w-20'}>เลขที่บิล</th>
              <th className={cell + ' text-left'}>รายการ / Description</th>
              <th className={cell + ' text-left w-20'}>รหัส</th>
              <th className={cell + ' text-right w-24'}>DR</th>
              <th className={cell + ' text-right w-24'}>CR</th>
            </tr>
          </thead>
          <tbody>
            {items.map((it, i) => (
              <tr key={'d' + i}>
                <td className={cell + ' num text-[#666]'}>{it.bill || ''}</td>
                <td className={cell}>{it.label}</td>
                <td className={cell + ' num text-[#666]'}>{it.code || ''}</td>
                <td className={cell + ' text-right num'} style={{ color: '#b3261e' }}>{baht(it.amount)}</td>
                <td className={cell}></td>
              </tr>
            ))}
            {Array.from({ length: Math.max(0, blanks) }).map((_, i) => (
              <tr key={'b' + i}><td className={cell + ' py-2.5'}>&nbsp;</td><td className={cell}></td><td className={cell}></td><td className={cell}></td><td className={cell}></td></tr>
            ))}
            {crLines.map((c, i) => (
              <tr key={'c' + i}>
                <td className={cell + ' num text-[#666]'}>{c[3] || ''}</td>
                <td className={cell}>{c[0]}</td>
                <td className={cell}></td>
                <td className={cell}></td>
                <td className={cell + ' text-right num'}>{baht(c[1])}</td>
              </tr>
            ))}
            <tr className="font-bold" style={{ background: '#fbf3e8' }}>
              <td className={cell + ' text-right'} colSpan={3}>รวม</td>
              <td className={cell + ' text-right num'} style={{ color: '#b3261e' }}>{baht(drTotal)}</td>
              <td className={cell + ' text-right num'}>{baht(crTotal)}</td>
            </tr>
          </tbody>
        </table>
      </div>

      {/* ลายเซ็น 4 จุด */}
      <div className="px-8 pt-10 pb-6 grid grid-cols-4 gap-5 text-center text-[11px] text-[#555]">
        <div className="border-t border-[#999] pt-1.5">ผู้จัดทำ</div>
        <div className="border-t border-[#999] pt-1.5">ผู้ตรวจสอบ</div>
        <div className="border-t border-[#999] pt-1.5">ผู้อนุมัติ</div>
        <div className="border-t border-[#999] pt-1.5">ผู้รับเงิน</div>
      </div>
    </div>
  );
}

/* =========================================================================
   Modal: ใบสำคัญจ่าย — แก้ไข/กรอกตัวเลขเองได้ก่อนพิมพ์
   ========================================================================= */
function VoucherModal({ open, onClose, initial, settings }) {
  const [v, setV] = txS(null);
  React.useEffect(() => {
    if (open) setV({ whtRate: 0, payMethod: '', ...(initial || { no: '', dateStr: ymd(TODAY), payee: '', items: [{ bill: '', label: '', amount: 0 }], deductions: [] }) });
  }, [open, initial]);
  if (!open || !v) return null;
  const drTotal = v.items.reduce((t, x) => t + (Number(x.amount) || 0), 0);
  const dedTotal = v.deductions.reduce((t, x) => t + (Number(x.amount) || 0), 0);
  const whtRate = Number(v.whtRate) || 0;
  const whtAmount = Math.round(drTotal * whtRate) / 100; // หัก ณ ที่จ่าย = ยอดเดบิต × อัตรา%
  const net = drTotal - dedTotal - whtAmount;
  const upd = (patch) => setV(p => ({ ...p, ...patch }));
  const setItem = (i, k, val) => setV(p => ({ ...p, items: p.items.map((it, j) => j === i ? { ...it, [k]: val } : it) }));
  const setDed = (i, k, val) => setV(p => ({ ...p, deductions: p.deductions.map((it, j) => j === i ? { ...it, [k]: val } : it) }));
  const addItem = () => setV(p => ({ ...p, items: [...p.items, { bill: '', label: '', amount: 0 }] }));
  const delItem = (i) => setV(p => ({ ...p, items: p.items.filter((_, j) => j !== i) }));
  const addDed = () => setV(p => ({ ...p, deductions: [...p.deductions, { label: '', amount: 0 }] }));
  const delDed = (i) => setV(p => ({ ...p, deductions: p.deductions.filter((_, j) => j !== i) }));
  const txParts = (v.dateStr || '').split('-');
  const txCode = txParts.length === 3 ? ('TX' + String((Number(txParts[0]) + 543) % 100).padStart(2, '0') + txParts[1] + txParts[2]) : 'TX';
  const docEl = () => (
    <PaymentVoucherDoc settings={settings} no={v.no} dateStr={v.dateStr} payee={v.payee}
      items={v.items.filter(x => x.label || x.amount)}
      deductions={[...v.deductions.filter(x => x.label || x.amount), ...(whtAmount > 0 ? [{ label: `หัก ภาษี ณ ที่จ่าย ${whtRate}%`, amount: whtAmount, bill: txCode }] : [])]}
      net={net} payMethod={v.payMethod} />
  );
  const doPrint = () => printElement(docEl(), 'A5');
  const doDownload = () => downloadElement(docEl(), 'ใบสำคัญจ่าย-' + (v.payee || '') + (v.no ? '-' + v.no : ''));
  return (
    <Modal open={open} onClose={onClose} wide title="ใบสำคัญจ่าย — ตรวจ/แก้ตัวเลขก่อนพิมพ์"
      footer={<><Button variant="ghost" onClick={onClose}>ปิด</Button><Button variant="dark" icon="download" onClick={doDownload}>ดาวน์โหลด (แก้ไขได้)</Button><Button icon="print" onClick={doPrint}>พิมพ์ใบสำคัญจ่าย</Button></>}>
      <div className="space-y-4">
        <div className="grid sm:grid-cols-3 gap-3">
          <Field label="เลขที่เอกสาร"><Input value={v.no} onChange={e => upd({ no: e.target.value })} className="num" /></Field>
          <Field label="วันที่จ่าย"><Input type="date" value={v.dateStr} onChange={e => upd({ dateStr: e.target.value })} className="[color-scheme:dark]" /></Field>
          <Field label="จ่ายให้แก่"><Input value={v.payee} onChange={e => upd({ payee: e.target.value })} /></Field>
        </div>

        <Field label="จ่ายโดย (ติ๊กเลือก แล้วจะแสดงบนใบสำคัญจ่าย)">
          <div className="flex items-center gap-2 flex-wrap">
            {[['cash', 'เงินสด'], ['transfer', 'โอนเข้าบัญชี'], ['cheque', 'เช็คธนาคาร']].map(([k, l]) => (
              <button key={k} onClick={() => upd({ payMethod: v.payMethod === k ? '' : k })}
                className={`tap px-3.5 py-1.5 rounded-lg text-sm flex items-center gap-1.5 ${v.payMethod === k ? 'bg-brand text-ink font-semibold' : 'bg-ink border border-line text-haze hover:text-chalk'}`}>
                <span>{v.payMethod === k ? '☑' : '☐'}</span>{l}
              </button>
            ))}
          </div>
        </Field>

        {/* รายการเดบิต (ค่าจ้าง/งาน) */}
        <div>
          <div className="flex items-center justify-between mb-2">
            <div className="text-[13px] font-semibold text-haze">รายการ (เดบิต DR)</div>
            <Button size="sm" variant="dark" icon="plus" onClick={addItem}>เพิ่มแถว</Button>
          </div>
          <div className="space-y-2">
            {v.items.map((it, i) => (
              <div key={i} className="flex items-center gap-2">
                <Input value={it.bill} onChange={e => setItem(i, 'bill', e.target.value)} placeholder="เลขที่บิล" className="w-28 num" />
                <Input value={it.label} onChange={e => setItem(i, 'label', e.target.value)} placeholder="รายการ / Description" className="flex-1" />
                <div className="w-32"><NumberInput value={Number(it.amount) || 0} onChange={val => setItem(i, 'amount', val)} step={100} /></div>
                <button onClick={() => delItem(i)} className="tap p-2 text-haze hover:text-bad rounded shrink-0"><Icon name="trash" size={16} /></button>
              </div>
            ))}
          </div>
        </div>

        {/* รายการเครดิต (หัก) */}
        <div>
          <div className="flex items-center justify-between mb-2">
            <div className="text-[13px] font-semibold text-haze">รายการหัก (เครดิต CR)</div>
            <Button size="sm" variant="dark" icon="plus" onClick={addDed}>เพิ่มรายการหัก</Button>
          </div>
          {v.deductions.length === 0 && <div className="text-xs text-haze px-1 pb-1">— ไม่มีรายการหัก —</div>}
          <div className="space-y-2">
            {v.deductions.map((d, i) => (
              <div key={i} className="flex items-center gap-2">
                <Input value={d.label} onChange={e => setDed(i, 'label', e.target.value)} placeholder="เช่น หัก ภาษี ณ ที่จ่าย / ประกันสังคม" className="flex-1" />
                <div className="w-32"><NumberInput value={Number(d.amount) || 0} onChange={val => setDed(i, 'amount', val)} step={100} /></div>
                <button onClick={() => delDed(i)} className="tap p-2 text-haze hover:text-bad rounded shrink-0"><Icon name="trash" size={16} /></button>
              </div>
            ))}
          </div>
        </div>

        {/* หัก ณ ที่จ่าย — คำนวณอัตโนมัติจากยอดเดบิต */}
        <div>
          <div className="text-[13px] font-semibold text-haze mb-2">หัก ภาษี ณ ที่จ่าย (คำนวณอัตโนมัติจากยอดเดบิต)</div>
          <div className="flex items-center gap-2 flex-wrap">
            {[0, 1, 2, 3, 5].map(r => (
              <button key={r} onClick={() => upd({ whtRate: r })} className={`tap px-3 py-1.5 rounded-lg text-sm ${whtRate === r ? 'bg-brand text-ink font-semibold' : 'bg-ink border border-line text-haze hover:text-chalk'}`}>{r}%</button>
            ))}
            <div className="w-20"><NumberInput value={whtRate} onChange={val => upd({ whtRate: val })} step={1} /></div>
            <span className="text-sm text-haze">→ หัก</span>
            <span className="num font-semibold text-bad">{baht(whtAmount)}</span>
          </div>
          <div className="text-xs text-haze mt-1.5">จ้างทำของ/รับเหมา = 3% · ค่าเช่า = 5% · ขนส่ง = 1% · ลูกจ้างรายวันมักเป็น 0%</div>
        </div>

        {/* สรุป */}
        <div className="bg-ink border border-line rounded-lg p-3 space-y-1.5 text-sm">
          <div className="flex justify-between"><span className="text-haze">รวมเดบิต (ค่าจ้าง)</span><span className="num">{baht(drTotal)}</span></div>
          {dedTotal > 0 && <div className="flex justify-between"><span className="text-haze">รวมรายการหัก</span><span className="num text-bad">−{baht(dedTotal)}</span></div>}
          <div className="flex justify-between"><span className="text-haze">หัก ภาษี ณ ที่จ่าย ({whtRate}%)</span><span className="num text-bad">−{baht(whtAmount)}</span></div>
          <div className="flex justify-between font-display font-bold border-t border-line pt-1.5"><span>จ่ายสุทธิ</span><span className="num text-brand">{baht(net)}</span></div>
        </div>
      </div>
    </Modal>
  );
}

/* =========================================================================
   เอกสาร: สรุปจ่ายค่าแรงประจำเดือน (ใบเสร็จ/สรุปยอดเดือน)
   ========================================================================= */
function MonthlySummaryDoc({ settings, year, month, rows }) {
  const totalGross = rows.reduce((t, r) => t + r.gross, 0);
  const totalSso = rows.reduce((t, r) => t + r.sso, 0);
  const totalWht = rows.reduce((t, r) => t + r.wht, 0);
  const totalNet = rows.reduce((t, r) => t + r.net, 0);
  return (
    <div className="bg-white text-[#1a1a1a] w-full" style={{ fontFamily: "'IBM Plex Sans Thai', sans-serif" }}>
      <div className="h-2 brand-strip"></div>
      <div className="px-8 pt-5 pb-3 flex items-start justify-between border-b-2 border-[#1a1a1a]">
        <div>
          <div className="font-display font-extrabold text-lg" style={{ color: '#92500f' }}>{settings.company}</div>
          <div className="text-[11px] text-[#555] mt-0.5 max-w-[380px] leading-snug">{settings.address}</div>
          <div className="text-[11px] text-[#555] num mt-0.5">เลขประจำตัวผู้เสียภาษี {settings.taxId}</div>
        </div>
        <div className="text-right">
          <div className="font-display font-bold text-xl">สรุปจ่ายค่าแรงประจำเดือน</div>
          <div className="text-[11px] text-[#777] tracking-wide">MONTHLY PAYROLL SUMMARY</div>
          <div className="text-[13px] mt-2 font-semibold">{TH_MONTHS[month - 1]} {year + 543}</div>
        </div>
      </div>

      <table className="w-full text-[12px] border-collapse">
        <thead>
          <tr className="bg-[#f5f5f5] text-[#444]">
            <th className="border border-[#ddd] py-1.5 px-2 text-left w-10">ที่</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-left">ชื่อ-สกุล</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-center w-14">วันงาน</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-right w-24">ค่าแรงรวม</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-right w-20">ปกส.</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-right w-20">ภาษี ณ ที่จ่าย</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-right w-24">จ่ายสุทธิ</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-center w-20">ลายเซ็นรับเงิน</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((r, i) => (
            <tr key={r.worker.id}>
              <td className="border border-[#eee] py-1.5 px-2 text-center num">{i + 1}</td>
              <td className="border border-[#eee] py-1.5 px-2">{r.worker.name}{r.worker.nickname ? ` (${r.worker.nickname})` : ''}</td>
              <td className="border border-[#eee] py-1.5 px-2 text-center num">{num(r.dayUnits, 1)}</td>
              <td className="border border-[#eee] py-1.5 px-2 text-right num">{baht(r.gross)}</td>
              <td className="border border-[#eee] py-1.5 px-2 text-right num">{r.sso ? baht(r.sso) : '—'}</td>
              <td className="border border-[#eee] py-1.5 px-2 text-right num">{r.wht ? baht(r.wht) : '—'}</td>
              <td className="border border-[#eee] py-1.5 px-2 text-right num font-semibold">{baht(r.net)}</td>
              <td className="border border-[#eee] py-1.5 px-2"></td>
            </tr>
          ))}
          <tr className="font-bold" style={{ background: '#fbf3e8' }}>
            <td className="border border-[#ddd] py-2 px-2 text-right" colSpan={3}>รวมทั้งสิ้น ({rows.length} คน)</td>
            <td className="border border-[#ddd] py-2 px-2 text-right num">{baht(totalGross)}</td>
            <td className="border border-[#ddd] py-2 px-2 text-right num">{baht(totalSso)}</td>
            <td className="border border-[#ddd] py-2 px-2 text-right num">{baht(totalWht)}</td>
            <td className="border border-[#ddd] py-2 px-2 text-right num" style={{ color: '#92500f' }}>{baht(totalNet)}</td>
            <td className="border border-[#ddd]"></td>
          </tr>
        </tbody>
      </table>

      <div className="px-8 pt-10 pb-6 grid grid-cols-3 gap-10 text-center text-[11px] text-[#555]">
        <div className="border-t border-[#999] pt-1.5">ผู้จัดทำ</div>
        <div className="border-t border-[#999] pt-1.5">ผู้ตรวจสอบ</div>
        <div className="border-t border-[#999] pt-1.5">ผู้อนุมัติ / ผู้จ่ายเงิน</div>
      </div>
    </div>
  );
}

/* =========================================================================
   เอกสาร: หนังสือรับรองการหักภาษี ณ ที่จ่าย (50 ทวิ) — รายปี
   ========================================================================= */
function Tawi50Doc({ settings, year, payeeName, payeeTaxId, idLabel = 'เลขประจำตัวประชาชน', incomeLabel = 'เงินเดือน / ค่าจ้าง 40(1)', income, tax, sso = 0, dateStr }) {
  return (
    <div className="bg-white text-[#1a1a1a] w-full" style={{ fontFamily: "'IBM Plex Sans Thai', sans-serif" }}>
      <div className="px-8 pt-5 pb-3 text-center border-b border-[#1a1a1a]">
        <div className="font-display font-bold text-lg">หนังสือรับรองการหักภาษี ณ ที่จ่าย</div>
        <div className="text-[11px] text-[#777]">ตามมาตรา 50 ทวิ แห่งประมวลรัษฎากร · ประจำปีภาษี {year + 543}</div>
      </div>

      <div className="px-8 py-3 text-[12.5px] border-b border-[#ddd]">
        <div className="font-semibold mb-1">ผู้มีหน้าที่หักภาษี ณ ที่จ่าย (ผู้จ่ายเงิน)</div>
        <div>{settings.company}</div>
        <div className="text-[#555]">{settings.address}</div>
        <div className="num text-[#555]">เลขประจำตัวผู้เสียภาษี {settings.taxId}</div>
      </div>
      <div className="px-8 py-3 text-[12.5px] border-b border-[#ddd]">
        <div className="font-semibold mb-1">ผู้ถูกหักภาษี ณ ที่จ่าย (ผู้รับเงิน)</div>
        <div>{payeeName}</div>
        <div className="num text-[#555]">{idLabel} {payeeTaxId || '— ยังไม่กรอก —'}</div>
        <div className="text-[#555]">ประเภทเงินได้: {incomeLabel}</div>
      </div>

      <table className="w-full text-[12.5px] border-collapse">
        <thead>
          <tr className="bg-[#f5f5f5] text-[#444]">
            <th className="border border-[#ddd] py-1.5 px-2 text-left">ประเภทเงินได้{dateStr ? ` (วันที่จ่าย ${thaiDate(dateStr)})` : ''}</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-right w-36">จำนวนเงินที่จ่าย</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-right w-36">ภาษีที่หักและนำส่ง</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td className="border border-[#eee] py-2 px-2">{incomeLabel}</td>
            <td className="border border-[#eee] py-2 px-2 text-right num">{baht(income)}</td>
            <td className="border border-[#eee] py-2 px-2 text-right num">{baht(tax)}</td>
          </tr>
          <tr className="font-bold" style={{ background: '#fbf3e8' }}>
            <td className="border border-[#ddd] py-2 px-2 text-right">รวมทั้งสิ้น</td>
            <td className="border border-[#ddd] py-2 px-2 text-right num">{baht(income)}</td>
            <td className="border border-[#ddd] py-2 px-2 text-right num">{baht(tax)}</td>
          </tr>
        </tbody>
      </table>

      {sso > 0 && (
        <div className="px-8 py-2 text-[12px] border-b border-[#ddd]">
          เงินที่นำส่งกองทุนประกันสังคมในปีนี้: <span className="num font-semibold">{baht(sso)}</span>
        </div>
      )}
      <div className="px-8 py-2 text-[12px]">
        จำนวนภาษีที่หัก (ตัวอักษร): <span className="font-semibold">({bahtText(tax)})</span>
      </div>

      <div className="px-8 pt-2 pb-3 text-[11.5px] text-[#555]">
        ผู้จ่ายเงินขอรับรองว่าข้อความและตัวเลขดังกล่าวข้างต้นถูกต้องตรงกับความจริงทุกประการ
      </div>
      <div className="px-8 pb-6 flex justify-end">
        <div className="text-center text-[11px] text-[#555] w-64">
          <div className="border-t border-[#999] pt-1.5">ลงชื่อผู้จ่ายเงิน / ผู้มีหน้าที่หักภาษี</div>
        </div>
      </div>
    </div>
  );
}

/* =========================================================================
   เอกสาร: สรุปเงินได้-ภาษี ลูกจ้างรายปี (รายคน)
   ========================================================================= */
function PND1kDoc({ settings, year, rows }) {
  const totalIncome = rows.reduce((t, r) => t + r.income, 0);
  return (
    <div className="bg-white text-[#1a1a1a] w-full" style={{ fontFamily: "'IBM Plex Sans Thai', sans-serif" }}>
      <div className="px-8 pt-5 pb-3 text-center border-b border-[#1a1a1a]">
        <div className="font-display font-bold text-lg">สรุปเงินได้ลูกจ้างรายปี</div>
        <div className="text-[11px] text-[#777]">สรุปการจ่ายค่าจ้างลูกจ้างรายวัน · ประจำปี {year + 543}</div>
        <div className="text-[12px] mt-1">{settings.company} · เลขประจำตัวผู้เสียภาษี <span className="num">{settings.taxId}</span></div>
      </div>
      <table className="w-full text-[12px] border-collapse">
        <thead>
          <tr className="bg-[#f5f5f5] text-[#444]">
            <th className="border border-[#ddd] py-1.5 px-2 text-left w-10">ที่</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-left">ชื่อ-สกุล</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-right w-40">เงินได้ทั้งปี</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((r, i) => (
            <tr key={r.worker.id}>
              <td className="border border-[#eee] py-1.5 px-2 text-center num">{i + 1}</td>
              <td className="border border-[#eee] py-1.5 px-2">{r.worker.name}{r.worker.nickname ? ` (${r.worker.nickname})` : ''}</td>
              <td className="border border-[#eee] py-1.5 px-2 text-right num">{baht(r.income)}</td>
            </tr>
          ))}
          <tr className="font-bold" style={{ background: '#fbf3e8' }}>
            <td className="border border-[#ddd] py-2 px-2 text-right" colSpan={2}>รวมทั้งสิ้น ({rows.length} ราย)</td>
            <td className="border border-[#ddd] py-2 px-2 text-right num">{baht(totalIncome)}</td>
          </tr>
        </tbody>
      </table>
      <div className="px-8 pt-10 pb-6 flex justify-end">
        <div className="text-center text-[11px] text-[#555] w-64"><div className="border-t border-[#999] pt-1.5">ลงชื่อผู้จ่ายเงิน</div></div>
      </div>
    </div>
  );
}

/* =========================================================================
   ภ.ง.ด.3 / 53 — การจ่ายเงินให้ผู้รับเหมา/จ้างทำของ (หัก ณ ที่จ่าย)
   เก็บในตาราง adjustments เดิม: kind='wht', period='wht-YYYY-MM',
   amount=ฐานเงินจ่าย, label=JSON รายละเอียดผู้รับเงิน — ไม่กระทบข้อมูลเดิม
   ========================================================================= */
const WHT_TYPES = [
  { key: 'service', label: 'จ้างทำของ / รับเหมา / ค่าบริการ', rate: 3, sec: '40(7)(8)' },
  { key: 'professional', label: 'ค่าวิชาชีพอิสระ', rate: 3, sec: '40(6)' },
  { key: 'rent', label: 'ค่าเช่าทรัพย์สิน', rate: 5, sec: '40(5)' },
  { key: 'transport', label: 'ค่าขนส่ง', rate: 1, sec: '40(8)' },
  { key: 'ad', label: 'ค่าโฆษณา', rate: 2, sec: '40(8)' },
];
const whtTypeBy = k => WHT_TYPES.find(t => t.key === k) || WHT_TYPES[0];

function parseWht(a) {
  let m = {};
  try { m = JSON.parse(a.label || '{}'); } catch (_) { m = {}; }
  const base = Number(a.amount) || 0;
  const rate = Number(m.rate) || 0;
  return {
    id: a.id, base, rate, wht: Math.round(base * rate) / 100,
    name: m.name || '', taxId: m.taxId || '', payeeType: m.payeeType || 'person',
    incomeType: m.incomeType || 'service', incomeLabel: m.incomeLabel || whtTypeBy(m.incomeType).label,
    date: m.date || '', addr: m.addr || '', note: m.note || '',
  };
}
const whtList = (db, year) => db.adjustments.filter(a => a.kind === 'wht')
  .map(parseWht).filter(r => !year || r.date.startsWith(String(year)))
  .sort((a, b) => a.date < b.date ? 1 : -1);

/* เอกสาร ภ.ง.ด.3 (บุคคล) / ภ.ง.ด.53 (นิติบุคคล) */
function PndWhtDoc({ settings, year, form, rows }) {
  const totalBase = rows.reduce((t, r) => t + r.base, 0);
  const totalWht = rows.reduce((t, r) => t + r.wht, 0);
  return (
    <div className="bg-white text-[#1a1a1a] w-full" style={{ fontFamily: "'IBM Plex Sans Thai', sans-serif" }}>
      <div className="px-8 pt-5 pb-3 text-center border-b border-[#1a1a1a]">
        <div className="font-display font-bold text-lg">ใบแนบ ภ.ง.ด.{form}</div>
        <div className="text-[11px] text-[#777]">รายการภาษีเงินได้หัก ณ ที่จ่าย ({form === '53' ? 'จ่ายให้นิติบุคคล' : 'จ่ายให้บุคคลธรรมดา'}) · ปีภาษี {year + 543}</div>
        <div className="text-[12px] mt-1">{settings.company} · เลขประจำตัวผู้เสียภาษี <span className="num">{settings.taxId}</span></div>
      </div>
      <table className="w-full text-[12px] border-collapse">
        <thead>
          <tr className="bg-[#f5f5f5] text-[#444]">
            <th className="border border-[#ddd] py-1.5 px-2 text-left w-8">ที่</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-left">เลขผู้เสียภาษี/บัตร ปชช.</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-left">ชื่อผู้รับเงิน</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-left">วันที่จ่าย</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-left">ประเภทเงินได้</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-right w-16">อัตรา</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-right w-28">จำนวนเงิน</th>
            <th className="border border-[#ddd] py-1.5 px-2 text-right w-24">ภาษีหัก</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((r, i) => (
            <tr key={r.id}>
              <td className="border border-[#eee] py-1.5 px-2 text-center num">{i + 1}</td>
              <td className="border border-[#eee] py-1.5 px-2 num">{r.taxId || '—'}</td>
              <td className="border border-[#eee] py-1.5 px-2">{r.name}</td>
              <td className="border border-[#eee] py-1.5 px-2 num">{r.date ? thaiDate(r.date) : '—'}</td>
              <td className="border border-[#eee] py-1.5 px-2">{r.incomeLabel}</td>
              <td className="border border-[#eee] py-1.5 px-2 text-right num">{r.rate}%</td>
              <td className="border border-[#eee] py-1.5 px-2 text-right num">{baht(r.base)}</td>
              <td className="border border-[#eee] py-1.5 px-2 text-right num">{baht(r.wht)}</td>
            </tr>
          ))}
          <tr className="font-bold" style={{ background: '#fbf3e8' }}>
            <td className="border border-[#ddd] py-2 px-2 text-right" colSpan={6}>รวมทั้งสิ้น ({rows.length} ราย)</td>
            <td className="border border-[#ddd] py-2 px-2 text-right num">{baht(totalBase)}</td>
            <td className="border border-[#ddd] py-2 px-2 text-right num">{baht(totalWht)}</td>
          </tr>
        </tbody>
      </table>
      <div className="px-8 py-4 text-[11.5px] text-[#555]">
        * นำส่ง ภ.ง.ด.{form} ภายในวันที่ 7 ของเดือนถัดจากเดือนที่จ่ายเงิน · จ้างทำของ/รับเหมา/บริการ หัก 3% · ค่าเช่า 5% · ค่าขนส่ง 1%
      </div>
      <div className="px-8 pb-6 flex justify-end">
        <div className="text-center text-[11px] text-[#555] w-64"><div className="border-t border-[#999] pt-1.5">ลงชื่อผู้มีหน้าที่หักภาษี ณ ที่จ่าย</div></div>
      </div>
    </div>
  );
}

/* Modal: เพิ่ม/แก้ไข รายการจ่ายผู้รับเหมา (หัก ณ ที่จ่าย) */
function WhtModal({ open, onClose, initial }) {
  const { db, addAdjustment, removeAdjustment } = useDB();
  const blank = { id: null, date: ymd(TODAY), name: '', taxId: '', payeeType: 'person', incomeType: 'service', rate: 3, base: 0, addr: '', note: '' };
  const [r, setR] = txS(blank);
  React.useEffect(() => { if (open) setR(initial ? { ...blank, ...initial } : blank); }, [open, initial]);
  // รายชื่อผู้รับเหมาที่เคยกรอก (ไว้เลือกอัตโนมัติ ไม่ต้องพิมพ์ซ้ำ)
  const known = React.useMemo(() => {
    const map = {};
    db.adjustments.filter(a => a.kind === 'wht').forEach(a => { const p = parseWht(a); if (p.name && !map[p.name]) map[p.name] = { name: p.name, taxId: p.taxId, payeeType: p.payeeType, incomeType: p.incomeType, rate: p.rate }; });
    return Object.values(map);
  }, [db.adjustments]);
  if (!open) return null;
  const f = (k, v) => setR(p => ({ ...p, [k]: v }));
  const onType = (k) => { const t = whtTypeBy(k); setR(p => ({ ...p, incomeType: k, rate: t.rate })); };
  // พิมพ์/เลือกชื่อ → ถ้าตรงกับที่เคยกรอก เติมเลขภาษี/ประเภท/อัตราให้อัตโนมัติ
  const onName = (v) => { const hit = known.find(k => k.name === v); setR(p => hit ? { ...p, name: v, taxId: hit.taxId || p.taxId, payeeType: hit.payeeType || p.payeeType, incomeType: hit.incomeType || p.incomeType, rate: hit.rate || p.rate } : { ...p, name: v }); };
  const wht = Math.round((Number(r.base) || 0) * (Number(r.rate) || 0)) / 100;
  const save = () => {
    if (!r.name.trim() || !(Number(r.base) > 0)) { alert('กรุณากรอกชื่อผู้รับเงินและจำนวนเงิน'); return; }
    const t = whtTypeBy(r.incomeType);
    const label = JSON.stringify({ name: r.name.trim(), taxId: r.taxId.trim(), payeeType: r.payeeType, incomeType: r.incomeType, incomeLabel: t.label, rate: Number(r.rate) || 0, date: r.date, addr: r.addr.trim(), note: r.note.trim() });
    if (r.id) removeAdjustment(r.id);
    addAdjustment({ workerId: 'ctr', period: 'wht-' + (r.date || '').slice(0, 7), kind: 'wht', label, amount: Number(r.base) || 0 });
    onClose();
  };
  return (
    <Modal open={open} onClose={onClose} title={r.id ? 'แก้ไขรายการจ่าย (หัก ณ ที่จ่าย)' : 'เพิ่มรายการจ่ายผู้รับเหมา'}
      footer={<><Button variant="ghost" onClick={onClose}>ยกเลิก</Button><Button icon="check" onClick={save}>บันทึก</Button></>}>
      <div className="space-y-4">
        <div className="grid sm:grid-cols-2 gap-3">
          <Field label="วันที่จ่าย" req><Input type="date" value={r.date} onChange={e => f('date', e.target.value)} className="[color-scheme:dark]" /></Field>
          <Field label="ประเภทผู้รับเงิน" req>
            <Select value={r.payeeType} onChange={e => f('payeeType', e.target.value)}>
              <option value="person">บุคคลธรรมดา → ภ.ง.ด.3</option>
              <option value="company">นิติบุคคล (บริษัท/หจก.) → ภ.ง.ด.53</option>
            </Select>
          </Field>
        </div>
        <Field label="ชื่อผู้รับเงิน" req hint={known.length ? 'เลือกจากรายชื่อที่เคยกรอก แล้วระบบเติมเลขภาษี/ประเภทให้เอง' : undefined}>
          <Input value={r.name} onChange={e => onName(e.target.value)} list="wht-payees" autoComplete="off" placeholder="เช่น นายสมศักดิ์ รับเหมา / หจก.ช่างดี" />
          <datalist id="wht-payees">{known.map(k => <option key={k.name} value={k.name} />)}</datalist>
        </Field>
        <Field label={r.payeeType === 'company' ? 'เลขประจำตัวผู้เสียภาษี (13 หลัก)' : 'เลขบัตรประชาชน (13 หลัก)'}><Input value={r.taxId} onChange={e => f('taxId', e.target.value.replace(/\D/g, '').slice(0, 13))} className="num" placeholder="x-xxxx-xxxxx-xx-x" /></Field>
        <div className="grid sm:grid-cols-2 gap-3">
          <Field label="ประเภทเงินได้" req>
            <Select value={r.incomeType} onChange={e => onType(e.target.value)}>
              {WHT_TYPES.map(t => <option key={t.key} value={t.key}>{t.label} ({t.rate}%)</option>)}
            </Select>
          </Field>
          <Field label="อัตราหัก %" hint="ปรับได้ตามจริง"><NumberInput value={Number(r.rate) || 0} onChange={v => f('rate', v)} step={1} /></Field>
        </div>
        <Field label="จำนวนเงินที่จ่าย (ฐานก่อนหัก)" req><NumberInput value={Number(r.base) || 0} onChange={v => f('base', v)} step={100} /></Field>
        <Field label="หมายเหตุ"><Input value={r.note} onChange={e => f('note', e.target.value)} placeholder="เช่น งานเหมาเทพื้น บ.นาเมือง" /></Field>
        <div className="bg-ink border border-line rounded-lg p-3 text-sm flex items-center justify-between">
          <span className="text-haze">ภาษีหัก ณ ที่จ่าย ({r.rate}%)</span>
          <span className="num font-semibold text-bad">{baht(wht)}</span>
        </div>
        <div className="text-sm flex items-center justify-between px-1">
          <span className="text-haze">จ่ายจริง (สุทธิ)</span>
          <span className="num font-semibold text-brand">{baht((Number(r.base) || 0) - wht)}</span>
        </div>
      </div>
    </Modal>
  );
}

/* =========================================================================
   Modal: แก้ไข (แต่ง) ค่าแรงรายเดือน
   ========================================================================= */
function EditMonthModal({ open, onClose, db, worker, year, month }) {
  const { addAdjustment, removeAdjustment } = useDB();
  const calc = open && worker ? wageForMonth(db, worker.id, year, month) : { gross: 0 };
  const cur = open && worker ? monthOverride(db, worker.id, year, month) : null;
  const [val, setVal] = txS('');
  const [note, setNote] = txS('');
  React.useEffect(() => {
    if (open) { setVal(cur ? String(cur.amount) : String(Math.round(calc.gross))); setNote(cur?.label || ''); }
  }, [open, worker, year, month]);
  if (!open || !worker) return null;

  const save = () => {
    if (cur) removeAdjustment(cur.id);
    addAdjustment({ workerId: worker.id, period: TMKEY(year, month), kind: 'taxadj', label: note.trim() || 'แก้ไขด้วยมือ', amount: Number(val) || 0 });
    onClose();
  };
  const reset = () => { if (cur) removeAdjustment(cur.id); onClose(); };

  return (
    <Modal open={open} onClose={onClose} title={`แก้ค่าแรง ${worker.name} · ${TH_MONTHS[month - 1]} ${year + 543}`}
      footer={<>
        {cur && <Button variant="ghost" onClick={reset} className="!text-bad mr-auto">ล้างเป็นค่าอัตโนมัติ</Button>}
        <Button variant="ghost" onClick={onClose}>ยกเลิก</Button>
        <Button icon="check" onClick={save}>บันทึก</Button>
      </>}>
      <div className="space-y-4">
        <div className="bg-ink border border-line rounded-lg p-3 text-sm flex items-center justify-between">
          <span className="text-haze">ยอดที่ระบบคำนวณจากการลงเวลา</span>
          <span className="num font-semibold">{baht(calc.gross)}</span>
        </div>
        <Field label="ค่าแรงที่ใช้จริง (แก้ได้)" hint="ตัวเลขนี้จะใช้แทนยอดคำนวณ ในการสรุปภาษี/ใบสำคัญจ่าย — ไม่กระทบข้อมูลลงเวลาเดิม">
          <NumberInput value={Number(val) || 0} onChange={v => setVal(String(v))} step={100} />
        </Field>
        <Field label="หมายเหตุ"><Input value={note} onChange={e => setNote(e.target.value)} placeholder="เช่น ปรับยอดตามที่ตกลง / รวมเบี้ยขยัน" /></Field>
      </div>
    </Modal>
  );
}

/* =========================================================================
   Modal: สรุปรายเดือน + ออกใบสำคัญจ่าย
   ========================================================================= */
function MonthlySummaryModal({ open, onClose, db, year, month, workers }) {
  if (!open) return null;
  const rows = workers.map(w => {
    const e = effMonth(db, w.id, year, month);
    const sso = ssoMonth(e.gross, db.settings);
    // ภาษีหัก ณ ที่จ่ายรายเดือน = ภาษีทั้งปีหารเฉลี่ย (ประมาณการ) — ลูกจ้างรายวันมักเป็น 0
    const yw = yearWage(db, w.id, year);
    const ssoYear = yw.months.reduce((t, mm) => t + ssoMonth(mm.gross, db.settings), 0);
    const taxYear = withholdingYear(yw.total, ssoYear).tax;
    const monthsWithPay = yw.months.filter(mm => mm.gross > 0).length || 1;
    const wht = e.gross > 0 ? Math.round(taxYear / monthsWithPay) : 0;
    return { worker: w, ...e, sso, wht, net: e.gross - sso - wht };
  }).filter(r => r.gross > 0 || r.overridden);

  const doPrintSummary = () => printElement(<MonthlySummaryDoc settings={docSettings(db)} year={year} month={month} rows={rows} />, 'A4');
  const doPrintVoucher = (r) => printElement(
    <PaymentVoucherDoc settings={docSettings(db)} no={`PV-${year}${String(month).padStart(2, '0')}-${r.worker.code}`}
      dateStr={ymd(new Date(year, month, 0))} payee={`${r.worker.name}${r.worker.nickname ? ' (' + r.worker.nickname + ')' : ''}`}
      items={[{ label: `ค่าแรงประจำเดือน ${TH_MONTHS[month - 1]} ${year + 543} (${num(r.dayUnits, 1)} วัน)`, amount: r.base }, ...(r.ot > 0 ? [{ label: 'ค่าล่วงเวลา (OT)', amount: r.ot }] : [])]}
      deductions={[...(r.wht > 0 ? [{ label: 'หัก ภาษี ณ ที่จ่าย', amount: r.wht }] : []), ...(r.sso > 0 ? [{ label: 'หัก เงินประกันสังคม', amount: r.sso }] : [])]} net={r.net} />, 'A5');

  const totalNet = rows.reduce((t, r) => t + r.net, 0);

  return (
    <Modal open={open} onClose={onClose} wide title={`สรุปจ่ายค่าแรง · ${TH_MONTHS[month - 1]} ${year + 543}`}
      footer={<>
        <Button variant="ghost" onClick={onClose}>ปิด</Button>
        <Button icon="print" onClick={doPrintSummary}>พิมพ์สรุปยอดเดือน (A4)</Button>
      </>}>
      {rows.length === 0 ? <Empty title="ยังไม่มีค่าแรงในเดือนนี้" sub="ลงเวลาให้คนงานก่อน หรือเลือกเดือนอื่น" /> : (
        <div className="overflow-x-auto -mx-1">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-haze text-xs border-b border-line">
                <th className="text-left font-medium py-2 px-2">ชื่อ</th>
                <th className="text-right font-medium py-2 px-2">วันงาน</th>
                <th className="text-right font-medium py-2 px-2">ค่าแรงรวม</th>
                <th className="text-right font-medium py-2 px-2">ปกส.</th>
                <th className="text-right font-medium py-2 px-2">ภาษี</th>
                <th className="text-right font-medium py-2 px-2">สุทธิ</th>
                <th className="text-right font-medium py-2 px-2">ใบสำคัญจ่าย</th>
              </tr>
            </thead>
            <tbody>
              {rows.map(r => (
                <tr key={r.worker.id} className="border-b border-line/60">
                  <td className="py-2 px-2">{r.worker.name}{r.overridden && <span className="ml-1 text-[10px] text-hazard">●แก้ไข</span>}</td>
                  <td className="py-2 px-2 text-right num">{num(r.dayUnits, 1)}</td>
                  <td className="py-2 px-2 text-right num">{baht(r.gross)}</td>
                  <td className="py-2 px-2 text-right num text-haze">{r.sso ? baht(r.sso) : '—'}</td>
                  <td className="py-2 px-2 text-right num text-haze">{r.wht ? baht(r.wht) : '—'}</td>
                  <td className="py-2 px-2 text-right num font-semibold text-brand">{baht(r.net)}</td>
                  <td className="py-2 px-2 text-right"><Button size="sm" variant="dark" icon="slip" onClick={() => doPrintVoucher(r)}>PV</Button></td>
                </tr>
              ))}
              <tr className="font-display font-bold">
                <td className="py-2 px-2" colSpan={5}>รวมจ่ายสุทธิ ({rows.length} คน)</td>
                <td className="py-2 px-2 text-right num text-brand">{baht(totalNet)}</td>
                <td></td>
              </tr>
            </tbody>
          </table>
        </div>
      )}
    </Modal>
  );
}

/* =========================================================================
   หน้าหลัก: ภาษีค่าแรง
   ========================================================================= */
function WageTax() {
  const { db } = useDB();
  const thisYear = TODAY.getFullYear();
  const [year, setYear] = txS(thisYear);
  const [tab, setTab] = txS('grid'); // grid | tax
  const [edit, setEdit] = txS(null); // {worker, month}
  const [sumMonth, setSumMonth] = txS(null); // month number → open summary modal
  const [whtEdit, setWhtEdit] = txS(null); // null=ปิด, {}=เพิ่ม, {record}=แก้
  const [voucher, setVoucher] = txS(null); // ใบสำคัญจ่าย (แก้ตัวเลขเอง)

  const workers = db.workers.filter(w => w.active);
  const yearOpts = [thisYear, thisYear - 1, thisYear - 2];

  // ตารางรายเดือน
  const grid = txM(() => workers.map(w => ({ worker: w, ...yearWage(db, w.id, year) })), [db, workers, year]);
  const monthTotals = Array.from({ length: 12 }, (_, m) => grid.reduce((t, g) => t + g.months[m].gross, 0));
  const grandTotal = grid.reduce((t, g) => t + g.total, 0);

  // สรุปภาษีรายปีลูกจ้าง
  const taxRows = txM(() => workers.map(w => {
    const yw = yearWage(db, w.id, year);
    const ssoYear = yw.months.reduce((t, mm) => t + ssoMonth(mm.gross, db.settings), 0);
    const wy = withholdingYear(yw.total, ssoYear);
    return { worker: w, income: yw.total, sso: ssoYear, ...wy };
  }).filter(r => r.income > 0), [db, workers, year]);

  // ภ.ง.ด.3/53 — รายการจ่ายผู้รับเหมา
  const whtRows = txM(() => whtList(db, year), [db, year]);
  const wht3 = whtRows.filter(r => r.payeeType === 'person');
  const wht53 = whtRows.filter(r => r.payeeType === 'company');
  const { removeAdjustment } = useDB();

  return (
    <div data-screen>
      <PageHead title="ภาษีค่าแรง" sub="สรุปค่าแรงสะสมรายเดือน/รายปีต่อคน · กรอกตัวเลขเอง · ออกใบสำคัญจ่าย"
        actions={<>
          <Select value={year} onChange={e => setYear(Number(e.target.value))} className="!py-2 min-w-[120px]">
            {yearOpts.map(y => <option key={y} value={y}>ปี {y + 543}</option>)}
          </Select>
          <Button icon="print" onClick={() => printElement(<PND1kDoc settings={docSettings(db)} year={year} rows={taxRows} />, 'A4')} disabled={taxRows.length === 0}>พิมพ์สรุปรายปี</Button>
        </>} />

      {/* tabs */}
      <div className="flex gap-2 mb-5">
        {[['grid', 'ตารางค่าแรงรายเดือน'], ['tax', 'ลูกจ้างรายวัน'], ['wht3', 'จ้างเหมา (ภ.ง.ด.3/53)']].map(([k, l]) => (
          <button key={k} onClick={() => setTab(k)}
            className={`tap px-4 py-2 rounded-lg text-sm font-medium ${tab === k ? 'bg-brand text-ink font-semibold' : 'bg-panel border border-line text-haze hover:text-chalk'}`}>{l}</button>
        ))}
      </div>

      {tab === 'grid' && (
        <>
          <Card className="!p-0 overflow-hidden mb-4">
            <div className="overflow-x-auto">
              <table className="w-full text-[13px] border-collapse">
                <thead>
                  <tr className="bg-raised text-haze text-xs">
                    <th className="sticky left-0 bg-raised text-left font-medium py-2.5 px-3 min-w-[140px] z-10">คนงาน</th>
                    {TH_MONTHS_SHORT.map((mn, i) => (
                      <th key={i} className="text-right font-medium py-2.5 px-2 min-w-[78px]">
                        <button onClick={() => setSumMonth(i + 1)} className="tap hover:text-brand" title="กดเพื่อสรุป/ออกใบสำคัญจ่ายเดือนนี้">{mn}</button>
                      </th>
                    ))}
                    <th className="text-right font-semibold py-2.5 px-3 min-w-[96px] text-chalk">รวมทั้งปี</th>
                  </tr>
                </thead>
                <tbody>
                  {grid.map(g => (
                    <tr key={g.worker.id} className="border-t border-line hover:bg-white/[0.02]">
                      <td className="sticky left-0 bg-panel py-2 px-3 font-medium z-10">
                        <div className="truncate max-w-[140px]">{g.worker.name}</div>
                        <div className="text-[10px] text-haze">{g.worker.nickname} · {TYPE[g.worker.type].short}</div>
                      </td>
                      {g.months.map((e, mi) => (
                        <td key={mi} className="py-1 px-1 text-right">
                          <button onClick={() => setEdit({ worker: g.worker, month: mi + 1 })}
                            className={`tap w-full text-right px-1.5 py-1 rounded num text-[12px] hover:bg-brand/10 ${e.overridden ? 'text-hazard font-semibold' : e.gross > 0 ? 'text-chalk' : 'text-haze/40'}`}
                            title={e.overridden ? 'แก้ไขด้วยมือ — กดเพื่อแก้' : 'กดเพื่อแก้ตัวเลข'}>
                            {e.gross > 0 ? num(e.gross, 0) : '–'}{e.overridden && <span className="text-[8px] align-top">●</span>}
                          </button>
                        </td>
                      ))}
                      <td className="py-2 px-3 text-right num font-semibold text-brand">{baht(g.total, 0)}</td>
                    </tr>
                  ))}
                  <tr className="border-t-2 border-line bg-raised/50 font-semibold">
                    <td className="sticky left-0 bg-raised py-2.5 px-3 z-10">รวมทุกคน</td>
                    {monthTotals.map((t, i) => (
                      <td key={i} className="py-2.5 px-2 text-right num text-[12px]">{t > 0 ? num(t, 0) : '–'}</td>
                    ))}
                    <td className="py-2.5 px-3 text-right num text-brand">{baht(grandTotal, 0)}</td>
                  </tr>
                </tbody>
              </table>
            </div>
          </Card>
          <div className="flex flex-wrap items-center gap-3 text-xs text-haze">
            <span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-full bg-hazard"></span>● = แก้ไขด้วยมือ (override)</span>
            <span>· กดที่ตัวเลขเพื่อแก้ · กดชื่อเดือนบนหัวตารางเพื่อสรุป + ออกใบสำคัญจ่าย</span>
          </div>
        </>
      )}

      {tab === 'tax' && (
        <>
          <Card className="!p-0 overflow-hidden">
            <div className="overflow-x-auto">
              <table className="w-full text-[13px] border-collapse">
                <thead>
                  <tr className="bg-raised text-haze text-xs">
                    <th className="text-left font-medium py-2.5 px-3">คนงาน</th>
                    <th className="text-right font-medium py-2.5 px-3">เงินได้ทั้งปี (ที่กรอก)</th>
                    <th className="text-right font-medium py-2.5 px-3">ใบสำคัญจ่าย</th>
                  </tr>
                </thead>
                <tbody>
                  {grid.length === 0 && <tr><td colSpan={3} className="text-center text-haze py-8">ยังไม่มีคนงาน</td></tr>}
                  {grid.map(g => (
                    <tr key={g.worker.id} className="border-t border-line">
                      <td className="py-2 px-3 font-medium">{g.worker.nickname || g.worker.name}<div className="text-[10px] text-haze">{g.worker.code}{g.worker.name && g.worker.name !== g.worker.nickname ? ` · ${g.worker.name}` : ''}</div></td>
                      <td className="py-2 px-3 text-right num font-semibold">{g.total > 0 ? baht(g.total) : <span className="text-haze/50">—</span>}</td>
                      <td className="py-2 px-3 text-right">
                        <Button size="sm" variant="dark" icon="slip" onClick={() => setVoucher({
                          no: `PV-${year + 543}-${g.worker.code}`,
                          dateStr: ymd(TODAY),
                          payee: `${g.worker.name || g.worker.nickname}${g.worker.nickname && g.worker.name && g.worker.name !== g.worker.nickname ? ' (' + g.worker.nickname + ')' : ''}`,
                          items: [{ bill: '', label: `ค่าแรงประจำปี ${year + 543}`, amount: g.total }],
                          deductions: [],
                        })}>ใบสำคัญจ่าย</Button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            <div className="p-4 text-xs text-haze border-t border-line bg-ink/40">
              ตัวเลขเงินได้มาจากที่กรอกในแท็บ "ตารางค่าแรงรายเดือน" (แก้ได้ทุกช่อง) · กด "ใบสำคัญจ่าย" เพื่อสร้างเอกสาร แล้วแก้ตัวเลขเองได้ก่อนพิมพ์ · ภาษีหัก ณ ที่จ่ายเป็นหน้าที่ของระบบสรรพากร — ระบบนี้ไม่คำนวณให้
            </div>
          </Card>
        </>
      )}

      {tab === 'wht3' && (
        <>
          <div className="flex flex-wrap items-center gap-2 mb-4">
            <Button icon="plus" onClick={() => setWhtEdit({})}>เพิ่มรายการจ่ายผู้รับเหมา</Button>
            <div className="flex-1"></div>
            <Button variant="dark" icon="print" onClick={() => printElement(<PndWhtDoc settings={docSettings(db)} year={year} form="3" rows={wht3} />, 'A4')} disabled={wht3.length === 0}>พิมพ์ ภ.ง.ด.3</Button>
            <Button variant="dark" icon="print" onClick={() => printElement(<PndWhtDoc settings={docSettings(db)} year={year} form="53" rows={wht53} />, 'A4')} disabled={wht53.length === 0}>พิมพ์ ภ.ง.ด.53</Button>
          </div>
          <Card className="!p-0 overflow-hidden">
            <div className="overflow-x-auto">
              <table className="w-full text-[13px] border-collapse">
                <thead>
                  <tr className="bg-raised text-haze text-xs">
                    <th className="text-left font-medium py-2.5 px-3">วันที่จ่าย</th>
                    <th className="text-left font-medium py-2.5 px-3">ผู้รับเงิน</th>
                    <th className="text-center font-medium py-2.5 px-3">แบบ</th>
                    <th className="text-left font-medium py-2.5 px-3">ประเภทเงินได้</th>
                    <th className="text-right font-medium py-2.5 px-3">จำนวนเงิน</th>
                    <th className="text-right font-medium py-2.5 px-3">อัตรา</th>
                    <th className="text-right font-medium py-2.5 px-3">ภาษีหัก</th>
                    <th className="text-right font-medium py-2.5 px-3">จัดการ</th>
                  </tr>
                </thead>
                <tbody>
                  {whtRows.length === 0 && <tr><td colSpan={8} className="text-center text-haze py-10">ยังไม่มีรายการจ้างเหมาในปีนี้ — กด "เพิ่มรายการจ่ายผู้รับเหมา"</td></tr>}
                  {whtRows.map(r => (
                    <tr key={r.id} className="border-t border-line">
                      <td className="py-2 px-3 num text-haze">{r.date ? thaiDate(r.date) : '—'}</td>
                      <td className="py-2 px-3">{r.name}<div className="num text-[10px] text-haze">{r.taxId || '— ไม่มีเลขผู้เสียภาษี —'}</div></td>
                      <td className="py-2 px-3 text-center"><Badge tone={r.payeeType === 'company' ? 'hazard' : 'brand'}>{r.payeeType === 'company' ? 'ภ.ง.ด.53' : 'ภ.ง.ด.3'}</Badge></td>
                      <td className="py-2 px-3 text-haze">{r.incomeLabel}{r.note ? <div className="text-[10px] text-haze/70">{r.note}</div> : null}</td>
                      <td className="py-2 px-3 text-right num">{baht(r.base)}</td>
                      <td className="py-2 px-3 text-right num text-haze">{r.rate}%</td>
                      <td className="py-2 px-3 text-right num font-semibold text-bad">{baht(r.wht)}</td>
                      <td className="py-2 px-3 text-right whitespace-nowrap">
                        <button onClick={() => printElement(<Tawi50Doc settings={docSettings(db)} year={year} payeeName={r.name} payeeTaxId={r.taxId} idLabel={r.payeeType === 'company' ? 'เลขประจำตัวผู้เสียภาษี' : 'เลขบัตรประชาชน'} incomeLabel={r.incomeLabel} income={r.base} tax={r.wht} dateStr={r.date} />, 'A5')} className="tap p-1.5 text-haze hover:text-brand rounded" title="พิมพ์ 50 ทวิ"><Icon name="slip" size={16} /></button>
                        <button onClick={() => setWhtEdit(r)} className="tap p-1.5 text-haze hover:text-brand rounded" title="แก้ไข"><Icon name="edit" size={16} /></button>
                        <button onClick={() => { if (confirm(`ลบรายการจ่าย ${r.name} (${baht(r.base)})?`)) removeAdjustment(r.id); }} className="tap p-1.5 text-haze hover:text-bad rounded" title="ลบ"><Icon name="trash" size={16} /></button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            {whtRows.length > 0 && (
              <div className="flex flex-wrap gap-x-8 gap-y-1 p-4 border-t border-line bg-ink/40 text-sm">
                <span className="text-haze">ภ.ง.ด.3 (บุคคล): <span className="num text-chalk">{wht3.length} ราย · ภาษี {baht(wht3.reduce((t, r) => t + r.wht, 0))}</span></span>
                <span className="text-haze">ภ.ง.ด.53 (นิติบุคคล): <span className="num text-chalk">{wht53.length} ราย · ภาษี {baht(wht53.reduce((t, r) => t + r.wht, 0))}</span></span>
              </div>
            )}
          </Card>
          <div className="text-xs text-haze mt-3 flex items-start gap-2"><Icon name="warn" size={14} className="text-hazard mt-0.5 shrink-0" />จ้างเหมา/จ้างทำของบุคคลธรรมดา หัก 3% → ภ.ง.ด.3 · จ่ายให้บริษัท/หจก. → ภ.ง.ด.53 · นำส่งภายในวันที่ 7 ของเดือนถัดไป</div>
        </>
      )}

      <EditMonthModal open={!!edit} onClose={() => setEdit(null)} db={db} worker={edit?.worker} year={year} month={edit?.month} />
      <MonthlySummaryModal open={!!sumMonth} onClose={() => setSumMonth(null)} db={db} year={year} month={sumMonth} workers={workers} />
      <WhtModal open={!!whtEdit} onClose={() => setWhtEdit(null)} initial={whtEdit && whtEdit.id ? whtEdit : null} />
      <VoucherModal open={!!voucher} onClose={() => setVoucher(null)} initial={voucher} settings={docSettings(db)} />
    </div>
  );
}

Object.assign(window, { WageTax });
