/* global React, I, UI, SSSData, SSSAccounting, XLSX */
const { useState: useStatePP, useMemo: useMemoPP } = React;

// ============================================================
//  ลงบัญชีเงินเดือน → สมุดรายวันจ่ายเงิน (Payroll → Journal)
//  สูตรการคำนวณอ้างอิงจาก payroll-calculator (server/api.test.ts):
//   • OT (รายเดือน) = (ฐาน/30/8) × 1.5 ;  OT (รายวัน) = (ฐาน/8) × 1.5
//   • ฐานรายวัน = ชั่วโมงทำงาน × (ฐาน/8)
//   • รายได้รวม = ฐาน + OT + OT นอกสถานที่
//   • ประกันสังคม = 5% ของฐาน (เพดานเงินเดือน 15,000 → สูงสุด 750)
//   • สุทธิ = รายได้รวม − ประกันสังคม − ภาษีหัก ณ ที่จ่าย − มาสาย
// ============================================================

const SSO_RATE = 0.05;
const SSO_SALARY_CAP = 15000;       // เพดานฐานคำนวณ
const SSO_MAX = SSO_SALARY_CAP * SSO_RATE; // 750
const OT_MULTIPLIER = 1.5;
const DAILY_WORK_DAYS = 26;         // สำหรับประมาณฐานประกันสังคมรายวัน

// พนักงานงวด พ.ค. 2569 — direct = ค่าจ้างทางตรง(โรงงาน) 5120, office = เงินเดือนสำนักงาน 5210
const PAYROLL_EMPLOYEES = [
  { id: "EMP-005", name: "นันทพร กิตติศักดิ์", role: "ผจก.ฝ่ายขาย", cls: "office", payType: "monthly", base: 45000, regHours: 0, otHours: 0, otOutside: 0, wht: 1250, late: 0, sso: true },
  { id: "EMP-009", name: "วิทยา ใจดี", role: "หัวหน้าช่าง", cls: "direct", payType: "monthly", base: 38000, regHours: 0, otHours: 12, otOutside: 0, wht: 925, late: 0, sso: true },
  { id: "EMP-018", name: "ภาณุพงศ์ วงศ์ไทย", role: "เขียนแบบ/3D", cls: "office", payType: "monthly", base: 32000, regHours: 0, otHours: 6, otOutside: 0, wht: 480, late: 0, sso: true },
  { id: "EMP-021", name: "ดวงใจ บุญมี", role: "คลังสินค้า", cls: "office", payType: "monthly", base: 18000, regHours: 0, otHours: 0, otOutside: 0, wht: 0, late: 120, sso: true },
  { id: "EMP-014", name: "สมศักดิ์ ทองคำ", role: "ช่างเชื่อม", cls: "direct", payType: "daily", base: 600, regHours: 208, otHours: 10, otOutside: 0, wht: 0, late: 0, sso: true },
  { id: "EMP-024", name: "สุชาติ ขยันงาน", role: "ช่างทั่วไป", cls: "direct", payType: "daily", base: 550, regHours: 208, otHours: 8, otOutside: 1500, wht: 0, late: 0, sso: true }
];

function calcEmployee(e) {
  let baseEarn, otRate;
  if (e.payType === "monthly") {
    baseEarn = e.base;
    otRate = (e.base / 30 / 8) * OT_MULTIPLIER;
  } else {
    const hourly = e.base / 8;
    baseEarn = e.regHours * hourly;
    otRate = hourly * OT_MULTIPLIER;
  }
  const otPay = e.otHours * otRate;
  const gross = baseEarn + otPay + (e.otOutside || 0);

  // ฐานประกันสังคม: รายเดือนใช้เงินเดือน, รายวันใช้ค่าจ้าง × วันทำงานโดยประมาณ
  const ssoBase = e.payType === "monthly" ? e.base : e.base * DAILY_WORK_DAYS;
  const ssoEmp = e.sso ? Math.round(Math.min(ssoBase, SSO_SALARY_CAP) * SSO_RATE) : 0;
  const ssoEr = ssoEmp; // นายจ้างสมทบเท่าลูกจ้าง
  const wht = e.wht || 0;
  const late = e.late || 0;
  const net = gross - ssoEmp - wht - late;

  return { ...e, baseEarn, otPay, gross, ssoEmp, ssoEr, wht, late, net };
}

