/* global React, I, UI, SSSData */
const { useState: useStateP2, useEffect: useEffectP2 } = React;

// ============ Storage helpers ============
// ย่อชื่อพนักงานแบบสั้น (สอดคล้องรูปแบบ seed)
function prShortName(name) { const p = String(name || "").trim().split(/\s+/); return p.length > 1 ? `${p[0]} ${p[1][0]}.` : (p[0] || "—"); }
// สร้างแถวเงินเดือนตั้งต้นจากข้อมูลพนักงาน (สำหรับคนที่ยังไม่มีใน payroll)
function basePayrollRow(e) {
  const base = e.salary || 0;
  const hourly = e.hourly || 0;
  const stdHours = base ? 0 : (hourly ? 176 : 0);
  const gross = base || (hourly * stdHours);
  const sso = e.sso ? Math.min(Math.round(gross * 0.05), 750) : 0;
  return { emp: e.id, name: prShortName(e.name), base, hours: stdHours, otHours: 0, gross, advance: 0, late: 0, sso, tax: 0, net: gross - sso };
}
// โหลดรายการเงินเดือน + เติมพนักงานที่เพิ่มใหม่ให้มีแถวเสมอ (พนักงานใหม่เข้าระบบคำนวณเงินเดือน)
function loadPayroll() {
  let seed;
  try { seed = JSON.parse(localStorage.getItem("sss-payroll") || "null"); } catch {}
  seed = seed || window.SSSData.PayrollRows || [];
  const emps = (window.SSSData.Employees || []).filter(e => e.id !== "EMP-001" && e.status !== "ลาออก");
  const byId = {}; seed.forEach(r => { byId[r.emp] = r; });
  return emps.map(e => byId[e.id] || basePayrollRow(e));
}
function savePayroll(rows) { try { localStorage.setItem("sss-payroll", JSON.stringify(rows)); } catch {} window.SSSData.PayrollRows = rows; }
function loadTimeRecords() { try { return JSON.parse(localStorage.getItem("sss-timerecords") || "null") || window.SSSData.TimeRecords; } catch { return window.SSSData.TimeRecords; } }
function saveTimeRecords(rows) { try { localStorage.setItem("sss-timerecords", JSON.stringify(rows)); } catch {} window.SSSData.TimeRecords = rows; }
function loadAdvances() {
  try { return JSON.parse(localStorage.getItem("sss-advances") || "null") || []; } catch { return []; }
}
function saveAdvances(list) { try { localStorage.setItem("sss-advances", JSON.stringify(list)); } catch {} }
function loadPayHistory() {
  try { return JSON.parse(localStorage.getItem("sss-pay-history") || "null") || []; } catch { return []; }
}
function savePayHistory(list) { try { localStorage.setItem("sss-pay-history", JSON.stringify(list)); } catch {} }

// วันที่คำนวนล่าสุด (ประทับบนเอกสารทุกฉบับ)
function thaiNowStamp() {
  const d = new Date();
  return d.toLocaleDateString("th-TH", { day: "numeric", month: "short", year: "numeric" }) + " " + d.toLocaleTimeString("th-TH", { hour: "2-digit", minute: "2-digit" }) + " น.";
}
function loadCalcDate() { try { return localStorage.getItem("sss-payroll-calcdate") || "21 พ.ค. 2569 09:42 น."; } catch { return "21 พ.ค. 2569 09:42 น."; } }
function saveCalcDate(s) { try { localStorage.setItem("sss-payroll-calcdate", s); } catch {} }