function PayrollPosting() {
  const { Card, Btn } = window.UI;
  const A = window.SSSAccounting;
  const rows = useMemoPP(() => PAYROLL_EMPLOYEES.map(calcEmployee), []);

  const sum = (k) => rows.reduce((s, r) => s + r[k], 0);
  const totals = {
    base: sum("baseEarn"), ot: sum("otPay"), otOut: rows.reduce((s, r) => s + (r.otOutside || 0), 0),
    gross: sum("gross"), ssoEmp: sum("ssoEmp"), ssoEr: sum("ssoEr"),
    wht: sum("wht"), late: sum("late"), net: sum("net")
  };
  const directGross = rows.filter(r => r.cls === "direct").reduce((s, r) => s + r.gross, 0);
  const officeGross = rows.filter(r => r.cls === "office").reduce((s, r) => s + r.gross, 0);

  // สร้าง JV (CP) — รายการจ่ายเงินเดือนปิดงวด
  const jv = [
    { acc: "5120", name: "ค่าจ้างทางตรง (โรงงาน)", dr: directGross, cr: 0 },
    { acc: "5210", name: "เงินเดือนพนักงานสำนักงาน", dr: officeGross, cr: 0 },
    { acc: "5215", name: "เงินสมทบประกันสังคม (นายจ้าง)", dr: totals.ssoEr, cr: 0 },
    { acc: "2131", name: "ภาษีหัก ณ ที่จ่าย ภ.ง.ด.1", dr: 0, cr: totals.wht },
    { acc: "2140", name: "ประกันสังคมค้างนำส่ง (ลูกจ้าง+นายจ้าง)", dr: 0, cr: totals.ssoEmp + totals.ssoEr },
    { acc: "1121", name: "เงินฝากธนาคาร – จ่ายเงินเดือนสุทธิ", dr: 0, cr: totals.net + totals.late }
  ];
  // หมายเหตุ: มาสายถือเป็นรายได้อื่น/ลดค่าใช้จ่าย — เครดิตคืนผ่านยอดสุทธิให้สมดุล
  const totDr = jv.reduce((s, l) => s + l.dr, 0);
  const totCr = jv.reduce((s, l) => s + l.cr, 0);
  const balanced = Math.abs(totDr - totCr) < 1;

  const exportExcel = () => {
    const aoa = [
      ["บริษัท ทริปเปิ้ลเอส ครีเอทีฟ จำกัด"],
      ["สรุปการจ่ายเงินเดือน — งวดพฤษภาคม 2569"],
      ["คำนวณตามสูตร payroll-calculator · ประกันสังคม 5% เพดาน 750 · OT ×1.5"],
      [],
      ["รหัส", "ชื่อ", "ตำแหน่ง", "ประเภท", "ฐาน/เงินเดือน", "OT", "OT นอกสถานที่", "รายได้รวม", "ปกส.(ลูกจ้าง)", "ภ.ง.ด.1", "มาสาย", "เงินสุทธิ"]
    ];
    rows.forEach(r => aoa.push([r.id, r.name, r.role, r.payType === "monthly" ? "รายเดือน" : "รายวัน",
      round2(r.baseEarn), round2(r.otPay), round2(r.otOutside || 0), round2(r.gross), r.ssoEmp, r.wht, r.late, round2(r.net)]));
    aoa.push(["", "รวม", "", "", round2(totals.base), round2(totals.ot), round2(totals.otOut), round2(totals.gross), totals.ssoEmp, totals.wht, totals.late, round2(totals.net)]);
    aoa.push([]);
    aoa.push(["การบันทึกบัญชี (สมุดรายวันจ่ายเงิน)", "", "", "เดบิต", "เครดิต"]);
    jv.forEach(l => aoa.push([l.acc, l.name, "", l.dr || "", l.cr || ""]));
    window.exportAOAExcel ? window.exportAOAExcel(aoa, "เงินเดือน 2569-05", "เงินเดือน_บันทึกบัญชี_2569-05.xlsx") : null;
  };

  const post = () => {
    window.toast && window.toast(`ลงบัญชีเงินเดือนงวด พ.ค. 2569 — JV CP69-0069 (Dr/Cr ฿${round2(totDr).toLocaleString()})`);
  };

  return (
    <div style={{display: "flex", flexDirection: "column", gap: 14}}>
      {/* Source note */}
      <div style={{padding: "10px 14px", background: "var(--info-bg)", border: "1px solid var(--info)",
        borderRadius: "var(--radius-sm)", fontSize: 12, color: "var(--ink-2)", display: "flex", gap: 10, alignItems: "flex-start"}}>
        <I.payroll size={14} stroke="var(--info)" style={{flexShrink: 0, marginTop: 2}}/>
        <div>
          คำนวณเงินเดือนตามสูตรจากระบบ <b>payroll-calculator</b> — ประกันสังคม 5% (เพดานเงินเดือน 15,000 = สูงสุด 750/เดือน),
          OT รายเดือน (ฐาน/30/8)×1.5, รายวัน (ฐาน/8)×1.5, รวม OT นอกสถานที่ แล้วสร้างรายการบันทึกบัญชีเข้า <b>สมุดรายวันจ่ายเงิน</b> อัตโนมัติ
        </div>
      </div>

      {/* Summary tiles */}
      <div className="grid" style={{gridTemplateColumns: "repeat(4, 1fr)", gap: 10}}>
        <PPTile label="รายได้รวม (Gross)" value={totals.gross} accent="var(--ink-1)"/>
        <PPTile label="ประกันสังคม (ลูกจ้าง+นายจ้าง)" value={totals.ssoEmp + totals.ssoEr} accent="oklch(55% 0.10 230)"/>
        <PPTile label="ภาษีหัก ณ ที่จ่าย ภ.ง.ด.1" value={totals.wht} accent="oklch(64% 0.13 70)"/>
        <PPTile label="จ่ายสุทธิ (โอนธนาคาร)" value={totals.net} accent="oklch(60% 0.10 150)"/>
      </div>

      {/* Employee calc table */}
      <Card title="รายละเอียดการคำนวณรายบุคคล" sub={`${rows.length} คน · งวดพฤษภาคม 2569`} flush
        right={<Btn size="sm" kind="ghost" icon={I.download} onClick={exportExcel}>ส่งออก Excel</Btn>}>
        <div className="table-wrap">
          <table className="t">
            <thead>
              <tr>
                <th>พนักงาน</th>
                <th style={{width: 78}}>ประเภท</th>
                <th className="right" style={{width: 104}}>ฐาน/เงินเดือน</th>
                <th className="right" style={{width: 90}}>OT</th>
                <th className="right" style={{width: 96}}>OT นอกฯ</th>
                <th className="right" style={{width: 104}}>รายได้รวม</th>
                <th className="right" style={{width: 90}}>ปกส.</th>
                <th className="right" style={{width: 84}}>ภ.ง.ด.1</th>
                <th className="right" style={{width: 78}}>มาสาย</th>
                <th className="right" style={{width: 110}}>สุทธิ</th>
              </tr>
            </thead>
            <tbody>
              {rows.map(r => (
                <tr key={r.id}>
                  <td>
                    <div style={{fontSize: 13}}>{r.name}</div>
                    <div style={{fontSize: 11, color: "var(--ink-3)"}}>
                      <span className="mono">{r.id}</span> · {r.role}
                      <span style={{marginLeft: 6, padding: "1px 6px", borderRadius: 3, fontSize: 10,
                        background: r.cls === "direct" ? "var(--surface-3)" : "var(--surface-2)", color: "var(--ink-3)"}}>
                        {r.cls === "direct" ? "ทางตรง→5120" : "สำนักงาน→5210"}
                      </span>
                    </div>
                  </td>
                  <td style={{fontSize: 12, color: "var(--ink-3)"}}>{r.payType === "monthly" ? "รายเดือน" : "รายวัน"}</td>
                  <td className="right amount">{fmtPP(r.baseEarn)}</td>
                  <td className="right amount" style={{color: r.otPay ? "var(--ink-1)" : "var(--ink-4)"}}>{r.otPay ? fmtPP(r.otPay) : "–"}</td>
                  <td className="right amount" style={{color: r.otOutside ? "var(--ink-1)" : "var(--ink-4)"}}>{r.otOutside ? fmtPP(r.otOutside) : "–"}</td>
                  <td className="right amount" style={{fontWeight: 600}}>{fmtPP(r.gross)}</td>
                  <td className="right amount" style={{color: "var(--ink-3)"}}>{r.ssoEmp ? `−${fmtPP(r.ssoEmp)}` : "–"}</td>
                  <td className="right amount" style={{color: "var(--ink-3)"}}>{r.wht ? `−${fmtPP(r.wht)}` : "–"}</td>
                  <td className="right amount" style={{color: "var(--ink-3)"}}>{r.late ? `−${fmtPP(r.late)}` : "–"}</td>
                  <td className="right amount" style={{fontWeight: 600}}>{fmtPP(r.net)}</td>
                </tr>
              ))}
            </tbody>
            <tfoot>
              <tr style={{borderTop: "2px solid var(--ink-1)", background: "var(--surface-2)", fontWeight: 600}}>
                <td colSpan="2" style={{padding: "12px 14px"}}>รวมทั้งสิ้น ({rows.length} คน)</td>
                <td className="right amount" style={{padding: "12px 8px"}}>{fmtPP(totals.base)}</td>
                <td className="right amount" style={{padding: "12px 8px"}}>{fmtPP(totals.ot)}</td>
                <td className="right amount" style={{padding: "12px 8px"}}>{fmtPP(totals.otOut)}</td>
                <td className="right amount" style={{padding: "12px 8px"}}>{fmtPP(totals.gross)}</td>
                <td className="right amount" style={{padding: "12px 8px"}}>−{fmtPP(totals.ssoEmp)}</td>
                <td className="right amount" style={{padding: "12px 8px"}}>−{fmtPP(totals.wht)}</td>
                <td className="right amount" style={{padding: "12px 8px"}}>−{fmtPP(totals.late)}</td>
                <td className="right amount" style={{padding: "12px 8px"}}>{fmtPP(totals.net)}</td>
              </tr>
            </tfoot>
          </table>
        </div>
      </Card>

      {/* Generated JV */}
      <Card title="รายการบันทึกบัญชีที่จะสร้าง" sub="สมุดรายวันจ่ายเงิน (CP) · ปิดงวดเงินเดือน" flush>
        <div className="table-wrap">
          <table className="t">
            <thead>
              <tr>
                <th style={{width: 80}}>รหัส</th>
                <th>ชื่อบัญชี</th>
                <th className="right" style={{width: 140}}>เดบิต</th>
                <th className="right" style={{width: 140}}>เครดิต</th>
              </tr>
            </thead>
            <tbody>
              {jv.map((l, i) => (
                <tr key={i}>
                  <td className="mono" style={{fontSize: 12, color: "var(--ink-3)", paddingLeft: l.cr > 0 ? 28 : 14}}>{l.acc}</td>
                  <td style={{paddingLeft: l.cr > 0 ? 20 : 0}}>{l.name}</td>
                  <td className="right amount">{l.dr ? fmtPP(l.dr) : ""}</td>
                  <td className="right amount">{l.cr ? fmtPP(l.cr) : ""}</td>
                </tr>
              ))}
            </tbody>
            <tfoot>
              <tr style={{borderTop: "2px solid var(--ink-1)", background: balanced ? "var(--success-bg)" : "var(--warning-bg)", fontWeight: 600}}>
                <td colSpan="2" style={{padding: "12px 14px", color: balanced ? "var(--success)" : "var(--warning)"}}>
                  {balanced ? <><I.check size={12}/> สมดุล Dr = Cr</> : "⚠ ไม่สมดุล"}
                </td>
                <td className="right amount" style={{padding: "12px 8px"}}>{fmtPP(totDr)}</td>
                <td className="right amount" style={{padding: "12px 8px"}}>{fmtPP(totCr)}</td>
              </tr>
            </tfoot>
          </table>
        </div>
        <div style={{display: "flex", gap: 8, padding: "12px 14px", borderTop: "1px solid var(--line)", alignItems: "center"}}>
          <div style={{flex: 1, fontSize: 11.5, color: "var(--ink-3)"}}>
            เงินเบิกล่วงหน้า (advance) จัดการผ่านใบเบิกแยกต่างหากตามระบบ payroll-calculator — ไม่รวมในรายการปิดงวดนี้
          </div>
          <Btn kind="ghost" icon={I.download} onClick={exportExcel}>ส่งออก Excel</Btn>
          <Btn kind="primary" icon={I.check} onClick={post} disabled={!balanced}>ลงบัญชีเข้าสมุดรายวัน</Btn>
        </div>
      </Card>
    </div>
  );
}

function PPTile({ label, value, accent }) {
  return (
    <div style={{padding: 14, background: "var(--surface)", border: "1px solid var(--line)",
      borderRadius: "var(--radius)", borderLeft: `3px solid ${accent}`}}>
      <div style={{fontSize: 11.5, color: "var(--ink-3)"}}>{label}</div>
      <div className="amount" style={{fontSize: 21, fontWeight: 600, marginTop: 6}}>฿{fmtPP(value)}</div>
    </div>
  );
}

const fmtPP = (n) => (n || 0).toLocaleString("th-TH", { minimumFractionDigits: 0, maximumFractionDigits: 0 });
const round2 = (n) => Math.round((n || 0) * 100) / 100;

window.PayrollPosting = PayrollPosting;