// ============ Payroll ============
function Payroll({ navigate }) {
  const D = window.SSSData;
  const { Btn, Badge, Card, PageHead, Tabs, Drawer, fmt0, fmtM, bahtText } = window.UI;
  const [tab, setTab] = useStateP2("calc");
  const [active, setActive] = useStateP2(null);
  const [rows, setRows] = useStateP2(loadPayroll);
  const [timeRecs, setTimeRecs] = useStateP2(loadTimeRecords);
  const [advances, setAdvances] = useStateP2(loadAdvances);
  const [showTimeAdd, setShowTimeAdd] = useStateP2(false);
  const [showAdvAdd, setShowAdvAdd] = useStateP2(false);
  const [historyDetail, setHistoryDetail] = useStateP2(null);
  const [selectedAdv, setSelectedAdv] = useStateP2(new Set());
  const [payRound, setPayRound] = useStateP2("full"); // full | first | second
  const [month, setMonth] = useStateP2("2026-05");      // ตัวกรองเดือน
  const [calcDate, setCalcDate] = useStateP2(loadCalcDate); // วันที่คำนวนล่าสุด
  const [payAccountId, setPayAccountId] = useStateP2("SCB"); // บัญชีที่จ่ายค่าแรง
  const [payHistory, setPayHistory] = useStateP2(loadPayHistory);
  const [slogan, setSlogan] = useStateP2(() => { try { return localStorage.getItem("sss-payslip-slogan") || "ขยัน อดทน ซื่อสัตย์ — ทีมแข็งแรง บริษัทเติบโตไปด้วยกัน 💪"; } catch { return ""; } });
  useEffectP2(() => { try { localStorage.setItem("sss-payslip-slogan", slogan); } catch {} }, [slogan]);

  // ===== ตัวกรองเดือน =====
  const TH_M_P = ["ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.", "ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค."];
  const monthLabelOf = (ym) => { const [y, m] = ym.split("-").map(Number); return `${TH_M_P[m - 1]} ${y + 543}`; };
  const MONTH_OPTIONS = Array.from({ length: 12 }, (_, i) => `2026-${String(i + 1).padStart(2, "0")}`);
  const [mYear, mMon] = month.split("-").map(Number);
  const ML = monthLabelOf(month);
  const NML = monthLabelOf(mMon === 12 ? `${mYear + 1}-01` : `${mYear}-${String(mMon + 1).padStart(2, "0")}`);
  const lastD = new Date(mYear, mMon, 0).getDate();
  const isoOfRec = (t) => t.iso || (window.DocDates ? window.DocDates.toISO(t.date) : null) || "";
  const timeRecsMonth = timeRecs.filter(t => isoOfRec(t).startsWith(month));

  // ===== Semi-monthly pay rounds (จ่ายวันที่ 1 และ 16) =====
  const ROUND_INFO = {
    full:   { label: "ทั้งเดือน (2 รอบ)",      range: `1–${lastD} ${ML}`,  pay: `จ่าย 2 รอบ · 16 ${ML} และ 1 ${NML}`, payDate: `16 ${ML} / 1 ${NML}`, workdays: 22, slipPeriod: ML },
    first:  { label: "งวดต้นเดือน (1–15)",     range: `1–15 ${ML}`,  pay: `จ่ายวันที่ 16 ${ML}`,          payDate: `16 ${ML}`,          workdays: 11, slipPeriod: `1–15 ${ML}` },
    second: { label: `งวดท้ายเดือน (16–${lastD})`,   range: `16–${lastD} ${ML}`, pay: `จ่ายวันที่ 1 ${NML}`,          payDate: `1 ${NML}`,          workdays: 11, slipPeriod: `16–${lastD} ${ML}` },
  };
  const dayOf = (d) => { const m = String(d || "").match(/(\d{1,2})/); return m ? +m[1] : 0; };
  const advInRound = (a, round) => {
    if (round === "full") return true;
    const day = dayOf(a.date);
    return round === "first" ? day <= 15 : day >= 16;
  };
  // Build the rows shown for the selected round.
  // Earnings (เงินเดือน/OT/ชั่วโมง) are split in half each round.
  // ประกันสังคม + ภาษีหัก ณ ที่จ่าย ถูกหักในรอบสิ้นเดือน (จ่าย 1) ตามแนวปฏิบัติทั่วไป.
  const roundRows = (round) => {
    if (round === "full") return rows;
    return rows.map(r => {
      const base = Math.round((r.base || 0) / 2);
      const hours = Math.round((r.hours || 0) / 2);
      const otHours = Math.round(((r.otHours || 0) / 2) * 10) / 10;
      const gross = Math.round((r.gross || 0) / 2);
      const late = Math.round((r.late || 0) / 2);
      const advance = advances
        .filter(a => a.empId === r.emp && a.status === "อนุมัติแล้ว" && advInRound(a, round))
        .reduce((s, a) => s + a.amount, 0);
      const sso = round === "second" ? r.sso : 0;
      const tax = round === "second" ? r.tax : 0;
      const net = gross - advance - late - sso - tax;
      return { ...r, base, hours, otHours, gross, late, advance, sso, tax, net };
    });
  };
  const viewRows = roundRows(payRound);
  const RI = ROUND_INFO[payRound];

  // Bulk print advance withdrawal slip(s)
  const printAdvancesBulk = (items) => {
    if (!items || items.length === 0) return;
    const C = D.Company;
    const totalAmount = items.reduce((s, a) => s + a.amount, 0);
    const docNo = "ADV-2569-" + String(Math.floor(Math.random() * 9000) + 1000);
    const today = new Date().toLocaleDateString("th-TH", { day: "numeric", month: "long" }) + " 2569";

    const html = `<div style="background:white;color:#0c0a09;padding:32px 40px;min-height:90vh;border-top:5px solid #9f1239">
      <div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:22px">
        <div style="display:flex;gap:14px;align-items:center">
          <div style="width:54px;height:54px;background:#0c0a09;color:white;display:grid;place-items:center;font-weight:700;font-size:17px;border-radius:5px">SSS</div>
          <div>
            <div style="font-weight:700;font-size:14px">${C.name}</div>
            <div style="font-size:10.5px;color:#57534e;margin-top:3px;max-width:320px">${C.address}</div>
            <div style="font-size:10.5px;color:#57534e">โทร ${C.phone} · เลขผู้เสียภาษี ${C.taxId}</div>
          </div>
        </div>
        <div style="text-align:right">
          <h1 style="margin:0;font-size:24px;color:#9f1239;font-weight:700">ใบเบิกเงินล่วงหน้า</h1>
          <div style="font-size:10.5px;color:#78716c;letter-spacing:0.08em;margin-top:2px">ADVANCE WITHDRAWAL FORM</div>
          <div style="margin-top:12px;padding:8px 14px;background:rgba(159,19,57,0.08);border-radius:4px;font-size:11px">
            <div>เลขที่ <b style="font-family:monospace">${docNo}</b></div>
            <div>วันที่ <b>${today}</b></div>
            <div>จำนวนรายการ <b>${items.length} คน</b></div>
          </div>
        </div>
      </div>

      <table style="width:100%;border-collapse:collapse;margin-top:14px">
        <thead>
          <tr style="background:#9f1239;color:white">
            <th style="padding:10px 8px;font-size:10.5px;text-align:center;width:30px;border-radius:4px 0 0 0">#</th>
            <th style="padding:10px 12px;font-size:10.5px;text-align:left">วันที่ขอเบิก</th>
            <th style="padding:10px 12px;font-size:10.5px;text-align:left">ผู้ขอเบิก</th>
            <th style="padding:10px 12px;font-size:10.5px;text-align:left">เหตุผล / รายละเอียด</th>
            <th style="padding:10px 12px;font-size:10.5px;text-align:right;width:120px;border-radius:0 4px 0 0">จำนวนเงิน (บาท)</th>
          </tr>
        </thead>
        <tbody>
          ${items.map((a, i) => `
            <tr style="${i % 2 === 0 ? 'background:white' : 'background:#fafaf9'}">
              <td style="padding:11px 8px;border-bottom:1px solid #f1efeb;text-align:center;font-size:11.5px;color:#78716c">${i+1}</td>
              <td style="padding:11px 12px;border-bottom:1px solid #f1efeb;font-size:11.5px">${a.date}</td>
              <td style="padding:11px 12px;border-bottom:1px solid #f1efeb;font-size:12px;font-weight:500">${a.emp}</td>
              <td style="padding:11px 12px;border-bottom:1px solid #f1efeb;font-size:11.5px;color:#44403c">${a.reason}</td>
              <td style="padding:11px 12px;border-bottom:1px solid #f1efeb;text-align:right;font-size:12px;font-weight:600">${a.amount.toLocaleString()}</td>
            </tr>
          `).join("")}
          <tr style="background:#f7f6f4">
            <td colspan="4" style="padding:12px;text-align:right;font-weight:700;font-size:13px">รวมเป็นเงิน</td>
            <td style="padding:12px;text-align:right;font-weight:700;font-size:14px">${totalAmount.toLocaleString()}</td>
          </tr>
        </tbody>
      </table>

      <div style="margin-top:18px;padding:10px 14px;background:#9f1239;color:white;border-radius:5px;display:flex;justify-content:space-between;align-items:center">
        <span style="font-size:12px">จำนวนเงินรวมทั้งสิ้น</span>
        <span style="font-size:18px;font-weight:700;font-variant-numeric:tabular-nums">฿ ${totalAmount.toLocaleString()}</span>
      </div>
      <div style="padding:6px 14px;font-size:10.5px;color:#57534e;font-style:italic;text-align:right">(${bahtText(totalAmount)})</div>

      <div style="margin-top:18px;padding:10px 14px;background:#fefdf9;border:1px solid #f1efeb;border-radius:4px;font-size:11px;color:#44403c;line-height:1.6">
        <b style="color:#0c0a09">เงื่อนไข:</b> ยอดเบิกล่วงหน้าทั้งหมดจะถูกหักจากเงินเดือนของพนักงานในงวดที่ระบุ · พนักงานที่เบิกขอรับเงินสด/โอน หลังจากเอกสารได้รับอนุมัติเรียบร้อย
      </div>

      <div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:30px;margin-top:54px;font-size:11px">
        <div style="text-align:center"><div style="border-top:1px dashed #57534e;padding-top:6px;margin-top:40px"><b>ผู้จัดทำ</b><div style="color:#78716c;font-size:10px;margin-top:2px">วันเพ็ญ สุขใจ · ${today}</div></div></div>
        <div style="text-align:center"><div style="border-top:1px dashed #57534e;padding-top:6px;margin-top:40px"><b>หัวหน้าฝ่าย</b><div style="color:#78716c;font-size:10px;margin-top:2px">วันที่ ____________</div></div></div>
        <div style="text-align:center"><div style="border-top:1px dashed #57534e;padding-top:6px;margin-top:40px"><b>ผู้อนุมัติ</b><div style="color:#78716c;font-size:10px;margin-top:2px">ปิยะ ศรีสวัสดิ์ · ____________</div></div></div>
      </div>

      <div style="margin-top:30px;padding-top:8px;border-top:2px solid #9f1239;font-size:9.5px;color:#78716c;display:flex;justify-content:space-between">
        <span>${C.name} · ${C.website}</span>
        <span>${docNo} · ออกโดยระบบ SSS</span>
      </div>
    </div>`;

    document.getElementById("__print_modal")?.remove();
    document.body.classList.remove("printing-modal");
    const modal = document.createElement("div");
    modal.id = "__print_modal";
    modal.className = "print-modal";
    modal.innerHTML = `
      <div class="print-modal-bar no-print">
        <div style="font-weight:600;font-size:14px;flex:1">พิมพ์ใบเบิกเงินล่วงหน้า — ${items.length} รายการ · ฿${totalAmount.toLocaleString()}</div>
        <button id="__print_close" class="pm-btn pm-btn-ghost">ปิด</button>
        <button id="__print_btn" class="pm-btn pm-btn-primary">🖨 พิมพ์</button>
      </div>
      <div class="print-modal-paper">${html}</div>
    `;
    document.body.appendChild(modal);
    document.body.classList.add("printing-modal");
    const cleanup = () => { modal.remove(); document.body.classList.remove("printing-modal"); };
    modal.addEventListener("click", e => { if (e.target === modal) cleanup(); });
    document.getElementById("__print_btn").addEventListener("click", () => window.print());
    document.getElementById("__print_close").addEventListener("click", cleanup);
  };

  useEffectP2(() => savePayroll(rows), [rows]);
  useEffectP2(() => saveTimeRecords(timeRecs), [timeRecs]);
  useEffectP2(() => saveAdvances(advances), [advances]);

  // Generic print modal for official payroll reports (ภ.ง.ด.1 / สปส.1-10)
  const printReport = (kind, period) => {
    const C = D.Company;
    const per = period || "พ.ค. 2569";
    const today = new Date().toLocaleDateString("th-TH", { day: "numeric", month: "long" }) + " 2569";
    const accent = kind === "pnd1" ? "#1e3a5f" : "#1f5f3a";
    const title = kind === "pnd1" ? "แบบ ภ.ง.ด.1" : "แบบ สปส.1-10";
    const subtitle = kind === "pnd1"
      ? "รายการภาษีเงินได้หัก ณ ที่จ่าย ตามมาตรา 59 (เงินเดือน/ค่าจ้าง)"
      : "รายการแสดงการส่งเงินสมทบกองทุนประกันสังคม";
    const docNo = (kind === "pnd1" ? "PND1-2569-" : "SPS-2569-") + String(Math.floor(Math.random() * 9000) + 1000);

    let headCols, bodyRows, totals;
    if (kind === "pnd1") {
      headCols = ["#", "ชื่อ-สกุล", "เลขประจำตัวผู้เสียภาษี", "เงินได้ (บาท)", "ภาษีหัก ณ ที่จ่าย (บาท)"];
      const totIncome = rows.reduce((s, r) => s + r.gross, 0);
      const totTax = rows.reduce((s, r) => s + r.tax, 0);
      bodyRows = rows.map((r, i) => {
        const emp = D.Employees.find(e => e.id === r.emp);
        const taxId = (emp && emp.taxId) || ("3-" + (1000 + i) + "-XXXXX-XX-" + (10 + i));
        return [i + 1, r.name, taxId, r.gross.toLocaleString(), r.tax > 0 ? r.tax.toLocaleString() : "0.00", i % 2];
      });
      totals = ["", "รวม " + rows.length + " ราย", "", totIncome.toLocaleString(), totTax.toLocaleString()];
    } else {
      headCols = ["#", "ชื่อ-สกุล", "ค่าจ้าง (บาท)", "สมทบลูกจ้าง 5%", "สมทบนายจ้าง 5%", "รวม (บาท)"];
      let tWage = 0, tEmp = 0, tEr = 0;
      bodyRows = rows.map((r, i) => {
        const wage = r.gross;
        const empC = r.sso;
        const erC = r.sso; // employer matches 5% (capped 750)
        tWage += wage; tEmp += empC; tEr += erC;
        return [i + 1, r.name, wage.toLocaleString(), empC.toLocaleString(), erC.toLocaleString(), (empC + erC).toLocaleString(), i % 2];
      });
      totals = ["", "รวม " + rows.length + " ราย", tWage.toLocaleString(), tEmp.toLocaleString(), tEr.toLocaleString(), (tEmp + tEr).toLocaleString()];
    }

    const colAlign = (idx) => idx === 0 ? "center" : (idx >= (kind === "pnd1" ? 3 : 2) ? "right" : "left");

    const html = `<div style="background:white;color:#0c0a09;padding:32px 40px;min-height:90vh;border-top:5px solid ${accent}">
      <div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:22px">
        <div style="display:flex;gap:14px;align-items:center">
          <div style="width:54px;height:54px;background:#0c0a09;color:white;display:grid;place-items:center;font-weight:700;font-size:17px;border-radius:5px">SSS</div>
          <div>
            <div style="font-weight:700;font-size:14px">${C.name}</div>
            <div style="font-size:10.5px;color:#57534e;margin-top:3px;max-width:340px">${C.address}</div>
            <div style="font-size:10.5px;color:#57534e">เลขประจำตัวผู้เสียภาษี ${C.taxId}</div>
          </div>
        </div>
        <div style="text-align:right">
          <h1 style="margin:0;font-size:23px;color:${accent};font-weight:700">${title}</h1>
          <div style="font-size:10.5px;color:#78716c;margin-top:2px;max-width:280px">${subtitle}</div>
          <div style="margin-top:12px;padding:8px 14px;background:${accent}14;border-radius:4px;font-size:11px">
            <div>เลขที่ <b style="font-family:monospace">${docNo}</b></div>
            <div>งวด <b>${per}</b></div>
            <div>คำนวนเมื่อ <b>${calcDate}</b></div>
            <div>ยื่นเมื่อ <b>${today}</b></div>
          </div>
        </div>
      </div>

      <table style="width:100%;border-collapse:collapse;margin-top:8px">
        <thead>
          <tr style="background:${accent};color:white">
            ${headCols.map((h, i) => `<th style="padding:9px 10px;font-size:10.5px;text-align:${colAlign(i)}">${h}</th>`).join("")}
          </tr>
        </thead>
        <tbody>
          ${bodyRows.map(r => `<tr style="${r[r.length-1] === 0 ? 'background:white' : 'background:#fafaf9'}">
            ${r.slice(0, -1).map((c, i) => `<td style="padding:9px 10px;border-bottom:1px solid #f1efeb;font-size:11.5px;text-align:${colAlign(i)};${i===1?'font-weight:500':''}">${c}</td>`).join("")}
          </tr>`).join("")}
          <tr style="background:#f3f1ee;font-weight:700">
            ${totals.map((c, i) => `<td style="padding:11px 10px;font-size:12px;text-align:${colAlign(i)}">${c}</td>`).join("")}
          </tr>
        </tbody>
      </table>

      <div style="display:grid;grid-template-columns:1fr 1fr;gap:40px;margin-top:54px;font-size:11px">
        <div style="text-align:center"><div style="border-top:1px dashed #57534e;padding-top:6px;margin-top:40px"><b>ผู้จัดทำ</b><div style="color:#78716c;font-size:10px;margin-top:2px">วันเพ็ญ สุขใจ · ${today}</div></div></div>
        <div style="text-align:center"><div style="border-top:1px dashed #57534e;padding-top:6px;margin-top:40px"><b>ผู้มีอำนาจลงนาม</b><div style="color:#78716c;font-size:10px;margin-top:2px">ปิยะ ศรีสวัสดิ์ · ____________</div></div></div>
      </div>

      <div style="margin-top:30px;padding-top:8px;border-top:2px solid ${accent};font-size:9.5px;color:#78716c;display:flex;justify-content:space-between">
        <span>${C.name} · ${C.website || ""}</span>
        <span>${docNo} · ออกโดยระบบ SSS</span>
      </div>
    </div>`;

    document.getElementById("__print_modal")?.remove();
    document.body.classList.remove("printing-modal");
    const modal = document.createElement("div");
    modal.id = "__print_modal";
    modal.className = "print-modal";
    modal.innerHTML = `
      <div class="print-modal-bar no-print">
        <div style="font-weight:600;font-size:14px;flex:1">${title} — งวด ${per}</div>
        <button id="__print_close" class="pm-btn pm-btn-ghost">ปิด</button>
        <button id="__print_btn" class="pm-btn pm-btn-primary">🖨 พิมพ์ / บันทึก PDF</button>
      </div>
      <div class="print-modal-paper">${html}</div>
    `;
    document.body.appendChild(modal);
    document.body.classList.add("printing-modal");
    const cleanup = () => { modal.remove(); document.body.classList.remove("printing-modal"); };
    modal.addEventListener("click", e => { if (e.target === modal) cleanup(); });
    document.getElementById("__print_btn").addEventListener("click", () => window.print());
    document.getElementById("__print_close").addEventListener("click", cleanup);
    window.toast && window.toast(`ออก${title} งวด ${per} แล้ว`);
  };

  const totalGross = viewRows.reduce((s, r) => s + r.gross, 0);
  const totalNet = viewRows.reduce((s, r) => s + r.net, 0);
  const totalSSO = viewRows.reduce((s, r) => s + r.sso, 0);
  const totalTax = viewRows.reduce((s, r) => s + r.tax, 0);
  const totalAdvance = viewRows.reduce((s, r) => s + r.advance, 0);
  const totalLate = viewRows.reduce((s, r) => s + r.late, 0);

  // Recalculate all payroll rows
  const recalculate = async () => {
    const ok = await window.confirmDialog({
      title: "คำนวนเงินเดือนใหม่",
      message: "ระบบจะดึงข้อมูลล่าสุดมาคำนวน",
      bullets: [
        `ชั่วโมงทำงานรวม OT จากการลงเวลา (${timeRecs.length} วัน)`,
        "เบิกเงินล่วงหน้าที่อนุมัติแล้ว",
        "หักประกันสังคม 5% (สูงสุด 750 บาท)",
        "หัก ณ ที่จ่าย ภ.ง.ด.1"
      ],
      confirmText: "คำนวนใหม่"
    });
    if (!ok) return;
    const next = rows.map(r => {
      const emp = D.Employees.find(e => e.id === r.emp);
      if (!emp) return r;
      // Sum hours from time records
      const myTime = timeRecs.filter(t => t.emp === r.emp);
      const hours = myTime.reduce((s, t) => s + (t.work || 0), 0);
      const otHours = myTime.reduce((s, t) => s + (t.ot || 0), 0);
      const lateMin = myTime.reduce((s, t) => s + (t.late || 0), 0);
      // Calculate gross
      let gross;
      if (emp.salary > 0) {
        gross = emp.salary + otHours * (emp.otRate || 0);
      } else {
        gross = (hours > 0 ? hours : r.hours) * (emp.hourly || 0) + otHours * (emp.otRate || 0);
      }
      // SSO 5% (cap 750)
      const sso = emp.sso ? Math.min(750, Math.floor(gross * 0.05)) : 0;
      // Late deduction = lateMin / 60 × hourly
      const lateAmount = lateMin > 0 ? Math.round((lateMin / 60) * (emp.hourly || (emp.salary / 22 / 8))) : r.late;
      // Advance from approved advances this period
      const advAmount = advances.filter(a => a.empId === r.emp && a.status === "อนุมัติแล้ว" && a.period === "พ.ค. 2569").reduce((s, a) => s + a.amount, 0);
      const tax = r.tax;
      const net = gross - sso - tax - advAmount - lateAmount;
      return { ...r, hours: hours || r.hours, otHours: otHours || r.otHours, gross, sso, advance: advAmount, late: lateAmount, net };
    });
    setRows(next);
    const stamp = thaiNowStamp();
    setCalcDate(stamp);
    saveCalcDate(stamp);
    window.logActivity && window.logActivity("คำนวนเงินเดือน", `งวด ${ML} · คำนวนเมื่อ ${stamp}`, "update");
    window.toast && window.toast("คำนวนเงินเดือนใหม่แล้ว · " + stamp);
  };

  const bulkTransfer = async () => {
    const payAccts = (window.CompanyCashStore && window.CompanyCashStore.ACCOUNTS) || [];
    const acc = payAccts.find(a => a.id === payAccountId) || { name: "ธ.ไทยพาณิชย์", short: "SCB" };
    const ok = await window.confirmDialog({
      title: `จ่ายเงินเดือน — ${RI.label}`,
      message: `<b class="mono">จ่ายรวม ฿${fmt0(totalNet)} ไปยังพนักงาน ${viewRows.length} คน</b><br/>รอบ ${RI.range} · จ่ายจาก <b>${acc.name}</b>`,
      bullets: [
        `ตัดยอดเงินออกจากบัญชี ${acc.short} ในหน้าบัญชีธนาคาร`,
        "ดาวน์โหลดไฟล์ Bulk Transfer (.xlsx) สำหรับอัปโหลดเข้า K-Cyber Banking",
        "บันทึกใบสำคัญจ่าย PV-2569-XXXX อัตโนมัติ",
        "ส่ง pay slip ให้พนักงานทุกคนทางอีเมล",
        "อัปเดตสถานะรอบเป็น 'จ่ายแล้ว'"
      ],
      confirmText: "จ่ายเงินเดือน",
      cancelText: "ยกเลิก"
    });
    if (!ok) return;
    if (window.CompanyCashStore && window.CompanyCashStore.addMovement) {
      window.CompanyCashStore.addMovement({
        accountId: payAccountId, direction: "out", amount: totalNet,
        desc: `จ่ายเงินเดือน ${RI.label} — พนักงาน ${viewRows.length} คน`, ref: "PAYROLL", source: "คำนวนเงินเดือน"
      });
    }
    const histEntry = {
      id: "PAY-" + Date.now(),
      month, monthLabel: ML, round: payRound, roundLabel: RI.label,
      payDate: RI.payDate, paidAt: thaiNowStamp(),
      count: viewRows.length, gross: totalGross,
      deduct: totalSSO + totalTax + totalAdvance + totalLate,
      net: totalNet, accountId: payAccountId, accountName: acc.short,
    };
    const nextHist = [histEntry, ...payHistory];
    setPayHistory(nextHist);
    savePayHistory(nextHist);
    window.logActivity && window.logActivity("จ่ายเงินเดือน", `${RI.label} ฿${fmt0(totalNet)} จาก${acc.short}`, "approve");
    window.toast && window.toast(`จ่ายเงินเดือน ฿${fmt0(totalNet)} จาก${acc.name} (${RI.label}) แล้ว — ตัดยอดบัญชีให้อัตโนมัติ`);
  };

  const exportExcel = () => {
    // Generate CSV
    const headers = ["รหัส", "ชื่อ", "เงินเดือน", "ชม.ทำงาน", "ชม. OT", "รวมรายได้", "เบิกล่วงหน้า", "มาสาย", "SSO", "หักภาษี", "สุทธิ"];
    const csvRows = [headers.join(",")];
    viewRows.forEach(r => {
      csvRows.push([r.emp, r.name, r.base, r.hours, r.otHours, r.gross, r.advance, r.late, r.sso, r.tax, r.net].join(","));
    });
    const blob = new Blob(["\uFEFF" + csvRows.join("\n")], { type: "text/csv;charset=utf-8" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a"); a.href = url; a.download = `payroll-${payRound}-${new Date().toISOString().slice(0,10)}.csv`; a.click();
    URL.revokeObjectURL(url);
    window.toast && window.toast(`ส่งออก Excel (${RI.label}) แล้ว`);
  };

  const printAllSlips = () => {
    if (viewRows.length === 0) return;
    // Render all slips into a modal
    const C = D.Company;
    const slipsHTML = viewRows.map((row, i) => {
      const emp = D.Employees.find(e => e.id === row.emp);
      return `
        <div style="${i > 0 ? 'page-break-before:always;' : ''}background:white;color:#0c0a09;padding:30px 36px;min-height:90vh">
          <div style="display:flex;justify-content:space-between;border-bottom:1px solid #e7e5e4;padding-bottom:12px;margin-bottom:16px">
            <div style="display:flex;align-items:center;gap:10px">
              <div style="width:36px;height:36px;background:#0c0a09;color:white;display:grid;place-items:center;font-weight:700;border-radius:5px">SSS</div>
              <div><div style="font-weight:600;font-size:13px">${C.name}</div><div style="font-size:10.5px;color:#78716c">เลขผู้เสียภาษี ${C.taxId}</div></div>
            </div>
            <div style="text-align:right"><h1 style="margin:0;font-size:18px">ใบจ่ายเงินเดือน</h1><div style="font-size:11px;color:#57534e">PAY SLIP · งวด ${RI.slipPeriod}</div><div style="font-size:10px;color:#78716c;margin-top:2px">คำนวนเมื่อ ${calcDate} · พิมพ์เมื่อ ${thaiNowStamp()}</div></div>
          </div>
          <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:14px;font-size:12px">
            <div><div style="font-size:10px;color:#78716c">พนักงาน</div><div style="font-weight:600">${emp?.name}</div></div>
            <div><div style="font-size:10px;color:#78716c">รหัส / แผนก</div><div>${emp?.id} · ${emp?.dept}</div></div>
            <div><div style="font-size:10px;color:#78716c">ตำแหน่ง</div><div>${emp?.role}</div></div>
            <div><div style="font-size:10px;color:#78716c">วันจ่าย</div><div>${RI.payDate}</div></div>
            <div><div style="font-size:10px;color:#78716c">วันที่คำนวน</div><div>${calcDate}</div></div>
          </div>
          <div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px">
            <div>
              <div style="font-size:11px;font-weight:600;text-transform:uppercase;margin-bottom:6px">รายได้</div>
              <table style="width:100%;font-size:12px">
                <tr><td>เงินเดือน/ค่าจ้าง</td><td style="text-align:right">${(row.base > 0 ? row.base : row.hours * (emp?.hourly || 0)).toLocaleString()}</td></tr>
                <tr><td>OT (${row.otHours} ชม.)</td><td style="text-align:right">${(row.otHours * (emp?.otRate || 0)).toLocaleString()}</td></tr>
                <tr style="border-top:1px solid #e7e5e4;font-weight:600"><td style="padding:6px 0">รวม</td><td style="text-align:right">${row.gross.toLocaleString()}</td></tr>
              </table>
            </div>
            <div>
              <div style="font-size:11px;font-weight:600;text-transform:uppercase;margin-bottom:6px">รายการหัก</div>
              <table style="width:100%;font-size:12px">
                <tr><td>SSO 5%</td><td style="text-align:right">−${row.sso.toLocaleString()}</td></tr>
                <tr><td>ภ.ง.ด.1</td><td style="text-align:right">${row.tax > 0 ? '−'+row.tax.toLocaleString() : '—'}</td></tr>
                <tr><td>เบิกล่วงหน้า</td><td style="text-align:right">${row.advance > 0 ? '−'+row.advance.toLocaleString() : '—'}</td></tr>
                <tr><td>มาสาย</td><td style="text-align:right">${row.late > 0 ? '−'+row.late.toLocaleString() : '—'}</td></tr>
                <tr style="border-top:1px solid #e7e5e4;font-weight:600"><td style="padding:6px 0">รวม</td><td style="text-align:right">−${(row.sso+row.tax+row.advance+row.late).toLocaleString()}</td></tr>
              </table>
            </div>
          </div>
          <div style="border-top:2px solid #0c0a09;padding:12px 0;display:flex;justify-content:space-between;align-items:center">
            <div style="font-size:11px;color:#78716c">ยอดสุทธิจ่าย</div>
            <div style="font-size:22px;font-weight:600">฿${row.net.toLocaleString()}</div>
          </div>
        </div>
      `;
    }).join("");

    document.getElementById("__print_modal")?.remove();
    document.body.classList.remove("printing-modal");
    const modal = document.createElement("div");
    modal.id = "__print_modal";
    modal.className = "print-modal";
    modal.innerHTML = `
      <div class="print-modal-bar no-print">
        <div style="font-weight:600;font-size:14px;flex:1">พิมพ์ Pay Slip — ${rows.length} ใบ</div>
        <button id="__print_close" class="pm-btn pm-btn-ghost">ปิด</button>
        <button id="__print_btn" class="pm-btn pm-btn-primary">🖨 พิมพ์</button>
      </div>
      <div class="print-modal-paper">${slipsHTML}</div>
    `;
    document.body.appendChild(modal);
    document.body.classList.add("printing-modal");
    const cleanup = () => { modal.remove(); document.body.classList.remove("printing-modal"); };
    modal.addEventListener("click", e => { if (e.target === modal) cleanup(); });
    document.getElementById("__print_btn").addEventListener("click", () => window.print());
    document.getElementById("__print_close").addEventListener("click", cleanup);
  };

  const editLate = (empId, delta) => {
    setRows(rs => rs.map(r => r.emp === empId ? { ...r, late: Math.max(0, r.late + delta), net: r.net - delta } : r));
  };

  return (
    <>
      <PageHead title="คำนวนเงินเดือน · Payroll"
        sub={`เดือน ${ML} · ${RI.label} · ${RI.pay} · คำนวนล่าสุด ${calcDate}`}
        right={<>
          <select className="input" style={{width: 130, height: 34, fontSize: 13}} value={month} onChange={e => setMonth(e.target.value)} title="เลือกเดือน">
            {MONTH_OPTIONS.map(m => <option key={m} value={m}>{monthLabelOf(m)}</option>)}
          </select>
          <select className="input" style={{ width: 168, height: 34, fontSize: 12.5 }} value={payAccountId} onChange={e => setPayAccountId(e.target.value)} title="จ่ายค่าแรงจากบัญชี">
            {((window.CompanyCashStore && window.CompanyCashStore.ACCOUNTS) || []).map(a => <option key={a.id} value={a.id}>จ่ายจาก: {a.short}</option>)}
          </select>
          <Btn icon={I.calc} kind="ghost" onClick={recalculate}>คำนวนใหม่</Btn>
          <Btn icon={I.send} kind="primary" onClick={bulkTransfer}>จ่ายเงินเดือน</Btn>
        </>}/>

      <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 14, padding: "8px 12px", background: "var(--surface-2)", border: "1px solid var(--line)", borderRadius: 8 }}>
        <span style={{ fontSize: 13 }}>📢</span>
        <span style={{ fontSize: 12.5, color: "var(--ink-3)", whiteSpace: "nowrap" }}>คำขวัญปลุกใจ (พิมพ์บนใบจ่ายเงิน)</span>
        <input className="input" value={slogan} onChange={e => setSlogan(e.target.value)} placeholder="เช่น ขยันวันนี้ เพื่อพรุ่งนี้ที่ดีกว่า" style={{ flex: 1, height: 32, fontSize: 12.5 }}></input>
      </div>

      <div className="grid cols-5 mb-lg">
        <window.UI.Stat label="พนักงาน" value={`${rows.length} คน`} sub="ใน 5 แผนก" icon={I.user}/>
        <window.UI.Stat label="ค่าจ้างขั้นต้น" value={`฿${fmt0(totalGross)}`} sub="รวม OT" icon={I.payroll}/>
        <window.UI.Stat label="หักประกันสังคม" value={`฿${fmt0(totalSSO)}`} sub="นายจ้างสมทบเท่ากัน" icon={I.shield}/>
        <window.UI.Stat label="หัก ณ ที่จ่าย" value={`฿${fmt0(totalTax)}`} sub="ส่งกรมสรรพากร" icon={I.tax}/>
        <window.UI.Stat label="ยอดสุทธิจ่าย" value={`฿${fmt0(totalNet)}`} sub="โอนเข้าบัญชีพนักงาน" icon={I.money}/>
      </div>

      <Tabs items={[
        { key: "calc", label: "คำนวนเงินเดือน" },
        { key: "time", label: "ลงเวลา / OT", count: timeRecsMonth.length },
        { key: "late", label: "การมาสาย / ขาดงาน" },
        { key: "advance", label: "เบิกล่วงหน้า", count: advances.length },
        { key: "history", label: "ประวัติการจ่าย" }
      ]} active={tab} onChange={setTab}/>

      {tab === "calc" && (
        <Card flush>
          <div style={{padding: 12, borderBottom: "1px solid var(--line)", display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap"}}>
            <div style={{display: "flex", alignItems: "center", gap: 8}}>
              <span className="label" style={{color: "var(--ink-3)"}}>รอบจ่าย:</span>
              <div className="payseg">
                {[["full", "ทั้งเดือน"], ["first", "ต้นเดือน (1–15)"], ["second", "ท้ายเดือน (16–31)"]].map(([k, lbl]) => (
                  <button key={k} className={"payseg-btn" + (payRound === k ? " active" : "")} onClick={() => setPayRound(k)}>{lbl}</button>
                ))}
              </div>
            </div>
            <div className="label" style={{color: "var(--ink-3)"}}>ช่วง <b style={{color: "var(--ink-1)"}}>{RI.range}</b> · วันทำงาน <b style={{color: "var(--ink-1)"}}>{RI.workdays} วัน</b> · {RI.pay}</div>
            <span className="spacer"/>
            <span style={{fontSize: 11.5, color: "var(--ink-3)", display: "inline-flex", alignItems: "center", gap: 5, padding: "4px 10px", background: "var(--surface-2)", border: "1px solid var(--line)", borderRadius: 99}}>
              <I.clock size={12}/>คำนวนล่าสุด <b style={{color: "var(--ink-1)"}}>{calcDate}</b>
            </span>
            <Btn size="sm" kind="ghost" icon={I.download} onClick={exportExcel}>ส่งออก Excel</Btn>
            <Btn size="sm" kind="ghost" icon={I.print} onClick={printAllSlips}>พิมพ์ Slip ทั้งหมด</Btn>
          </div>
          <div className="table-wrap">
            <table className="t">
              <thead>
                <tr>
                  <th>รหัส</th><th>ชื่อ</th>
                  <th className="right">เงินเดือน</th>
                  <th className="right">ชม.ทำงาน</th>
                  <th className="right">ชม. OT</th>
                  <th className="right">รวมรายได้</th>
                  <th className="right">เบิกล่วงหน้า</th>
                  <th className="right">มาสาย</th>
                  <th className="right">SSO</th>
                  <th className="right">หัก ณ ที่จ่าย</th>
                  <th className="right">สุทธิ</th>
                  <th></th>
                </tr>
              </thead>
              <tbody>
                {viewRows.map(r => (
                  <tr key={r.emp} className="row-clickable" onClick={() => setActive(r)}>
                    <td className="mono">{r.emp}</td>
                    <td>{r.name}</td>
                    <td className="right amount muted">{r.base > 0 ? `฿${fmt0(r.base)}` : `${D.Employees.find(e=>e.id===r.emp)?.hourly}/ชม.`}</td>
                    <td className="right amount">{r.hours || "—"}</td>
                    <td className="right amount">{r.otHours || "—"}</td>
                    <td className="right amount">฿{fmt0(r.gross)}</td>
                    <td className="right amount muted">{r.advance > 0 ? `−฿${fmt0(r.advance)}` : "—"}</td>
                    <td className="right amount muted" style={{color: r.late > 0 ? "var(--danger)" : "inherit"}}>{r.late > 0 ? `−฿${fmt0(r.late)}` : "—"}</td>
                    <td className="right amount muted">−฿{fmt0(r.sso)}</td>
                    <td className="right amount muted">{r.tax > 0 ? `−฿${fmt0(r.tax)}` : "—"}</td>
                    <td className="right amount" style={{fontWeight: 600}}>฿{fmt0(r.net)}</td>
                    <td onClick={e=>e.stopPropagation()}><Btn kind="ghost" size="sm" icon={I.print} onClick={() => setActive(r)}/></td>
                  </tr>
                ))}
                <tr style={{background: "var(--surface-2)", fontWeight: 600}}>
                  <td colSpan={5} style={{textAlign: "right"}}>รวมทั้งหมด</td>
                  <td className="right amount">฿{fmt0(totalGross)}</td>
                  <td className="right amount">−฿{fmt0(totalAdvance)}</td>
                  <td className="right amount">−฿{fmt0(totalLate)}</td>
                  <td className="right amount">−฿{fmt0(totalSSO)}</td>
                  <td className="right amount">−฿{fmt0(totalTax)}</td>
                  <td className="right amount" style={{fontSize: 15}}>฿{fmt0(totalNet)}</td>
                  <td></td>
                </tr>
              </tbody>
            </table>
          </div>
        </Card>
      )}

      {tab === "time" && (
        <>
          {window.PayrollQRImport && <window.PayrollQRImport timeRecs={timeRecs} setTimeRecs={setTimeRecs} month={month} setMonth={setMonth}/>}
          {window.PayrollTimeTab
            ? <window.PayrollTimeTab timeRecs={timeRecs} setTimeRecs={setTimeRecs} month={month}/>
            : <TimeScheduleBuilder timeRecs={timeRecs} setTimeRecs={setTimeRecs}/>}
        </>
      )}

      {tab === "late" && window.PayrollAttendanceTab && (
        <window.PayrollAttendanceTab timeRecs={timeRecs} month={month}/>
      )}

      {tab === "advance" && (
        <Card title={`คำขอเบิกเงินล่วงหน้า — ${ML}`} flush right={<>
          {advances.filter(a => selectedAdv.has(a.empId + "_" + a.date)).length > 0 ? (
            <>
              <span style={{fontSize: 12, color: "var(--ink-3)", padding: "0 6px"}}>เลือก {selectedAdv.size} รายการ</span>
              <Btn size="sm" kind="ghost" onClick={() => setSelectedAdv(new Set())}>ยกเลิก</Btn>
              <Btn size="sm" icon={I.print} kind="primary" onClick={() => printAdvancesBulk(advances.filter(a => selectedAdv.has(a.empId + "_" + a.date)))}>พิมพ์รวม ({selectedAdv.size})</Btn>
            </>
          ) : <Btn size="sm" icon={I.plus} onClick={() => setShowAdvAdd(true)}>บันทึกการเบิก</Btn>}
        </>}>
          <div className="table-wrap">
            <table className="t">
              <thead><tr>
                <th style={{width: 36, paddingLeft: 14}}>
                  <input type="checkbox" checked={advances.length > 0 && advances.every(a => selectedAdv.has(a.empId + "_" + a.date))}
                    onChange={e => {
                      if (e.target.checked) setSelectedAdv(new Set(advances.map(a => a.empId + "_" + a.date)));
                      else setSelectedAdv(new Set());
                    }}/>
                </th>
                <th>วันที่</th><th>พนักงาน</th><th>เหตุผล</th><th className="right">จำนวน</th><th>สถานะ</th><th>หักจากงวด</th><th></th>
              </tr></thead>
              <tbody>
                {advances.map((a, i) => {
                  const key = a.empId + "_" + a.date;
                  return (
                    <tr key={i}>
                      <td style={{paddingLeft: 14}} onClick={e => e.stopPropagation()}>
                        <input type="checkbox" checked={selectedAdv.has(key)} onChange={() => {
                          const next = new Set(selectedAdv);
                          if (next.has(key)) next.delete(key); else next.add(key);
                          setSelectedAdv(next);
                        }}/>
                      </td>
                      <td>{a.date}</td>
                      <td>{a.emp}</td>
                      <td className="muted">{a.reason}</td>
                      <td className="right amount">฿{fmt0(a.amount)}</td>
                      <td>
                        {a.status === "รออนุมัติ" ? (
                          <div style={{display: "flex", gap: 4}}>
                            <Btn size="sm" kind="primary" onClick={() => { setAdvances(advances.map((x, j) => j === i ? { ...x, status: "อนุมัติแล้ว" } : x)); window.logActivity && window.logActivity("อนุมัติ", `ใบเบิก ${a.emp} ฿${fmt0(a.amount)}`, "approve"); window.toast && window.toast("อนุมัติแล้ว"); }}>อนุมัติ</Btn>
                            <Btn size="sm" kind="ghost" onClick={() => { setAdvances(advances.map((x, j) => j === i ? { ...x, status: "ปฏิเสธ" } : x)); window.logActivity && window.logActivity("ปฏิเสธ", `ใบเบิก ${a.emp}`, "approve"); }}>ปฏิเสธ</Btn>
                          </div>
                        ) : <Badge>{a.status}</Badge>}
                      </td>
                      <td>{a.period}</td>
                      <td>
                        <div style={{display:"flex", gap:2}}>
                          <Btn size="sm" kind="ghost" icon={I.print} onClick={() => printAdvancesBulk([a])} title="พิมพ์ใบเบิก"/>
                          <Btn size="sm" kind="ghost" icon={I.trash} onClick={async () => {
                            const ok = await window.confirmDelete(`ใบเบิก ${a.emp}`, `จำนวน ฿${fmt0(a.amount)} · เหตุผล: ${a.reason}`);
                            if (ok) setAdvances(advances.filter((_, j) => j !== i));
                          }}/>
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </Card>
      )}

      {tab === "history" && (
        <Card title="ประวัติการจ่ายเงินเดือน — แยกตามใบจ่าย (ต้นเดือน / ท้ายเดือน)" sub="บริษัทจ่าย 2 รอบ · งวด 1–15 จ่ายวันที่ 16 · งวด 16–สิ้นเดือน จ่ายวันที่ 1 ของเดือนถัดไป" flush>
          {payHistory.length === 0 ? (
            <div style={{ padding: 40, textAlign: "center", color: "var(--ink-3)" }}>
              <div style={{ fontSize: 32, marginBottom: 10 }}>📋</div>
              <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 6 }}>ยังไม่มีประวัติการจ่ายเงิน</div>
              <div style={{ fontSize: 12.5 }}>กด "จ่ายเงินเดือน" ในแท็บคำนวนเงินเดือน เพื่อบันทึกรายการ</div>
            </div>
          ) : (
            <div className="table-wrap">
              <table className="t">
                <thead><tr><th>เดือน</th><th>รอบ</th><th>วันจ่าย</th><th>บัญชี</th><th className="right">จำนวนคน</th><th className="right">ยอดรวม</th><th className="right">หักรวม</th><th className="right">สุทธิ</th><th>สถานะ</th><th></th></tr></thead>
                <tbody>
                  {payHistory.map((h) => (
                    <tr key={h.id} className="row-clickable" onClick={() => setHistoryDetail({ period: `${h.roundLabel} · ${h.monthLabel}`, total: h.gross, net: h.net, deduct: h.deduct, count: h.count, payDate: h.paidAt })}>
                      <td style={{ fontWeight: 600 }}>{h.monthLabel}</td>
                      <td><span className={`badge ${h.round === "first" ? "info" : ""}`}>{h.roundLabel}</span></td>
                      <td>{h.payDate}</td>
                      <td className="muted">{h.accountName}</td>
                      <td className="right">{h.count}</td>
                      <td className="right amount">฿{fmt0(h.gross)}</td>
                      <td className="right amount">−฿{fmt0(h.deduct)}</td>
                      <td className="right amount" style={{ fontWeight: 600 }}>฿{fmt0(h.net)}</td>
                      <td><Badge tone="success">จ่ายแล้ว</Badge></td>
                      <td><Btn size="sm" kind="ghost" icon={I.search}>ดู</Btn></td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </Card>
      )}

      {/* Pay slip drawer */}
      <Drawer open={!!active} onClose={() => setActive(null)} title={active ? `ใบจ่ายเงินเดือน · ${active.name}` : ""} wide
        footer={<><Btn icon={I.send} kind="ghost" onClick={() => window.toast && window.toast("ส่งอีเมล pay slip ไปยังพนักงานแล้ว")}>ส่งทางอีเมล</Btn><Btn icon={I.print} kind="primary" onClick={() => window.printDocPaperWithOptions()}>พิมพ์</Btn></>}>
        {active && <PaySlip row={active} period={RI.slipPeriod} payDate={RI.payDate} calcDate={calcDate} slogan={slogan} timeRecs={timeRecs} advances={advances} month={month}/>}
      </Drawer>

      {showTimeAdd && <TimeAddModal onClose={() => setShowTimeAdd(false)} onSave={(t) => { setTimeRecs([t, ...timeRecs]); setShowTimeAdd(false); window.toast && window.toast("บันทึกเวลาแล้ว"); }}/>}
      {showAdvAdd && <AdvanceAddModal onClose={() => setShowAdvAdd(false)} onSave={(a) => { setAdvances([{ ...a, status: "รออนุมัติ", period: "พ.ค. 2569", date: "22 พ.ค. 2569" }, ...advances]); setShowAdvAdd(false); window.toast && window.toast("บันทึกใบเบิกแล้ว"); }}/>}

      <Drawer open={!!historyDetail} onClose={() => setHistoryDetail(null)} title={historyDetail ? "งวด " + historyDetail.period : ""}
        footer={<Btn kind="ghost" onClick={() => setHistoryDetail(null)}>ปิด</Btn>}>
        {historyDetail && (
          <div style={{display: "flex", flexDirection: "column", gap: 12}}>
            <div className="grid cols-2" style={{gap: 8}}>
              <div className="stat"><div className="label">วันจ่าย</div><div className="value" style={{fontSize: 14}}>{historyDetail.payDate}</div></div>
              <div className="stat"><div className="label">จำนวนพนักงาน</div><div className="value">{historyDetail.count} คน</div></div>
              <div className="stat"><div className="label">ยอดรวม (Gross)</div><div className="value">฿{fmt0(historyDetail.total)}</div></div>
              <div className="stat"><div className="label">หักรวม</div><div className="value">฿{fmt0(historyDetail.deduct)}</div></div>
            </div>
            <div className="stat" style={{background: "var(--success-bg)", border: "1px solid var(--success)"}}>
              <div className="label">ยอดสุทธิที่จ่าย</div>
              <div className="value" style={{color: "var(--success)"}}>฿{fmt0(historyDetail.net)}</div>
            </div>
            <Btn icon={I.download} onClick={() => { printAllSlips(); }}>ดาวน์โหลด pay slip รวม</Btn>
            <Btn icon={I.doc} onClick={() => printReport("pnd1", historyDetail.period)}>ออก ภ.ง.ด.1</Btn>
            <Btn icon={I.book} onClick={() => printReport("sps110", historyDetail.period)}>ออก สปส.1-10</Btn>
          </div>
        )}
      </Drawer>
    </>
  );
}

function TimeScheduleBuilder({ timeRecs, setTimeRecs }) {
  const D = window.SSSData;
  const { Btn, Badge, Card } = window.UI;
  const monthsTh = ["ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค."];
  const dayNames = ["อา","จ","อ","พ","พฤ","ศ","ส"];

  // Time policy defaults — persisted
  const loadPolicy = () => {
    try { return JSON.parse(localStorage.getItem("sss-time-policy") || "null") || {
      defaultIn: "08:30",
      breakStart: "12:00",
      breakEnd: "13:00",
      defaultOut: "17:30",
      standardHours: 8,
      otMultiplier: 1.5,
      lateGraceMin: 5,
      lateDeductPerMin: 5
    }; } catch { return {}; }
  };
  const [policy, setPolicy] = useStateP2(loadPolicy);
  const [showPolicy, setShowPolicy] = useStateP2(false);

  React.useEffect(() => { localStorage.setItem("sss-time-policy", JSON.stringify(policy)); }, [policy]);

  const [empId, setEmpId] = useStateP2(D.Employees[2]?.id || D.Employees[0]?.id || "");
  const [startDate, setStartDate] = useStateP2("2026-05-01");
  const [endDate, setEndDate] = useStateP2("2026-05-31");
  const [schedule, setSchedule] = useStateP2([]);

  // กัน state ค้างจากรายชื่อพนักงานที่ถูกแก้/ลบ — ถ้า id ไม่อยู่ในลิสต์แล้ว รีเซ็ตเป็นคนแรก
  React.useEffect(() => {
    if (D.Employees.length && !D.Employees.some(e => e.id === empId)) {
      setEmpId(D.Employees[0].id);
    }
  }, [D.Employees.length]);

  const emp = D.Employees.find(e => e.id === empId);

  const STATUSES = [
    { key: "ทำงาน", emoji: "💼" },
    { key: "OT", emoji: "⏰" },
    { key: "วันหยุด", emoji: "🏖️" },
    { key: "ลา", emoji: "🌴" },
    { key: "ขาด", emoji: "❌" },
    { key: "นอกสถานที่", emoji: "🚗" }
  ];

  const fmtThai = (iso) => {
    const [y, m, d] = iso.split("-").map(Number);
    return `${d} ${monthsTh[m-1]} ${y + 543}`;
  };

  // Helpers
  const toMin = (t) => { if (!t) return 0; const [h, m] = t.split(":").map(Number); return h*60+m; };
  const breakMin = () => toMin(policy.breakEnd) - toMin(policy.breakStart);

  // Compute work/OT/late from in-out times, applying policy
  const computeFromTimes = (inT, outT) => {
    if (!inT || !outT) return { work: 0, ot: 0, late: 0, lateDeduct: 0 };
    const inM = toMin(inT), outM = toMin(outT);
    const stdInM = toMin(policy.defaultIn);
    let lateRaw = Math.max(0, inM - stdInM);
    // Grace period
    const lateMin = lateRaw > policy.lateGraceMin ? lateRaw : 0;
    const lateDeduct = lateMin * policy.lateDeductPerMin;
    const total = Math.max(0, outM - inM - breakMin()) / 60;
    let work = Math.min(total, policy.standardHours);
    let ot = Math.max(0, total - policy.standardHours);
    return { work: Math.round(work * 100) / 100, ot: Math.round(ot * 100) / 100, late: lateMin, lateDeduct };
  };

  const generateSchedule = () => {
    const effEmpId = D.Employees.some(e => e.id === empId) ? empId : (D.Employees[0]?.id || "");
    if (!effEmpId || !startDate || !endDate) { window.toast && window.toast("กรุณาเลือกพนักงานและช่วงวันที่"); return; }
    if (effEmpId !== empId) setEmpId(effEmpId);
    const effEmp = D.Employees.find(e => e.id === effEmpId);
    const s = new Date(startDate);
    const e = new Date(endDate);
    if (e < s) { window.toast && window.toast("วันสิ้นสุดต้องหลังวันเริ่ม"); return; }
    const days = [];
    const cur = new Date(s);
    while (cur <= e) {
      const dow = cur.getDay();
      const iso = cur.toISOString().slice(0, 10);
      const existing = timeRecs.find(t => t.iso === iso && t.emp === effEmpId);
      const isWeekend = dow === 0 || dow === 6;
      if (existing) {
        days.push(existing);
      } else {
        const calc = isWeekend ? { work: 0, ot: 0, late: 0 } : computeFromTimes(policy.defaultIn, policy.defaultOut);
        days.push({
          iso, emp: effEmpId, name: effEmp?.name,
          date: fmtThai(iso), dow,
          status: isWeekend ? "วันหยุด" : "ทำงาน",
          in: isWeekend ? "" : policy.defaultIn,
          out: isWeekend ? "" : policy.defaultOut,
          break: breakMin(),
          work: calc.work, ot: calc.ot, late: calc.late,
          offsiteDays: 0, note: ""
        });
      }
      cur.setDate(cur.getDate() + 1);
    }
    setSchedule(days);
    window.toast && window.toast(`สร้างตาราง ${days.length} วันแล้ว`);
  };

  const updateRow = (idx, patch) => {
    setSchedule(s => s.map((r, i) => {
      if (i !== idx) return r;
      const next = { ...r, ...patch };
      // Auto-recalc if in/out changed and status is ทำงาน or OT
      if ((patch.in !== undefined || patch.out !== undefined) && (next.status === "ทำงาน" || next.status === "OT")) {
        const calc = computeFromTimes(next.in, next.out);
        next.work = calc.work; next.ot = calc.ot; next.late = calc.late;
        if (next.ot > 0 && next.status === "ทำงาน") next.status = "OT";
      }
      return next;
    }));
  };

  const onStatusChange = (idx, status) => {
    const cur = schedule[idx];
    const patches = { status };
    if (status === "วันหยุด" || status === "ลา" || status === "ขาด") {
      patches.in = ""; patches.out = ""; patches.work = 0; patches.ot = 0; patches.late = 0;
    } else if (status === "นอกสถานที่") {
      patches.in = ""; patches.out = ""; patches.work = 0; patches.late = 0; patches.ot = 0;
      if (!cur.offsiteDays) patches.offsiteDays = 1;
    } else if (status === "OT") {
      const inT = cur.in || policy.defaultIn;
      const outT = cur.out || "20:00";
      patches.in = inT; patches.out = outT;
      const c = computeFromTimes(inT, outT);
      patches.work = c.work; patches.ot = c.ot; patches.late = c.late;
    } else if (status === "ทำงาน") {
      const inT = cur.in || policy.defaultIn;
      const outT = cur.out || policy.defaultOut;
      patches.in = inT; patches.out = outT;
      const c = computeFromTimes(inT, outT);
      patches.work = c.work; patches.ot = c.ot; patches.late = c.late;
    }
    updateRow(idx, patches);
  };

  const saveSchedule = () => {
    const merged = [...timeRecs];
    schedule.forEach(s => {
      const idx = merged.findIndex(t => t.iso === s.iso && t.emp === s.emp);
      if (idx >= 0) merged[idx] = s; else merged.unshift(s);
    });
    setTimeRecs(merged);
    window.toast && window.toast(`บันทึก ${schedule.length} วันของ ${emp?.name}`);
  };

  const summary = {
    workDays: schedule.filter(s => s.status === "ทำงาน" || s.status === "OT").length,
    otHours: schedule.reduce((a, s) => a + (s.ot || 0), 0),
    totalWork: schedule.reduce((a, s) => a + (s.work || 0), 0),
    leave: schedule.filter(s => s.status === "ลา").length,
    absent: schedule.filter(s => s.status === "ขาด").length,
    holiday: schedule.filter(s => s.status === "วันหยุด").length,
    offsite: schedule.reduce((a, s) => a + (s.offsiteDays || 0), 0),
    lateMin: schedule.reduce((a, s) => a + (s.late || 0), 0)
  };

  return (
    <>
      <Card title="สร้างตารางเวลาทำงานรายช่วง" sub="เลือกพนักงานและช่วงวันที่ → ระบบสร้างตารางมาให้กรอก" right={<Btn size="sm" kind="ghost" icon={I.cog} onClick={() => setShowPolicy(true)}>ตั้งค่าเวลา & OT</Btn>}>
        <div className="field-row cols-4">
          <div className="field"><label>พนักงาน</label>
            <select className="input" value={empId} onChange={e=>setEmpId(e.target.value)}>
              {D.Employees.map(e => <option key={e.id} value={e.id}>{e.id} · {e.name}</option>)}
            </select>
          </div>
          <div className="field"><label>วันที่เริ่ม</label><input className="input" type="date" value={startDate} onChange={e=>setStartDate(e.target.value)}/></div>
          <div className="field"><label>วันที่สิ้นสุด</label><input className="input" type="date" value={endDate} onChange={e=>setEndDate(e.target.value)}/></div>
          <div className="field" style={{display: "flex", flexDirection: "column", justifyContent: "flex-end"}}><Btn kind="primary" icon={I.calc} onClick={generateSchedule}>สร้างตาราง</Btn></div>
        </div>
        <div style={{marginTop: 10, padding: "8px 12px", background: "var(--info-bg)", color: "var(--info)", borderRadius: 6, fontSize: 12.5, display: "flex", gap: 14, flexWrap: "wrap"}}>
          <span>⚙️ <b>นโยบาย:</b></span>
          <span>เข้า {policy.defaultIn} · ออก {policy.defaultOut}</span>
          <span>พัก {policy.breakStart}-{policy.breakEnd}</span>
          <span>เกิน {policy.standardHours} ชม. = OT (×{policy.otMultiplier})</span>
          <span>สาย: อนุโลม {policy.lateGraceMin} นาที · เกิน หัก ฿{policy.lateDeductPerMin}/นาที</span>
        </div>
      </Card>

      {schedule.length > 0 && (
        <>
          <div className="grid cols-4" style={{gap: 8, margin: "14px 0"}}>
            <div className="stat"><div className="label">วันทำงาน</div><div className="value">{summary.workDays} วัน</div></div>
            <div className="stat"><div className="label">ชม.ทำงานรวม</div><div className="value">{summary.totalWork.toFixed(1)} ชม.</div></div>
            <div className="stat"><div className="label">OT รวม · เป็นเงิน</div><div className="value" style={{fontSize: 16}}>{summary.otHours.toFixed(1)} ชม. <span style={{fontSize: 12, color: "var(--ink-3)"}}>(×{policy.otMultiplier})</span></div></div>
            <div className="stat"><div className="label">ลา / ขาด / หยุด</div><div className="value" style={{fontSize: 14}}>{summary.leave} / {summary.absent} / {summary.holiday}</div></div>
          </div>
          {(summary.offsite > 0 || summary.lateMin > 0) && (
            <div style={{padding: "8px 12px", background: "var(--info-bg)", color: "var(--info)", borderRadius: 6, fontSize: 13, marginBottom: 14, display: "flex", gap: 16, flexWrap: "wrap"}}>
              {summary.offsite > 0 && <span>🚗 <b>นอกสถานที่:</b> {summary.offsite} วัน</span>}
              {summary.lateMin > 0 && <span>⏰ <b>มาสายรวม:</b> {summary.lateMin} นาที · หัก ฿{(summary.lateMin * policy.lateDeductPerMin).toLocaleString()}</span>}
            </div>
          )}

          <Card flush title={`ตารางเวลา · ${emp?.name} · ${schedule.length} วัน`}
            right={<>
              <Btn size="sm" kind="ghost" onClick={() => setSchedule([])}>ล้างตาราง</Btn>
              <Btn size="sm" kind="primary" icon={I.check} onClick={saveSchedule}>บันทึกตาราง</Btn>
            </>}>
            <div className="table-wrap">
              <table className="t" style={{fontSize: 13}}>
                <thead>
                  <tr>
                    <th style={{width: 40}}>วัน</th>
                    <th style={{width: 110}}>วันที่</th>
                    <th style={{width: 160}}>สถานะ</th>
                    <th style={{width: 95}}>เข้างาน</th>
                    <th style={{width: 95}}>เลิกงาน</th>
                    <th className="right" style={{width: 72}}>พัก<div style={{fontSize: 9, fontWeight: 400, color: "var(--ink-4)"}}>(นาที)</div></th>
                    <th className="right" style={{width: 80}}>ชม.</th>
                    <th className="right" style={{width: 78}}>OT</th>
                    <th className="right" style={{width: 78}}>สาย<div style={{fontSize: 9, fontWeight: 400, color: "var(--ink-4)"}}>(นาที)</div></th>
                    <th className="right" style={{width: 90}}>นอกสถานที่<div style={{fontSize: 9, fontWeight: 400, color: "var(--ink-4)"}}>(วัน)</div></th>
                  </tr>
                </thead>
                <tbody>
                  {schedule.map((r, i) => {
                    const isWeekend = r.dow === 0 || r.dow === 6;
                    const isOffsite = r.status === "นอกสถานที่";
                    const noTime = r.status === "วันหยุด" || r.status === "ลา" || r.status === "ขาด" || r.status === "นอกสถานที่";
                    const cellStyle = { height: 32, padding: "0 8px", fontSize: 12 };
                    const numCellStyle = { ...cellStyle, textAlign: "right" };
                    return (
                      <tr key={i} style={{background: isWeekend ? "var(--surface-2)" : "transparent"}}>
                        <td style={{textAlign: "center", color: isWeekend ? "var(--danger)" : "var(--ink-3)", fontWeight: isWeekend ? 600 : 400}}>{dayNames[r.dow]}</td>
                        <td style={{fontSize: 12}}>{r.date}</td>
                        <td>
                          <select className="input" style={cellStyle} value={r.status} onChange={e=>onStatusChange(i, e.target.value)}>
                            {STATUSES.map(s => <option key={s.key} value={s.key}>{s.emoji} {s.key}</option>)}
                          </select>
                        </td>
                        <td><input className="input mono" type="time" style={cellStyle} disabled={noTime} value={r.in} onChange={e=>updateRow(i, { in: e.target.value })}/></td>
                        <td><input className="input mono" type="time" style={cellStyle} disabled={noTime} value={r.out} onChange={e=>updateRow(i, { out: e.target.value })}/></td>
                        <td><input className="input" type="number" style={numCellStyle} disabled={noTime} value={r.break} onChange={e=>updateRow(i, { break: +e.target.value })}/></td>
                        <td><input className="input" type="number" step="0.25" style={numCellStyle} disabled={noTime} value={r.work} onChange={e=>updateRow(i, { work: +e.target.value })}/></td>
                        <td><input className="input" type="number" step="0.25" style={{...numCellStyle, color: r.ot > 0 ? "var(--info)" : "inherit", fontWeight: r.ot > 0 ? 600 : 400}} disabled={noTime} value={r.ot} onChange={e=>updateRow(i, { ot: +e.target.value })}/></td>
                        <td><input className="input" type="number" style={{...numCellStyle, color: r.late > 0 ? "var(--danger)" : "inherit"}} disabled={noTime} value={r.late} onChange={e=>updateRow(i, { late: +e.target.value })}/></td>
                        <td>
                          {isOffsite ? (
                            <input className="input" type="number" step="0.5" min="0" style={numCellStyle}
                              value={r.offsiteDays || 1} onChange={e=>updateRow(i, { offsiteDays: +e.target.value })}/>
                          ) : <div style={{color: "var(--ink-4)", fontSize: 12, textAlign: "right", paddingRight: 8}}>—</div>}
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </Card>
        </>
      )}

      {schedule.length === 0 && (
        <Card title="ตารางเวลาที่บันทึกแล้ว" sub={`${timeRecs.length} รายการ`} flush>
          <div className="table-wrap">
            <table className="t">
              <thead><tr><th>วันที่</th><th>พนักงาน</th><th>สถานะ</th><th>เข้า</th><th>ออก</th><th className="right">ชม.</th><th className="right">OT</th><th className="right">สาย</th><th></th></tr></thead>
              <tbody>
                {timeRecs.slice(0, 30).map((t, i) => (
                  <tr key={i}>
                    <td>{t.date}</td>
                    <td>{t.name}</td>
                    <td><Badge>{t.status}</Badge></td>
                    <td className="mono">{t.in || "—"}</td>
                    <td className="mono">{t.out || "—"}</td>
                    <td className="right amount">{(t.work || 0).toFixed(1)}</td>
                    <td className="right amount">{t.ot > 0 ? t.ot.toFixed(1) : "—"}</td>
                    <td className="right amount" style={{color: t.late > 0 ? "var(--danger)" : "inherit"}}>{t.late > 0 ? t.late : "—"}</td>
                    <td><Btn size="sm" kind="ghost" icon={I.trash} onClick={async () => {
        const ok = await window.confirmDelete("ตารางเวลา " + t.date, t.name);
        if (!ok) return;
        setTimeRecs(timeRecs.filter((_, j) => j !== i));
        window.logActivity && window.logActivity("ลบ", "ตารางเวลา " + t.date + " ของ " + t.name, "delete");
      }}/></td>
                  </tr>
                ))}
                {timeRecs.length === 0 && <tr><td colSpan={9} style={{padding: 20, textAlign: "center", color: "var(--ink-3)"}}>ยังไม่มีตารางเวลา — สร้างตารางด้านบน</td></tr>}
              </tbody>
            </table>
          </div>
        </Card>
      )}

      {showPolicy && <PolicyModal policy={policy} setPolicy={setPolicy} onClose={() => setShowPolicy(false)}/>}
    </>
  );
}

function PolicyModal({ policy, setPolicy, onClose }) {
  const { Btn } = window.UI;
  const [f, setF] = useStateP2(policy);
  const upd = (k, v) => setF(p => ({ ...p, [k]: v }));
  return (
    <div className="scrim" style={{display:"flex",alignItems:"center",justifyContent:"center",padding:24,zIndex:200}} onClick={onClose}>
      <div style={{background: "var(--surface)", borderRadius: 12, padding: 20, width: 480, maxWidth: "94vw", boxShadow: "var(--shadow-lg)"}} onClick={e => e.stopPropagation()}>
        <div style={{fontSize: 15, fontWeight: 600, marginBottom: 4}}>⚙️ ตั้งค่าเวลาทำงาน & OT</div>
        <div style={{fontSize: 12, color: "var(--ink-3)", marginBottom: 16}}>ใช้เป็นค่า default เมื่อสร้างตารางใหม่ และคำนวน OT/มาสายอัตโนมัติ</div>

        <div style={{fontSize: 12, fontWeight: 600, color: "var(--ink-3)", textTransform: "uppercase", letterSpacing: "0.04em", marginBottom: 6}}>เวลาทำงานปกติ</div>
        <div className="field-row cols-2 mb">
          <div className="field"><label>เข้างาน</label><input className="input mono" type="time" value={f.defaultIn} onChange={e=>upd("defaultIn", e.target.value)}/></div>
          <div className="field"><label>เลิกงาน</label><input className="input mono" type="time" value={f.defaultOut} onChange={e=>upd("defaultOut", e.target.value)}/></div>
        </div>
        <div className="field-row cols-2 mb">
          <div className="field"><label>เริ่มพักเที่ยง</label><input className="input mono" type="time" value={f.breakStart} onChange={e=>upd("breakStart", e.target.value)}/></div>
          <div className="field"><label>เลิกพักเที่ยง</label><input className="input mono" type="time" value={f.breakEnd} onChange={e=>upd("breakEnd", e.target.value)}/></div>
        </div>

        <div style={{fontSize: 12, fontWeight: 600, color: "var(--ink-3)", textTransform: "uppercase", letterSpacing: "0.04em", marginTop: 16, marginBottom: 6}}>OT (ล่วงเวลา)</div>
        <div className="field-row cols-2 mb">
          <div className="field"><label>ชั่วโมงทำงานมาตรฐาน (ต่อวัน)</label><input className="input" type="number" min="1" max="12" value={f.standardHours} onChange={e=>upd("standardHours", +e.target.value)}/></div>
          <div className="field"><label>OT คูณค่าแรง (เท่า)</label><input className="input" type="number" min="1" step="0.25" value={f.otMultiplier} onChange={e=>upd("otMultiplier", +e.target.value)}/></div>
        </div>
        <div style={{padding: "8px 10px", background: "var(--surface-2)", borderRadius: 6, fontSize: 11.5, color: "var(--ink-3)"}}>
          💡 ทำงานเกิน <b>{f.standardHours} ชม./วัน</b> → ส่วนเกินคิดเป็น OT (×{f.otMultiplier})
        </div>

        <div style={{fontSize: 12, fontWeight: 600, color: "var(--ink-3)", textTransform: "uppercase", letterSpacing: "0.04em", marginTop: 16, marginBottom: 6}}>การมาสาย</div>
        <div className="field-row cols-2 mb">
          <div className="field"><label>อนุโลม (นาที)</label><input className="input" type="number" min="0" value={f.lateGraceMin} onChange={e=>upd("lateGraceMin", +e.target.value)}/></div>
          <div className="field"><label>หักนาทีละ (บาท)</label><input className="input" type="number" min="0" value={f.lateDeductPerMin} onChange={e=>upd("lateDeductPerMin", +e.target.value)}/></div>
        </div>
        <div style={{padding: "8px 10px", background: "var(--surface-2)", borderRadius: 6, fontSize: 11.5, color: "var(--ink-3)"}}>
          💡 มาสายไม่เกิน <b>{f.lateGraceMin} นาที</b> → ไม่หัก · เกินกว่านั้นหัก <b>฿{f.lateDeductPerMin}/นาที</b>
        </div>

        <div style={{display: "flex", gap: 8, justifyContent: "flex-end", marginTop: 18}}>
          <Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn>
          <Btn kind="primary" icon={I.check} onClick={() => { setPolicy(f); window.toast && window.toast("บันทึกการตั้งค่าแล้ว"); onClose(); }}>บันทึก</Btn>
        </div>
      </div>
    </div>
  );
}

function TimeAddModal({ onClose, onSave }) {
  const D = window.SSSData;
  const { Btn } = window.UI;
  const [f, setF] = useStateP2({ date: "22 พ.ค. 2569", emp: D.Employees[2]?.id, name: D.Employees[2]?.name, in: "08:00", out: "17:00", break: 60, work: 8, ot: 0, late: 0, status: "ปกติ" });
  const setEmp = (id) => {
    const e = D.Employees.find(emp => emp.id === id);
    setF(p => ({ ...p, emp: id, name: e?.name }));
  };
  return (
    <div className="scrim" style={{display:"flex",alignItems:"center",justifyContent:"center",padding:24,zIndex:200}} onClick={onClose}>
      <div style={{background: "var(--surface)", borderRadius: 12, padding: 18, width: 480, maxWidth: "92vw"}} onClick={e => e.stopPropagation()}>
        <div style={{fontSize: 15, fontWeight: 600, marginBottom: 14}}>บันทึกเวลาทำงาน</div>
        <div style={{display: "flex", flexDirection: "column", gap: 10}}>
          <div className="field-row cols-2">
            <div className="field"><label>วันที่</label><input className="input" value={f.date} onChange={e=>setF(p=>({...p, date: e.target.value}))}/></div>
            <div className="field"><label>พนักงาน</label>
              <select className="input" value={f.emp} onChange={e=>setEmp(e.target.value)}>
                {D.Employees.map(e => <option key={e.id} value={e.id}>{e.name}</option>)}
              </select>
            </div>
          </div>
          <div className="field-row cols-3">
            <div className="field"><label>เข้างาน</label><input className="input mono" value={f.in} onChange={e=>setF(p=>({...p, in: e.target.value}))}/></div>
            <div className="field"><label>เลิกงาน</label><input className="input mono" value={f.out} onChange={e=>setF(p=>({...p, out: e.target.value}))}/></div>
            <div className="field"><label>พัก (นาที)</label><input className="input" type="number" value={f.break} onChange={e=>setF(p=>({...p, break: +e.target.value}))}/></div>
          </div>
          <div className="field-row cols-3">
            <div className="field"><label>ชม.ทำงาน</label><input className="input" type="number" step="0.5" value={f.work} onChange={e=>setF(p=>({...p, work: +e.target.value}))}/></div>
            <div className="field"><label>OT (ชม.)</label><input className="input" type="number" step="0.5" value={f.ot} onChange={e=>setF(p=>({...p, ot: +e.target.value}))}/></div>
            <div className="field"><label>สาย (นาที)</label><input className="input" type="number" value={f.late} onChange={e=>setF(p=>({...p, late: +e.target.value, status: +e.target.value > 0 ? "สาย" : "ปกติ"}))}/></div>
          </div>
        </div>
        <div style={{display: "flex", gap: 8, justifyContent: "flex-end", marginTop: 16}}>
          <Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn>
          <Btn kind="primary" icon={I.check} onClick={() => onSave(f)}>บันทึก</Btn>
        </div>
      </div>
    </div>
  );
}

function AdvanceAddModal({ onClose, onSave }) {
  const D = window.SSSData;
  const { Btn } = window.UI;
  const [f, setF] = useStateP2({ empId: D.Employees[2]?.id, emp: D.Employees[2]?.name, reason: "", amount: 0 });
  const setEmp = (id) => { const e = D.Employees.find(emp => emp.id === id); setF(p => ({ ...p, empId: id, emp: e?.name })); };
  return (
    <div className="scrim" style={{display:"flex",alignItems:"center",justifyContent:"center",padding:24,zIndex:200}} onClick={onClose}>
      <div style={{background: "var(--surface)", borderRadius: 12, padding: 18, width: 440, maxWidth: "92vw"}} onClick={e => e.stopPropagation()}>
        <div style={{fontSize: 15, fontWeight: 600, marginBottom: 14}}>บันทึกการเบิกเงินล่วงหน้า</div>
        <div style={{display: "flex", flexDirection: "column", gap: 10}}>
          <div className="field"><label>พนักงาน</label>
            <select className="input" value={f.empId} onChange={e=>setEmp(e.target.value)}>
              {D.Employees.map(e => <option key={e.id} value={e.id}>{e.name}</option>)}
            </select>
          </div>
          <div className="field"><label>จำนวนเงิน (บาท)</label><input className="input" type="number" value={f.amount} onChange={e=>setF(p=>({...p, amount: +e.target.value}))}/></div>
          <div className="field"><label>เหตุผล</label><textarea className="textarea" value={f.reason} onChange={e=>setF(p=>({...p, reason: e.target.value}))} placeholder="เช่น ค่ารักษาพยาบาล, ค่าเทอมลูก…"/></div>
        </div>
        <div style={{display: "flex", gap: 8, justifyContent: "flex-end", marginTop: 16}}>
          <Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn>
          <Btn kind="primary" icon={I.check} onClick={() => { if(!f.amount||!f.reason){window.toast&&window.toast("กรอกข้อมูลให้ครบ");return;} onSave(f); }}>บันทึก</Btn>
        </div>
      </div>
    </div>
  );
}

function PaySlip({ row, period, payDate, calcDate, slogan, timeRecs, advances, month }) {
  const { fmtM, fmt0, bahtText } = window.UI;
  const D = window.SSSData;
  const C = D.Company;
  const emp = D.Employees.find(e => e.id === row.emp);
  const hourly = emp ? (emp.hourly || (emp.salary ? Math.round(emp.salary / 22 / 8) : 0)) : 0;
  // ใบแจ้งการทำงานรายวัน — ดึงจากลงเวลาเดือนนี้
  const isoOf = (t) => t.iso || (window.DocDates ? window.DocDates.toISO(t.date) : "") || "";
  const dayLog = (timeRecs || []).filter(t => t.emp === row.emp && isoOf(t).startsWith(month || ""))
    .sort((a, b) => isoOf(a).localeCompare(isoOf(b)))
    .map(t => {
      const earn = Math.round((t.work || 0) * hourly + (t.ot || 0) * (emp?.otRate || 0));
      const advToday = (advances || []).filter(a => a.empId === row.emp && (a.date === t.date)).reduce((s, a) => s + a.amount, 0);
      return { ...t, earn, advToday };
    });
  const logEarnTotal = dayLog.reduce((s, d) => s + d.earn, 0);
  const logAdvTotal = dayLog.reduce((s, d) => s + d.advToday, 0);
  return (
    <div className="doc-paper" style={{padding: 30}}>
      <div style={{display: "flex", justifyContent: "space-between", marginBottom: 16, borderBottom: "1px solid #e7e5e4", paddingBottom: 12}}>
        <div>
          <div style={{display: "flex", alignItems: "center", gap: 10}}>
            <div style={{width: 36, height: 36, background: "#0c0a09", color: "white", display: "grid", placeItems: "center", fontWeight: 700, borderRadius: 5}}>SSS</div>
            <div>
              <div style={{fontWeight: 600, fontSize: 13}}>{C.name}</div>
              <div style={{fontSize: 10.5, color: "#78716c"}}>เลขผู้เสียภาษี {C.taxId}</div>
            </div>
          </div>
        </div>
        <div style={{textAlign: "right"}}>
          <h1 style={{fontSize: 18}}>ใบจ่ายเงินเดือน</h1>
          <div style={{fontSize: 11, color: "#57534e"}}>PAY SLIP · งวด {period || "พ.ค. 2569"}</div>
          {calcDate && <div style={{fontSize: 10, color: "#78716c", marginTop: 2}}>คำนวนเมื่อ {calcDate}</div>}
        </div>
      </div>

      <div className="field-row cols-2" style={{marginBottom: 14}}>
        <div><div style={{fontSize: 10, color: "#78716c"}}>พนักงาน</div><div style={{fontWeight: 600}}>{emp?.name}</div></div>
        <div><div style={{fontSize: 10, color: "#78716c"}}>รหัส / แผนก</div><div>{emp?.id} · {emp?.dept}</div></div>
        <div><div style={{fontSize: 10, color: "#78716c"}}>ตำแหน่ง</div><div>{emp?.role}</div></div>
        <div><div style={{fontSize: 10, color: "#78716c"}}>วันจ่าย</div><div>{payDate || "—"}</div></div>
        <div><div style={{fontSize: 10, color: "#78716c"}}>วันที่คำนวน</div><div>{calcDate || "—"}</div></div>
      </div>

      <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, marginBottom: 16}}>
        <div>
          <div style={{fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.05em", color: "#44403c", marginBottom: 6}}>รายได้</div>
          <table style={{width: "100%", fontSize: 12}}>
            <tbody>
              <tr><td style={{padding: "4px 0"}}>เงินเดือน/ค่าจ้างรายชั่วโมง</td><td style={{textAlign: "right"}}>{fmtM(row.base > 0 ? row.base : row.hours * (emp?.hourly || 0))}</td></tr>
              <tr><td style={{padding: "4px 0"}}>OT ({row.otHours} ชม. × {emp?.otRate})</td><td style={{textAlign: "right"}}>{fmtM(row.otHours * (emp?.otRate || 0))}</td></tr>
              <tr style={{borderTop: "1px solid #e7e5e4", fontWeight: 600}}><td style={{padding: "6px 0"}}>รวมรายได้</td><td style={{textAlign: "right"}}>{fmtM(row.gross)}</td></tr>
            </tbody>
          </table>
        </div>
        <div>
          <div style={{fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.05em", color: "#44403c", marginBottom: 6}}>รายการหัก</div>
          <table style={{width: "100%", fontSize: 12}}>
            <tbody>
              <tr><td style={{padding: "4px 0"}}>เงินสมทบประกันสังคม 5%</td><td style={{textAlign: "right"}}>−{fmtM(row.sso)}</td></tr>
              <tr><td style={{padding: "4px 0"}}>หัก ณ ที่จ่าย (ภ.ง.ด.1)</td><td style={{textAlign: "right"}}>{row.tax > 0 ? `−${fmtM(row.tax)}` : "—"}</td></tr>
              <tr><td style={{padding: "4px 0"}}>เบิกเงินล่วงหน้า</td><td style={{textAlign: "right"}}>{row.advance > 0 ? `−${fmtM(row.advance)}` : "—"}</td></tr>
              <tr><td style={{padding: "4px 0"}}>หักมาสาย/ขาดงาน</td><td style={{textAlign: "right"}}>{row.late > 0 ? `−${fmtM(row.late)}` : "—"}</td></tr>
              <tr style={{borderTop: "1px solid #e7e5e4", fontWeight: 600}}><td style={{padding: "6px 0"}}>รวมรายการหัก</td><td style={{textAlign: "right"}}>−{fmtM(row.sso + row.tax + row.advance + row.late)}</td></tr>
            </tbody>
          </table>
        </div>
      </div>

      <div style={{borderTop: "2px solid #0c0a09", padding: "12px 0", display: "flex", justifyContent: "space-between", alignItems: "center"}}>
        <div>
          <div style={{fontSize: 11, color: "#78716c"}}>ยอดสุทธิจ่าย (โอนเข้าบัญชี)</div>
          <div style={{fontSize: 11, color: "#57534e", fontStyle: "italic"}}>({bahtText(row.net)})</div>
        </div>
        <div style={{fontSize: 22, fontWeight: 600}}>฿{fmtM(row.net)}</div>
      </div>

      <div style={{marginTop: 12, padding: 10, background: "#f7f6f4", fontSize: 11, color: "#57534e", borderRadius: 4}}>
        <b>หมายเหตุ:</b> นายจ้างสมทบประกันสังคมเพิ่มอีก ฿{fmtM(row.sso)} (5%) เข้ากองทุน · เอกสารฉบับนี้เป็นข้อมูลส่วนตัวของพนักงาน
      </div>

      <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 40, marginTop: 40, fontSize: 11}}>
        <div style={{textAlign: "center"}}><div style={{borderTop: "1px solid #44403c", paddingTop: 4, marginTop: 30}}>ผู้จ่าย · วันเพ็ญ สุขใจ</div></div>
        <div style={{textAlign: "center"}}><div style={{borderTop: "1px solid #44403c", paddingTop: 4, marginTop: 30}}>ผู้รับ · {emp?.name}</div></div>
      </div>

      {slogan && (
        <div style={{marginTop: 16, padding: "12px 16px", background: "#0c0a09", color: "white", borderRadius: 6, textAlign: "center", fontSize: 13, fontWeight: 600, letterSpacing: "0.01em"}}>
          "{slogan}"
        </div>
      )}

      {/* ──── แผ่นที่ 2: ใบแจ้งการทำงานรายวัน (สำหรับพนักงาน + ผู้จ่ายเงินตรวจ) ──── */}
      <div style={{pageBreakBefore: "always", breakBefore: "page", marginTop: 30, paddingTop: 18, borderTop: "2px dashed #d6d3d1"}}>
        <div style={{display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 10}}>
          <div>
            <h2 style={{fontSize: 16, margin: 0}}>ใบแจ้งการทำงานรายวัน</h2>
            <div style={{fontSize: 11, color: "#78716c"}}>DAILY WORK LOG · สำหรับแจ้งพนักงาน และให้ผู้จ่ายเงินตรวจสอบ</div>
          </div>
          <div style={{textAlign: "right", fontSize: 11}}><div><b>{emp?.name}</b> · {emp?.id}</div><div style={{color: "#78716c"}}>งวด {period} · ค่าแรง ฿{fmt0(hourly)}/ชม.</div></div>
        </div>
        {dayLog.length === 0 ? (
          <div style={{padding: 24, textAlign: "center", color: "#78716c", fontSize: 12, border: "1px dashed #d6d3d1", borderRadius: 6}}>ยังไม่มีข้อมูลลงเวลารายวันของเดือนนี้ — ไปที่แท็บ "ลงเวลา / OT" หรือดึงจาก QR</div>
        ) : (
          <table style={{width: "100%", borderCollapse: "collapse", fontSize: 11.5}}>
            <thead><tr style={{background: "#f5f5f4"}}>
              <th style={{textAlign: "left", padding: "6px 8px", borderBottom: "2px solid #0c0a09"}}>วันที่</th>
              <th style={{textAlign: "left", padding: "6px 8px", borderBottom: "2px solid #0c0a09"}}>สถานะ</th>
              <th style={{textAlign: "center", padding: "6px 8px", borderBottom: "2px solid #0c0a09"}}>เข้า</th>
              <th style={{textAlign: "center", padding: "6px 8px", borderBottom: "2px solid #0c0a09"}}>ออก</th>
              <th style={{textAlign: "right", padding: "6px 8px", borderBottom: "2px solid #0c0a09"}}>ชม.</th>
              <th style={{textAlign: "right", padding: "6px 8px", borderBottom: "2px solid #0c0a09"}}>OT</th>
              <th style={{textAlign: "right", padding: "6px 8px", borderBottom: "2px solid #0c0a09"}}>ค่าแรงวันนี้</th>
              <th style={{textAlign: "right", padding: "6px 8px", borderBottom: "2px solid #0c0a09"}}>เบิก</th>
            </tr></thead>
            <tbody>
              {dayLog.map((d, i) => (
                <tr key={i} style={{borderBottom: "1px solid #eceae7"}}>
                  <td style={{padding: "5px 8px"}}>{d.date}</td>
                  <td style={{padding: "5px 8px"}}>{d.status}</td>
                  <td style={{padding: "5px 8px", textAlign: "center", fontFamily: "monospace"}}>{d.in || "—"}</td>
                  <td style={{padding: "5px 8px", textAlign: "center", fontFamily: "monospace"}}>{d.out || "—"}</td>
                  <td style={{padding: "5px 8px", textAlign: "right"}}>{(d.work || 0).toFixed(1)}</td>
                  <td style={{padding: "5px 8px", textAlign: "right"}}>{d.ot > 0 ? d.ot.toFixed(1) : "—"}</td>
                  <td style={{padding: "5px 8px", textAlign: "right"}}>฿{fmt0(d.earn)}</td>
                  <td style={{padding: "5px 8px", textAlign: "right", color: d.advToday > 0 ? "#b45309" : "#a8a29e"}}>{d.advToday > 0 ? `−฿${fmt0(d.advToday)}` : "—"}</td>
                </tr>
              ))}
              <tr style={{fontWeight: 700, background: "#fafaf9"}}>
                <td style={{padding: "7px 8px"}} colSpan={6}>รวมค่าแรงตามวันทำงาน ({dayLog.length} วัน)</td>
                <td style={{padding: "7px 8px", textAlign: "right"}}>฿{fmt0(logEarnTotal)}</td>
                <td style={{padding: "7px 8px", textAlign: "right", color: "#b45309"}}>{logAdvTotal > 0 ? `−฿${fmt0(logAdvTotal)}` : "—"}</td>
              </tr>
            </tbody>
          </table>
        )}
        <div style={{marginTop: 10, padding: "8px 12px", background: "#f7f6f4", fontSize: 10.5, color: "#57534e", borderRadius: 4, lineHeight: 1.7}}>
          "ค่าแรงวันนี้" คิดจากชั่วโมงทำงาน×ค่าแรงรายชั่วโมง + OT · ยอดเบิกระหว่างงวดจะถูกหักออกตอนคิดเงินเดือนสุทธิ
        </div>
        <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 40, marginTop: 28, fontSize: 11}}>
          <div style={{textAlign: "center"}}><div style={{borderTop: "1px dashed #57534e", paddingTop: 4, marginTop: 26}}>ผู้จ่ายเงินตรวจสอบ<br/>วันที่ ............................</div></div>
          <div style={{textAlign: "center"}}><div style={{borderTop: "1px dashed #57534e", paddingTop: 4, marginTop: 26}}>พนักงานรับทราบ ({emp?.name})<br/>วันที่ ............................</div></div>
        </div>
      </div>
    </div>
  );
}

window.Payroll = Payroll;
window.PayrollPolicyModal = PolicyModal;
