/* global React, I, UI, SSSData */
const { useState: useStateMisc } = React;

// Load saved company overrides into shared data on first import
(function () {
  try {
    const saved = JSON.parse(localStorage.getItem("sss-company") || "null");
    if (saved && window.SSSData && window.SSSData.Company) {
      // ล้าง override ชื่อบริษัทเดิม (SSS Metal / สแตนเลส สามพราน) — ใช้ชื่อใหม่จากระบบ
      if (saved.name && /สแตนเลส|สามพราน|SSS Metal|Stainless|Metal/i.test(saved.name)) {
        ["name", "nameEn", "shortName", "email", "website"].forEach(k => delete saved[k]);
        try { localStorage.setItem("sss-company", JSON.stringify(saved)); } catch {}
      }
      Object.assign(window.SSSData.Company, saved);
    }
  } catch {}
})();

// ============ Company settings (controlled + persisted) ============
function CompanySettings() {
  const D = window.SSSData;
  const { Btn, Card } = window.UI;
  const FIELDS = ["name", "nameEn", "shortName", "tagline", "logoText", "taxId", "address", "phone", "email", "bank"];
  const snapshot = () => { const o = {}; FIELDS.forEach(k => o[k] = D.Company[k] || ""); return o; };
  const [f, setF] = useStateMisc(snapshot);
  const [saved, setSaved] = useStateMisc(snapshot);
  const upd = (k, v) => setF(p => ({ ...p, [k]: v }));
  const dirty = FIELDS.some(k => f[k] !== saved[k]);

  const doSave = () => {
    if (!f.name.trim()) { window.toast && window.toast("กรอกชื่อบริษัทก่อน"); return; }
    Object.assign(D.Company, f);
    try { localStorage.setItem("sss-company", JSON.stringify(f)); } catch {}
    setSaved({ ...f });
    window.dispatchEvent(new Event("sss-company-changed"));
    window.logActivity && window.logActivity("แก้ไขข้อมูลบริษัท", f.name, "update");
    window.toast && window.toast("บันทึกข้อมูลบริษัทแล้ว");
  };
  const reset = () => setF({ ...saved });

  return (
    <div className="grid cols-2">
      <Card title="ข้อมูลบริษัท" right={<div style={{display: "flex", gap: 6}}>{dirty && <Btn size="sm" kind="ghost" onClick={reset}>ยกเลิก</Btn>}<Btn size="sm" kind="primary" icon={I.check} onClick={doSave} disabled={!dirty}>{dirty ? "บันทึก" : "บันทึกแล้ว"}</Btn></div>}>
        <div style={{display: "flex", flexDirection: "column", gap: 12}}>
          <div className="field"><label>ชื่อบริษัท (ภาษาไทย)</label><input className="input" value={f.name} onChange={e => upd("name", e.target.value)}/></div>
          <div className="field"><label>ชื่อบริษัท (English)</label><input className="input" value={f.nameEn} onChange={e => upd("nameEn", e.target.value)}/></div>
          <div className="field-row cols-2">
            <div className="field"><label>ชื่อย่อ (แสดงบนแถบเมนู)</label><input className="input" value={f.shortName} onChange={e => upd("shortName", e.target.value)} placeholder="เช่น SSS Metal"/></div>
            <div className="field"><label>โลโก้ (ตัวอักษรย่อ 1-3 ตัว)</label><input className="input" maxLength={3} value={f.logoText} onChange={e => upd("logoText", e.target.value)} placeholder="SSS"/></div>
          </div>
          <div className="field"><label>คำโปรย (ใต้ชื่อย่อ)</label><input className="input" value={f.tagline} onChange={e => upd("tagline", e.target.value)} placeholder="โปรแกรมบริหารจัดการ"/></div>
          <div className="field"><label>เลขประจำตัวผู้เสียภาษี</label><input className="input mono" value={f.taxId} onChange={e => upd("taxId", e.target.value)}/></div>
          <div className="field"><label>ที่อยู่</label><textarea className="textarea" value={f.address} onChange={e => upd("address", e.target.value)}/></div>
          <div className="field-row cols-2">
            <div className="field"><label>โทรศัพท์</label><input className="input" value={f.phone} onChange={e => upd("phone", e.target.value)}/></div>
            <div className="field"><label>อีเมล</label><input className="input" value={f.email} onChange={e => upd("email", e.target.value)}/></div>
          </div>
          <div className="field"><label>ข้อมูลธนาคาร (พิมพ์บนใบแจ้งหนี้)</label><input className="input" value={f.bank} onChange={e => upd("bank", e.target.value)}/></div>
        </div>
      </Card>

      <Card title="โลโก้และหัวบิล" right={<Btn size="sm" onClick={() => window.toast && window.toast("ลากไฟล์โลโก้มาวางในกรอบด้านล่างเพื่ออัปโหลด")}>อัปโหลดโลโก้ใหม่</Btn>}>
        <div className="label mb">โลโก้บริษัท</div>
        <div style={{display: "flex", gap: 14, alignItems: "center", marginBottom: 18}}>
          <div style={{width: 80, height: 80, background: "var(--accent)", color: "var(--accent-ink)", display: "grid", placeItems: "center", fontWeight: 700, fontSize: 22, borderRadius: 8, letterSpacing: 1.5}}>SSS</div>
          <div className="attach-dropzone" style={{flex: 1}}>ลากไฟล์โลโก้มาวาง (PNG, SVG)</div>
        </div>

        <div className="label mb">ตัวอย่างหัวบิล (อัปเดตสดตามที่กรอก)</div>
        <div style={{padding: 16, background: "white", color: "#0c0a09", borderRadius: 8, border: "1px solid var(--line)"}}>
          <div style={{display: "flex", gap: 12, alignItems: "flex-start"}}>
            <div style={{width: 44, height: 44, background: "#0c0a09", color: "white", display: "grid", placeItems: "center", fontWeight: 700, fontSize: 14, borderRadius: 5, flexShrink: 0}}>SSS</div>
            <div>
              <div style={{fontWeight: 600, fontSize: 13}}>{f.name || "—"}</div>
              <div style={{fontSize: 10.5, color: "#78716c"}}>{f.nameEn}</div>
              <div style={{fontSize: 10.5, color: "#78716c", marginTop: 2}}>เลขผู้เสียภาษี {f.taxId}</div>
              {f.address && <div style={{fontSize: 10.5, color: "#78716c", marginTop: 2, maxWidth: 280}}>{f.address}</div>}
              <div style={{fontSize: 10.5, color: "#78716c", marginTop: 2}}>{f.phone}{f.email ? " · " + f.email : ""}</div>
            </div>
          </div>
        </div>
        {dirty && <div className="muted" style={{fontSize: 12, marginTop: 12, color: "var(--warning)"}}>● มีการแก้ไขที่ยังไม่บันทึก — กดปุ่ม "บันทึก" เพื่อใช้กับเอกสารทั้งหมด</div>}
      </Card>
    </div>
  );
}

// ============ Customers (CRM-lite) ============
function Customers({ navigate }) {
  const D = window.SSSData;
  const { Btn, Badge, Card, PageHead, fmt0 } = window.UI;
  const [active, setActive] = useStateMisc(null);
  const [query, setQuery] = useStateMisc("");
  const [oweOnly, setOweOnly] = useStateMisc(false);
  const [showNew, setShowNew] = useStateMisc(false);
  const [list, setList] = useStateMisc(() => [...(D.Customers || [])]);

  React.useEffect(() => {
    const h = () => setList([...(D.Customers || [])]);
    window.addEventListener("sss-customers-changed", h);
    window.addEventListener("sss-data-synced", h);
    return () => { window.removeEventListener("sss-customers-changed", h); window.removeEventListener("sss-data-synced", h); };
  }, []);

  const filtered = list.filter(c => {
    if (oweOnly && !(c.owe > 0)) return false;
    if (!query.trim()) return true;
    const q = query.trim().toLowerCase();
    return [c.name, c.contact, c.phone, c.id, c.email, c.taxId].some(v => (v || "").toLowerCase().includes(q));
  });

  const totalOwe = list.reduce((s, c) => s + c.owe, 0);

  const exportCsv = () => window.exportRowsCSV("customers", [
    { key: "id", label: "รหัส" }, { key: "name", label: "ชื่อ" }, { key: "type", label: "ประเภท" },
    { key: "taxId", label: "เลขผู้เสียภาษี" }, { key: "contact", label: "ผู้ติดต่อ" }, { key: "phone", label: "โทร" },
    { key: "email", label: "อีเมล" }, { key: "credit", label: "เครดิต (วัน)" }, { key: "owe", label: "ค้างชำระ" }
  ], filtered);

  const addCustomer = (c) => {
    const maxN = Math.max(0, ...D.Customers.map(x => parseInt((x.id.split("-")[1]) || 0, 10)));
    const entry = { owe: 0, lastOrder: "—", ...c, id: "C-" + String(maxN + 1).padStart(4, "0"), tags: c.tags ? [c.tags] : [] };
    D.Customers.unshift(entry);
    setList([...D.Customers]);
    window.dispatchEvent(new Event("sss-customers-changed"));
    setShowNew(false);
    window.logActivity && window.logActivity("เพิ่มลูกค้า", `${entry.name} (${entry.id})`, "create");
    window.toast && window.toast(`เพิ่มลูกค้า ${entry.name} แล้ว`);
  };

  const updateCustomer = (id, patch) => {
    D.Customers = (D.Customers || []).map(c => c.id === id ? { ...c, ...patch } : c);
    setList([...D.Customers]);
    window.dispatchEvent(new Event("sss-customers-changed"));
    window.SSSSync && window.SSSSync.save && window.SSSSync.save();
    window.logActivity && window.logActivity("แก้ไขลูกค้า", `${patch.name || id}`, "update");
    window.toast && window.toast("บันทึกข้อมูลลูกค้าแล้ว");
    setActive(null);
  };
  const deleteCustomer = async (c) => {
    const ok = await window.confirmDelete("ลูกค้า " + c.name, c.id);
    if (!ok) return;
    window.markDeleted && window.markDeleted("Customers", c.id);
    D.Customers = (D.Customers || []).filter(x => x.id !== c.id);
    setList([...D.Customers]);
    window.dispatchEvent(new Event("sss-customers-changed"));
    window.SSSSync && window.SSSSync.save && window.SSSSync.save();
    window.toast && window.toast("ลบลูกค้าแล้ว");
    setActive(null);
  };

  return (
    <>
      <PageHead title="ลูกค้า · Customers (CRM)" sub="ฐานข้อมูล + ติดตามการสั่งซื้อและประวัติ"
        right={<><Btn icon={I.download} kind="ghost" onClick={exportCsv}>ส่งออก CSV</Btn><Btn icon={I.plus} kind="primary" onClick={() => setShowNew(true)}>เพิ่มลูกค้า</Btn></>}/>

      <div className="grid cols-4 mb-lg">
        <window.UI.Stat label="ลูกค้าทั้งหมด" value={list.length} sub={`นิติบุคคล ${list.filter(c=>c.type==="นิติบุคคล").length} · บุคคล ${list.filter(c=>c.type!=="นิติบุคคล").length}`} icon={I.user}/>
        <window.UI.Stat label="ลูกค้าใหม่เดือนนี้" value={1} sub="บจก. อินโนเวชั่น ฟู้ดส์" dir="up" icon={I.plus}/>
        <window.UI.Stat label="ลูกหนี้รวม" value={`฿${fmt0(totalOwe)}`} sub="ทุกใบ" icon={I.invoice}/>
        <window.UI.Stat label="LTV เฉลี่ย" value="฿1.2M" sub="ต่อลูกค้า ต่อปี" icon={I.briefcase}/>
      </div>

      <Card flush padded={false}>
        <div style={{padding: 12, borderBottom: "1px solid var(--line)", display: "flex", alignItems: "center", gap: 10}}>
          <div className="search" style={{width: 280}}>
            <I.search size={14}/>
            <input placeholder="ค้นหาลูกค้า…" value={query} onChange={e => setQuery(e.target.value)}/>
          </div>
          <span className="spacer"/>
          {(query || oweOnly) && <span className="muted" style={{fontSize: 12}}>{filtered.length} จาก {list.length} ราย</span>}
          <Btn icon={I.filter} kind={oweOnly ? "primary" : "ghost"} size="sm" onClick={() => setOweOnly(v => !v)}>{oweOnly ? "เฉพาะค้างชำระ" : "ตัวกรอง"}</Btn>
        </div>
        <div className="table-wrap">
          <table className="t">
            <thead><tr><th>รหัส</th><th>ชื่อ</th><th>ผู้ติดต่อ</th><th>โทร</th><th>เครดิต</th><th className="right">ค้างชำระ</th><th>ออเดอร์ล่าสุด</th><th>แท็ก</th><th></th></tr></thead>
            <tbody>
              {filtered.length === 0 && (
                <tr><td colSpan={9} style={{textAlign: "center", padding: "28px 0", color: "var(--ink-3)"}}>ไม่พบลูกค้าที่ตรงกับเงื่อนไข</td></tr>
              )}
              {filtered.map(c => (
                <tr key={c.id} className="row-clickable" onClick={() => setActive(c)}>
                  <td className="mono">{c.id}</td>
                  <td>{c.name}<div className="muted" style={{fontSize: 11}}>{c.type} · {c.taxId}</div></td>
                  <td>{c.contact}</td>
                  <td className="mono" style={{fontSize: 12}}>{c.phone}</td>
                  <td>{c.credit} วัน</td>
                  <td className="right amount" style={{color: c.owe > 0 ? "var(--ink-1)" : "var(--ink-3)"}}>{c.owe > 0 ? `฿${fmt0(c.owe)}` : "—"}</td>
                  <td className="muted">{c.lastOrder}</td>
                  <td><div style={{display: "flex", gap: 4}}>{c.tags.map(t => <Badge key={t}>{t}</Badge>)}</div></td>
                  <td><Btn kind="ghost" size="sm" icon={I.ellipsis} onClick={(e) => { e.stopPropagation(); setActive(c); }}/></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </Card>

      {active && <CustomerEditDrawer customer={active} onClose={() => setActive(null)} onSave={updateCustomer} onDelete={deleteCustomer} navigate={navigate}/>}

      {showNew && <NewCustomerDrawer onClose={() => setShowNew(false)} onSave={addCustomer}/>}
    </>
  );
}

function NewCustomerDrawer({ onClose, onSave }) {
  const { Btn, Drawer } = window.UI;
  const [f, setF] = useStateMisc({
    name: "", type: "นิติบุคคล", taxId: "", address: "", contact: "", phone: "", email: "", credit: 30, tags: ""
  });
  const [looking, setLooking] = useStateMisc(false);
  const upd = (k, v) => setF(p => ({ ...p, [k]: v }));
  // ค้นชื่อ+ที่อยู่จาก DBD ด้วยเลขผู้เสียภาษี 13 หลัก
  const dbdFind = async () => {
    if (!window.dbdLookup) { window.toast && window.toast("ระบบค้น DBD ยังไม่พร้อม (ยังไม่ได้ตั้งค่า Edge Function)"); return; }
    setLooking(true);
    try {
      const r = await window.dbdLookup(f.taxId);
      setF(p => ({ ...p, name: r.name || p.name, address: r.address || p.address, type: "นิติบุคคล" }));
      window.toast && window.toast(r.name ? ("พบ: " + r.name) : "ค้นสำเร็จ แต่ไม่พบชื่อในผลลัพธ์");
    } catch (e) {
      window.toast && window.toast("ค้นไม่สำเร็จ: " + (e.message || String(e)));
    } finally { setLooking(false); }
  };
  const save = () => {
    if (!f.name.trim()) { window.toast && window.toast("กรอกชื่อลูกค้าก่อน"); return; }
    onSave({ ...f, name: f.name.trim(), credit: +f.credit || 0 });
  };
  return (
    <Drawer open={true} onClose={onClose} title="เพิ่มลูกค้าใหม่" wide
      footer={<><Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn><Btn kind="primary" icon={I.check} onClick={save}>บันทึกลูกค้า</Btn></>}>
      <div style={{display: "flex", flexDirection: "column", gap: 12}}>
        <div className="field"><label>ชื่อลูกค้า / บริษัท *</label><input className="input" value={f.name} onChange={e=>upd("name", e.target.value)} placeholder="เช่น บริษัท ตัวอย่าง จำกัด"/></div>
        <div className="field-row cols-2">
          <div className="field"><label>ประเภท</label>
            <select className="input" value={f.type} onChange={e=>upd("type", e.target.value)}>
              <option>นิติบุคคล</option><option>บุคคลธรรมดา</option>
            </select>
          </div>
          <div className="field"><label>เลขผู้เสียภาษี (ค้นจาก DBD ได้)</label>
            <div style={{display: "flex", gap: 6}}>
              <input className="input mono" style={{flex: 1}} value={f.taxId} onChange={e=>upd("taxId", e.target.value)} placeholder="0105560XXXXXX (13 หลัก)"/>
              <Btn kind="ghost" icon={I.search} onClick={dbdFind} disabled={looking || String(f.taxId||"").replace(/\D/g,"").length !== 13}>{looking ? "กำลังค้น…" : "ค้น DBD"}</Btn>
            </div>
          </div>
        </div>
        <div className="field"><label>ที่อยู่</label><textarea className="textarea" style={{minHeight: 52}} value={f.address} onChange={e=>upd("address", e.target.value)} placeholder="เลขที่ / ถนน / ตำบล / อำเภอ / จังหวัด / รหัสไปรษณีย์ (กดค้น DBD เพื่อเติมอัตโนมัติ)"/></div>
        <div className="field-row cols-2">
          <div className="field"><label>ผู้ติดต่อ</label><input className="input" value={f.contact} onChange={e=>upd("contact", e.target.value)} placeholder="คุณ…"/></div>
          <div className="field"><label>โทรศัพท์</label><input className="input mono" value={f.phone} onChange={e=>upd("phone", e.target.value)} placeholder="08X-XXX-XXXX"/></div>
        </div>
        <div className="field-row cols-2">
          <div className="field"><label>อีเมล</label><input className="input" value={f.email} onChange={e=>upd("email", e.target.value)} placeholder="name@company.co.th"/></div>
          <div className="field"><label>เครดิต (วัน)</label><input className="input" type="number" min="0" value={f.credit} onChange={e=>upd("credit", e.target.value)}/></div>
        </div>
        <div className="field"><label>แท็ก</label><input className="input" value={f.tags} onChange={e=>upd("tags", e.target.value)} placeholder="เช่น VIP, ลูกค้าประจำ"/></div>
      </div>
    </Drawer>
  );
}

// แก้ไขข้อมูลลูกค้า (มีที่อยู่ + ค้น DBD + ลบ)
function CustomerEditDrawer({ customer, onClose, onSave, onDelete, navigate }) {
  const { Btn, Drawer } = window.UI;
  const [f, setF] = useStateMisc({
    name: customer.name || "", type: customer.type || "นิติบุคคล", taxId: customer.taxId || "",
    address: customer.address || "", contact: customer.contact || "", phone: customer.phone || "",
    email: customer.email || "", credit: customer.credit != null ? customer.credit : 30,
  });
  const [looking, setLooking] = useStateMisc(false);
  const upd = (k, v) => setF(p => ({ ...p, [k]: v }));
  const dbdFind = async () => {
    if (!window.dbdLookup) { window.toast && window.toast("ระบบค้น DBD ยังไม่พร้อม (ยังไม่ได้ตั้งค่า Edge Function)"); return; }
    setLooking(true);
    try { const r = await window.dbdLookup(f.taxId); setF(p => ({ ...p, name: r.name || p.name, address: r.address || p.address, type: "นิติบุคคล" })); window.toast && window.toast(r.name ? ("พบ: " + r.name) : "ค้นสำเร็จ แต่ไม่พบชื่อ"); }
    catch (e) { window.toast && window.toast("ค้นไม่สำเร็จ: " + (e.message || String(e))); }
    finally { setLooking(false); }
  };
  const save = () => { if (!f.name.trim()) { window.toast && window.toast("กรอกชื่อลูกค้าก่อน"); return; } onSave(customer.id, { ...f, name: f.name.trim(), credit: +f.credit || 0 }); };
  return (
    <Drawer open={true} onClose={onClose} title={`แก้ไขลูกค้า · ${customer.id}`} wide
      footer={<>
        <Btn kind="ghost" icon={I.trash} onClick={() => onDelete(customer)}>ลบลูกค้า</Btn>
        <span className="spacer"/>
        <Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn>
        <Btn kind="primary" icon={I.check} onClick={save}>บันทึกการแก้ไข</Btn>
      </>}>
      <div style={{display: "flex", flexDirection: "column", gap: 12}}>
        <div className="field"><label>ชื่อลูกค้า / บริษัท *</label><input className="input" value={f.name} onChange={e=>upd("name", e.target.value)}/></div>
        <div className="field-row cols-2">
          <div className="field"><label>ประเภท</label>
            <select className="input" value={f.type} onChange={e=>upd("type", e.target.value)}><option>นิติบุคคล</option><option>บุคคลธรรมดา</option></select>
          </div>
          <div className="field"><label>เลขผู้เสียภาษี (ค้นจาก DBD ได้)</label>
            <div style={{display: "flex", gap: 6}}>
              <input className="input mono" style={{flex: 1}} value={f.taxId} onChange={e=>upd("taxId", e.target.value)} placeholder="0105560XXXXXX"/>
              <Btn kind="ghost" icon={I.search} onClick={dbdFind} disabled={looking || String(f.taxId||"").replace(/\D/g,"").length !== 13}>{looking ? "กำลังค้น…" : "ค้น DBD"}</Btn>
            </div>
          </div>
        </div>
        <div className="field"><label>ที่อยู่</label><textarea className="textarea" style={{minHeight: 56}} value={f.address} onChange={e=>upd("address", e.target.value)} placeholder="ที่อยู่สำหรับออกเอกสาร/ใบกำกับภาษี"/></div>
        <div className="field-row cols-2">
          <div className="field"><label>ผู้ติดต่อ</label><input className="input" value={f.contact} onChange={e=>upd("contact", e.target.value)}/></div>
          <div className="field"><label>โทรศัพท์</label><input className="input mono" value={f.phone} onChange={e=>upd("phone", e.target.value)}/></div>
        </div>
        <div className="field-row cols-2">
          <div className="field"><label>อีเมล</label><input className="input" value={f.email} onChange={e=>upd("email", e.target.value)}/></div>
          <div className="field"><label>เครดิต (วัน)</label><input className="input" type="number" min="0" value={f.credit} onChange={e=>upd("credit", e.target.value)}/></div>
        </div>
        <Btn kind="ghost" icon={I.plus} onClick={() => { onClose(); window.openNewDoc && window.openNewDoc("quotation"); }}>สร้างใบเสนอราคาให้ลูกค้านี้</Btn>
      </div>
    </Drawer>
  );
}

// ============ Vendors ============
function Vendors({ navigate }) {
  const D = window.SSSData;
  const { Btn, Badge, Card, PageHead, Drawer, fmt0 } = window.UI;
  const [list, setList] = useStateMisc(() => [...(D.Vendors || [])]);
  const [active, setActive] = useStateMisc(null);
  const [showNew, setShowNew] = useStateMisc(false);

  React.useEffect(() => {
    const h = () => setList([...(D.Vendors || [])]);
    window.addEventListener("sss-vendors-changed", h);
    window.addEventListener("sss-data-synced", h);
    return () => { window.removeEventListener("sss-vendors-changed", h); window.removeEventListener("sss-data-synced", h); };
  }, []);

  const exportCsv = () => window.exportRowsCSV("vendors", [
    { key: "id", label: "รหัส" }, { key: "name", label: "ชื่อ" }, { key: "taxId", label: "เลขผู้เสียภาษี" },
    { key: "contact", label: "ผู้ติดต่อ" }, { key: "phone", label: "โทร" }, { key: "category", label: "หมวด" },
    { key: "terms", label: "เครดิต" }, { key: "bank", label: "ธนาคาร" }, { key: "bankAcc", label: "เลขที่บัญชี" }, { key: "accName", label: "ชื่อบัญชี" }, { key: "balance", label: "คงค้าง" }
  ], list);

  const addVendor = (v) => {
    const maxN = Math.max(0, ...D.Vendors.map(x => parseInt((x.id.split("-")[1]) || 0, 10)));
    const entry = { balance: 0, ...v, id: "V-" + String(maxN + 1).padStart(4, "0") };
    D.Vendors.unshift(entry);
    setList([...D.Vendors]);
    window.dispatchEvent(new Event("sss-vendors-changed"));
    setShowNew(false);
    window.logActivity && window.logActivity("เพิ่มผู้ขาย", `${entry.name} (${entry.id})`, "create");
    window.toast && window.toast(`เพิ่มผู้ขาย ${entry.name} แล้ว`);
  };

  const updateVendor = (id, patch) => {
    D.Vendors = (D.Vendors || []).map(v => v.id === id ? { ...v, ...patch } : v);
    setList([...D.Vendors]);
    window.dispatchEvent(new Event("sss-vendors-changed"));
    window.SSSSync && window.SSSSync.save && window.SSSSync.save();
    window.logActivity && window.logActivity("แก้ไขผู้ขาย", `${patch.name || id}`, "update");
    window.toast && window.toast("บันทึกข้อมูลผู้ขายแล้ว");
    setActive(null);
  };
  const deleteVendor = async (v) => {
    const ok = await window.confirmDelete("ผู้ขาย " + v.name, v.id);
    if (!ok) return;
    window.markDeleted && window.markDeleted("Vendors", v.id);
    D.Vendors = (D.Vendors || []).filter(x => x.id !== v.id);
    setList([...D.Vendors]);
    window.dispatchEvent(new Event("sss-vendors-changed"));
    window.SSSSync && window.SSSSync.save && window.SSSSync.save();
    window.toast && window.toast("ลบผู้ขายแล้ว");
    setActive(null);
  };

  return (
    <>
      <PageHead title="ผู้ขาย/Vendor" sub="ฐานข้อมูล supplier และเครดิต"
        right={<><Btn icon={I.download} kind="ghost" onClick={exportCsv}>ส่งออก CSV</Btn><Btn icon={I.plus} kind="primary" onClick={() => setShowNew(true)}>เพิ่ม Vendor</Btn></>}/>

      <div className="grid cols-4 mb-lg">
        <window.UI.Stat label="Vendor ทั้งหมด" value={list.length} icon={I.building}/>
        <window.UI.Stat label="เจ้าหนี้รวม" value={`฿${fmt0(list.reduce((s,v)=>s+v.balance,0))}`} sub="ตามใบสั่งซื้อยังไม่จ่าย" icon={I.invoice}/>
        <window.UI.Stat label="ต้องจ่ายสัปดาห์นี้" value="฿312,000" sub="3 ราย" dir="down" icon={I.clock}/>
        <window.UI.Stat label="Lead time เฉลี่ย" value="7 วัน" sub="วัตถุดิบหลัก" icon={I.truck}/>
      </div>

      <Card flush>
        <table className="t">
          <thead><tr><th>รหัส</th><th>ชื่อ</th><th>ติดต่อ</th><th>หมวด</th><th>เครดิต</th><th className="right">คงค้าง</th><th></th></tr></thead>
          <tbody>
            {list.map(v => (
              <tr key={v.id} className="row-clickable" onClick={() => setActive(v)}>
                <td className="mono">{v.id}</td>
                <td>{v.name}<div className="muted" style={{fontSize: 11}}>{v.taxId}</div></td>
                <td><div>{v.contact}</div><div className="mono muted" style={{fontSize: 11}}>{v.phone}</div></td>
                <td>{v.category}</td>
                <td>{v.terms}</td>
                <td className="right amount">{v.balance > 0 ? `฿${fmt0(v.balance)}` : "—"}</td>
                <td><Btn size="sm" kind="ghost" icon={I.ellipsis} onClick={(e) => { e.stopPropagation(); setActive(v); }}/></td>
              </tr>
            ))}
          </tbody>
        </table>
      </Card>

      {active && <VendorEditDrawer vendor={active} onClose={() => setActive(null)} onSave={updateVendor} onDelete={deleteVendor}/>}

      {showNew && <NewVendorDrawer onClose={() => setShowNew(false)} onSave={addVendor}/>}
    </>
  );
}

function NewVendorDrawer({ onClose, onSave }) {
  const { Btn, Drawer } = window.UI;
  const [f, setF] = useStateMisc({
    name: "", taxId: "", address: "", contact: "", phone: "", email: "", category: "วัตถุดิบ", terms: "30 วัน", bank: "", bankAcc: "", accName: ""
  });
  const [looking, setLooking] = useStateMisc(false);
  const upd = (k, v) => setF(p => ({ ...p, [k]: v }));
  const dbdFind = async () => {
    if (!window.dbdLookup) { window.toast && window.toast("ระบบค้น DBD ยังไม่พร้อม"); return; }
    setLooking(true);
    try { const r = await window.dbdLookup(f.taxId); setF(p => ({ ...p, name: r.name || p.name, address: r.address || p.address })); window.toast && window.toast(r.name ? ("พบ: " + r.name) : "ค้นสำเร็จ"); }
    catch (e) { window.toast && window.toast("ค้นไม่สำเร็จ: " + (e.message || String(e))); }
    finally { setLooking(false); }
  };
  const save = () => {
    if (!f.name.trim()) { window.toast && window.toast("กรอกชื่อผู้ขายก่อน"); return; }
    onSave({ ...f, name: f.name.trim() });
  };
  return (
    <Drawer open={true} onClose={onClose} title="เพิ่มผู้ขายใหม่" wide
      footer={<><Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn><Btn kind="primary" icon={I.check} onClick={save}>บันทึกผู้ขาย</Btn></>}>
      <div style={{display: "flex", flexDirection: "column", gap: 12}}>
        <div className="field"><label>ชื่อผู้ขาย / บริษัท *</label><input className="input" value={f.name} onChange={e=>upd("name", e.target.value)} placeholder="เช่น บริษัท ซัพพลายเออร์ จำกัด"/></div>
        <div className="field"><label>เลขผู้เสียภาษี (ค้นจาก DBD ได้)</label>
          <div style={{display: "flex", gap: 6}}>
            <input className="input mono" style={{flex: 1}} value={f.taxId} onChange={e=>upd("taxId", e.target.value)} placeholder="0105560XXXXXX"/>
            <Btn kind="ghost" icon={I.search} onClick={dbdFind} disabled={looking || String(f.taxId||"").replace(/\D/g,"").length !== 13}>{looking ? "กำลังค้น…" : "ค้น DBD"}</Btn>
          </div>
        </div>
        <div className="field"><label>ที่อยู่</label><textarea className="textarea" style={{minHeight: 52}} value={f.address} onChange={e=>upd("address", e.target.value)} placeholder="ที่อยู่สำหรับออกใบสำคัญจ่าย/เอกสาร"/></div>
        <div className="field-row cols-2">
          <div className="field"><label>หมวดสินค้า</label>
            <select className="input" value={f.category} onChange={e=>upd("category", e.target.value)}>
              <option>วัตถุดิบ</option><option>อุปกรณ์/เครื่องมือ</option><option>ก๊าซ/สิ้นเปลือง</option><option>ขนส่ง</option><option>บริการ</option>
            </select>
          </div>
          <div className="field"><label>ผู้ติดต่อ</label><input className="input" value={f.contact} onChange={e=>upd("contact", e.target.value)} placeholder="คุณ…"/></div>
        </div>
        <div className="field-row cols-2">
          <div className="field"><label>โทรศัพท์</label><input className="input mono" value={f.phone} onChange={e=>upd("phone", e.target.value)} placeholder="0X-XXX-XXXX"/></div>
          <div className="field"><label>อีเมล</label><input className="input" value={f.email} onChange={e=>upd("email", e.target.value)} placeholder="name@company.co.th"/></div>
        </div>
        <div className="field"><label>เงื่อนไขเครดิต</label>
          <select className="input" value={f.terms} onChange={e=>upd("terms", e.target.value)}>
            <option>เงินสด</option><option>15 วัน</option><option>30 วัน</option><option>45 วัน</option><option>60 วัน</option>
          </select>
        </div>
        <div style={{borderTop: "1px solid var(--line)", margin: "4px 0 0", paddingTop: 14}}>
          <div style={{fontSize: 12.5, fontWeight: 600, marginBottom: 10, display: "flex", alignItems: "center", gap: 8}}>{React.createElement(I.invoice, { size: 14 })} บัญชีรับโอนเงิน (สำหรับโอนจ่าย)</div>
          <div style={{display: "flex", flexDirection: "column", gap: 12}}>
            <div className="field-row cols-2">
              <div className="field"><label>ธนาคาร</label>
                <select className="input" value={f.bank} onChange={e=>upd("bank", e.target.value)}>
                  <option value="">— เลือกธนาคาร —</option>
                  <option>ธนาคารกสิกรไทย</option><option>ธนาคารไทยพาณิชย์</option><option>ธนาคารกรุงไทย</option><option>ธนาคารกรุงเทพ</option><option>ธนาคารทหารไทยธนชาต</option><option>ธนาคารออมสิน</option>
                </select>
              </div>
              <div className="field"><label>เลขที่บัญชี</label><input className="input mono" value={f.bankAcc} onChange={e=>upd("bankAcc", e.target.value)} placeholder="XXX-X-XXXXX-X"/></div>
            </div>
            <div className="field"><label>ชื่อบัญชี</label><input className="input" value={f.accName} onChange={e=>upd("accName", e.target.value)} placeholder="ชื่อเจ้าของบัญชี (ถ้าไม่ระบุจะใช้ชื่อผู้ขาย)"/></div>
          </div>
        </div>
      </div>
    </Drawer>
  );
}

// แก้ไขข้อมูลผู้ขาย (ที่อยู่ + บัญชีธนาคาร + ค้น DBD + ลบ)
function VendorEditDrawer({ vendor, onClose, onSave, onDelete }) {
  const { Btn, Drawer } = window.UI;
  const [f, setF] = useStateMisc({
    name: vendor.name || "", taxId: vendor.taxId || "", address: vendor.address || "", contact: vendor.contact || "",
    phone: vendor.phone || "", email: vendor.email || "", category: vendor.category || "วัตถุดิบ", terms: vendor.terms || "30 วัน",
    bank: vendor.bank || "", bankAcc: vendor.bankAcc || "", accName: vendor.accName || "",
  });
  const [looking, setLooking] = useStateMisc(false);
  const upd = (k, v) => setF(p => ({ ...p, [k]: v }));
  const dbdFind = async () => {
    if (!window.dbdLookup) { window.toast && window.toast("ระบบค้น DBD ยังไม่พร้อม"); return; }
    setLooking(true);
    try { const r = await window.dbdLookup(f.taxId); setF(p => ({ ...p, name: r.name || p.name, address: r.address || p.address })); window.toast && window.toast(r.name ? ("พบ: " + r.name) : "ค้นสำเร็จ"); }
    catch (e) { window.toast && window.toast("ค้นไม่สำเร็จ: " + (e.message || String(e))); }
    finally { setLooking(false); }
  };
  const save = () => { if (!f.name.trim()) { window.toast && window.toast("กรอกชื่อผู้ขายก่อน"); return; } onSave(vendor.id, { ...f, name: f.name.trim() }); };
  return (
    <Drawer open={true} onClose={onClose} title={`แก้ไขผู้ขาย · ${vendor.id}`} wide
      footer={<>
        <Btn kind="ghost" icon={I.trash} onClick={() => onDelete(vendor)}>ลบผู้ขาย</Btn>
        <span className="spacer"/>
        <Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn>
        <Btn kind="primary" icon={I.check} onClick={save}>บันทึกการแก้ไข</Btn>
      </>}>
      <div style={{display: "flex", flexDirection: "column", gap: 12}}>
        <div className="field"><label>ชื่อผู้ขาย / บริษัท *</label><input className="input" value={f.name} onChange={e=>upd("name", e.target.value)}/></div>
        <div className="field"><label>เลขผู้เสียภาษี (ค้นจาก DBD ได้)</label>
          <div style={{display: "flex", gap: 6}}>
            <input className="input mono" style={{flex: 1}} value={f.taxId} onChange={e=>upd("taxId", e.target.value)} placeholder="0105560XXXXXX"/>
            <Btn kind="ghost" icon={I.search} onClick={dbdFind} disabled={looking || String(f.taxId||"").replace(/\D/g,"").length !== 13}>{looking ? "กำลังค้น…" : "ค้น DBD"}</Btn>
          </div>
        </div>
        <div className="field"><label>ที่อยู่</label><textarea className="textarea" style={{minHeight: 52}} value={f.address} onChange={e=>upd("address", e.target.value)} placeholder="ที่อยู่สำหรับออกใบสำคัญจ่าย/เอกสาร"/></div>
        <div className="field-row cols-2">
          <div className="field"><label>หมวดสินค้า</label>
            <select className="input" value={f.category} onChange={e=>upd("category", e.target.value)}><option>วัตถุดิบ</option><option>อุปกรณ์/เครื่องมือ</option><option>ก๊าซ/สิ้นเปลือง</option><option>ขนส่ง</option><option>บริการ</option></select>
          </div>
          <div className="field"><label>เงื่อนไขเครดิต</label>
            <select className="input" value={f.terms} onChange={e=>upd("terms", e.target.value)}><option>เงินสด</option><option>15 วัน</option><option>30 วัน</option><option>45 วัน</option><option>60 วัน</option></select>
          </div>
        </div>
        <div className="field-row cols-2">
          <div className="field"><label>ผู้ติดต่อ</label><input className="input" value={f.contact} onChange={e=>upd("contact", e.target.value)}/></div>
          <div className="field"><label>โทรศัพท์</label><input className="input mono" value={f.phone} onChange={e=>upd("phone", e.target.value)}/></div>
        </div>
        <div className="field"><label>อีเมล</label><input className="input" value={f.email} onChange={e=>upd("email", e.target.value)}/></div>
        <div style={{borderTop: "1px solid var(--line)", margin: "4px 0 0", paddingTop: 14}}>
          <div style={{fontSize: 12.5, fontWeight: 600, marginBottom: 10, display: "flex", alignItems: "center", gap: 8}}>{React.createElement(I.invoice, { size: 14 })} บัญชีรับโอนเงิน (สำหรับโอนจ่าย)</div>
          <div style={{display: "flex", flexDirection: "column", gap: 12}}>
            <div className="field-row cols-2">
              <div className="field"><label>ธนาคาร</label>
                <select className="input" value={f.bank} onChange={e=>upd("bank", e.target.value)}>
                  <option value="">— เลือกธนาคาร —</option>
                  <option>ธนาคารกสิกรไทย</option><option>ธนาคารไทยพาณิชย์</option><option>ธนาคารกรุงไทย</option><option>ธนาคารกรุงเทพ</option><option>ธนาคารทหารไทยธนชาต</option><option>ธนาคารออมสิน</option>
                </select>
              </div>
              <div className="field"><label>เลขที่บัญชี</label><input className="input mono" value={f.bankAcc} onChange={e=>upd("bankAcc", e.target.value)} placeholder="XXX-X-XXXXX-X"/></div>
            </div>
            <div className="field"><label>ชื่อบัญชี</label><input className="input" value={f.accName} onChange={e=>upd("accName", e.target.value)} placeholder="ถ้าไม่ระบุจะใช้ชื่อผู้ขาย"/></div>
          </div>
        </div>
      </div>
    </Drawer>
  );
}

// ============ Employees + HR ============
function HR({ navigate }) {
  const D = window.SSSData;
  const { Btn, Badge, Card, PageHead, Tabs, Drawer, fmt0 } = window.UI;
  const [tab, setTab] = useStateMisc("emp");
  // ✅ ใช้ D.Employees (ซิงค์ผ่าน Supabase) เป็นแหล่งข้อมูลหลัก — ไม่อ่าน localStorage ทับ
  const [employees, setEmployees] = useStateMisc(() => [...(D.Employees || [])]);
  const [leaves, setLeaves] = useStateMisc(() => {
    try { return JSON.parse(localStorage.getItem("sss-hr-leaves") || "null") || []; } catch { return []; }
  });
  const [active, setActive] = useStateMisc(null);
  const [showNew, setShowNew] = useStateMisc(false);
  const [showLeave, setShowLeave] = useStateMisc(false);

  // เมื่อข้อมูลพนักงานเปลี่ยนจากเครื่องอื่น (poll/realtime) → รีเฟรชหน้านี้
  React.useEffect(() => {
    const h = () => setEmployees([...(D.Employees || [])]);
    window.addEventListener("sss-employees-changed", h);
    window.addEventListener("sss-data-synced", h);
    return () => {
      window.removeEventListener("sss-employees-changed", h);
      window.removeEventListener("sss-data-synced", h);
    };
  }, []);

  React.useEffect(() => {
    try { localStorage.setItem("sss-hr-leaves", JSON.stringify(leaves)); } catch {}
  }, [leaves]);

  // เขียนกลับ D.Employees + แจ้ง sync ให้บันทึกขึ้น Supabase ทันที
  const commitEmps = (next) => {
    setEmployees(next);
    D.Employees.length = 0;
    D.Employees.push(...next);
    try { localStorage.setItem("sss-employees", JSON.stringify(next)); } catch {}
    window.dispatchEvent(new Event("sss-employees-changed"));
  };

  const addEmp = (e) => { commitEmps([...employees, e]); setShowNew(false); window.toast && window.toast("เพิ่มพนักงาน " + e.name); };
  const updateEmp = (id, patch) => {
    commitEmps(employees.map(e => e.id === id ? { ...e, ...patch } : e));
    if (active && active.id === id) setActive({ ...active, ...patch });
  };
  const deleteEmp = async (id) => {
    const emp = employees.find(e => e.id === id);
    const ok = await window.confirmDelete("พนักงาน " + (emp?.name || id), emp?.role);
    if (!ok) return;
    commitEmps(employees.filter(e => e.id !== id));
    setActive(null);
    window.toast && window.toast("ลบแล้ว");
  };
  const approveLeave = (id, approve) => {
    setLeaves(list => list.map(l => l.id === id ? { ...l, status: approve ? "อนุมัติแล้ว" : "ปฏิเสธ" } : l));
    window.toast && window.toast(approve ? "อนุมัติการลาแล้ว" : "ปฏิเสธการลา");
  };
  const addLeave = (l) => { setLeaves(list => [{ ...l, id: Date.now(), status: "รออนุมัติ" }, ...list]); setShowLeave(false); window.toast && window.toast("ส่งใบลาแล้ว"); };

  const pendingLeaves = leaves.filter(l => l.status === "รออนุมัติ").length;

  return (
    <>
      <PageHead title="พนักงานและ HR" sub="ทะเบียน · ลา/ขาด · ตำแหน่ง"
        right={<Btn icon={I.plus} kind="primary" onClick={() => setShowNew(true)}>เพิ่มพนักงาน</Btn>}/>
      <div className="grid cols-4 mb-lg">
        <window.UI.Stat label="พนักงานทั้งหมด" value={`${employees.length} คน`} sub="ใน 5 แผนก" icon={I.user}/>
        <window.UI.Stat label="ทดลองงาน" value={employees.filter(e=>e.status==='ทดลองงาน').length} sub="ครบ 90 วันใน 12 ก.ค." icon={I.clock}/>
        <window.UI.Stat label="ยื่นลาเดือนนี้" value={leaves.length} sub={`รออนุมัติ ${pendingLeaves} · อนุมัติแล้ว ${leaves.length - pendingLeaves}`} icon={I.doc}/>
        <window.UI.Stat label="ใช้สิทธิ์ลาเฉลี่ย" value="62%" sub="ต่อโควต้าปี" icon={I.calc}/>
      </div>

      <Tabs items={[
        { key: "emp", label: "ทะเบียนพนักงาน", count: employees.length },
        { key: "leave", label: "ลา / ขาด / มาสาย", count: pendingLeaves },
        { key: "org", label: "ผังองค์กร" }
      ]} active={tab} onChange={setTab}/>

      {tab === "emp" && (
        <Card flush>
          <table className="t">
            <thead><tr><th>รหัส</th><th>ชื่อ</th><th>ตำแหน่ง</th><th>แผนก</th><th>วันเริ่มงาน</th><th className="right">ค่าจ้าง</th><th>SSO</th><th>สถานะ</th><th></th></tr></thead>
            <tbody>
              {employees.map(e => (
                <tr key={e.id} className="row-clickable" onClick={() => setActive(e)}>
                  <td className="mono">{e.id}</td>
                  <td>{e.name}</td>
                  <td>{e.role}</td>
                  <td>{e.dept}</td>
                  <td className="muted">{e.hireDate}</td>
                  <td className="right amount">{e.salary > 0 ? `฿${fmt0(e.salary)}/เดือน` : e.hourly > 0 ? `฿${e.hourly}/ชม.` : "—"}</td>
                  <td>{e.sso ? <I.check size={14} stroke="var(--success)"/> : <span className="muted">—</span>}</td>
                  <td><Badge>{e.status}</Badge></td>
                  <td onClick={ev => ev.stopPropagation()}><Btn size="sm" kind="ghost" icon={I.edit} onClick={() => setActive(e)}/></td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>
      )}

      {tab === "leave" && (
        <Card flush
          right={null}>
          <div style={{padding: 10, display: "flex", justifyContent: "flex-end", borderBottom: "1px solid var(--line)"}}>
            <Btn size="sm" icon={I.plus} kind="primary" onClick={() => setShowLeave(true)}>ยื่นใบลา</Btn>
          </div>
          <table className="t">
            <thead><tr><th>วันที่ยื่น</th><th>พนักงาน</th><th>ประเภท</th><th>ช่วงวันที่</th><th>เหตุผล</th><th>สถานะ</th><th></th></tr></thead>
            <tbody>
              {leaves.map(l => (
                <tr key={l.id}>
                  <td>{l.date}</td>
                  <td>{l.emp}</td>
                  <td>{l.type}</td>
                  <td>{l.period}</td>
                  <td className="muted">{l.reason}</td>
                  <td><Badge>{l.status}</Badge></td>
                  <td>
                    {l.status === "รออนุมัติ" ? (
                      <div style={{display: "flex", gap: 4}}>
                        <Btn size="sm" kind="primary" onClick={() => approveLeave(l.id, true)}>อนุมัติ</Btn>
                        <Btn size="sm" kind="ghost" onClick={() => approveLeave(l.id, false)}>ปฏิเสธ</Btn>
                      </div>
                    ) : <Btn size="sm" kind="ghost" onClick={() => window.toast && window.toast(`${l.emp} · ${l.type} · ${l.period} — ${l.status}`)}>ดู</Btn>}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>
      )}

      {tab === "org" && <OrgChartDraggable/>}

      <Drawer open={!!active} onClose={() => setActive(null)} title={active?.name || ""} wide
        footer={<><Btn kind="danger" icon={I.trash} onClick={() => deleteEmp(active.id)}>ลบ</Btn><Btn kind="primary" icon={I.check} onClick={() => { window.toast && window.toast("บันทึกแล้ว"); setActive(null); }}>บันทึก</Btn></>}>
        {active && <EmpEdit emp={active} update={(patch) => updateEmp(active.id, patch)}/>}
      </Drawer>

      {showNew && <NewEmpModal onClose={() => setShowNew(false)} onSave={addEmp}/>}
      {showLeave && <NewLeaveModal onClose={() => setShowLeave(false)} onSave={addLeave} employees={employees}/>}
    </>
  );
}

function EmpEdit({ emp, update }) {
  const photos = (window.lsSyncGet ? (window.lsSyncGet("sss-employee-photos") || {}) : (() => { try { return JSON.parse(localStorage.getItem("sss-employee-photos") || "{}"); } catch { return {}; } })());
  const [photo, setPhoto] = useStateMisc(photos[emp.id] || null);
  // เอกสารแนบพนักงาน — เก็บในแมพรวม sss-emp-docs (sync ทุกเครื่อง + ไม่กินโควต้า localStorage)
  // ของเก่า sss-emp-docs-<id> จะถูกย้ายเข้าแมพอัตโนมัติโดย supabase-sync
  const [docs, setDocs] = useStateMisc(() => {
    const map = (window.lsSyncGet && window.lsSyncGet("sss-emp-docs")) || {};
    if (Array.isArray(map[emp.id])) return map[emp.id];
    try { return JSON.parse(localStorage.getItem("sss-emp-docs-" + emp.id) || "[]"); } catch { return []; }
  });
  const saveDocs = (next) => {
    setDocs(next);
    const map = Object.assign({}, (window.lsSyncGet && window.lsSyncGet("sss-emp-docs")) || {});
    map[emp.id] = next;
    if (window.lsSyncSet) window.lsSyncSet("sss-emp-docs", map);
    else { try { localStorage.setItem("sss-emp-docs-" + emp.id, JSON.stringify(next)); } catch {} }
  };

  const onPhoto = async (e) => {
    const f = e.target.files[0]; if (!f) { return; }
    e.target.value = "";
    // ย่อรูปก่อนเก็บ (กัน localStorage เต็ม) + เผื่อ canvas ถอดรหัสไม่ได้ (HEIC) ใช้ไฟล์เดิม
    const url = await new Promise(resolve => {
      const r = new FileReader();
      r.onload = () => {
        const dataUrl = r.result;
        const img = new Image();
        img.onload = () => {
          try {
            const s = Math.min(1, 320 / Math.max(img.width, img.height));
            const c = document.createElement("canvas");
            c.width = Math.max(1, Math.round(img.width * s));
            c.height = Math.max(1, Math.round(img.height * s));
            c.getContext("2d").drawImage(img, 0, 0, c.width, c.height);
            resolve(c.toDataURL("image/jpeg", 0.68));
          } catch (err) { resolve(dataUrl); }
        };
        img.onerror = () => resolve(dataUrl);
        img.src = dataUrl;
      };
      r.onerror = () => resolve(null);
      r.readAsDataURL(f);
    });
    if (!url) { window.toast && window.toast("อ่านรูปไม่สำเร็จ — ลองรูป JPG/PNG อีกครั้ง"); return; }
    const all = { ...(window.lsSyncGet ? (window.lsSyncGet("sss-employee-photos") || {}) : (() => { try { return JSON.parse(localStorage.getItem("sss-employee-photos") || "{}"); } catch { return {}; } })()) };
    all[emp.id] = url;
    // เก็บในหน่วยความจำ + sync ขึ้น Supabase (ไม่ผ่าน localStorage → ไม่เต็มโควต้า)
    if (window.lsSyncSet) { window.lsSyncSet("sss-employee-photos", all); }
    else { try { localStorage.setItem("sss-employee-photos", JSON.stringify(all)); } catch (e) { window.toast && window.toast("พื้นที่จัดเก็บเต็มมาก — ลบรูปเก่าก่อน"); return; } }
    setPhoto(url);
    window.dispatchEvent(new Event("sss-profiles-changed"));
    window.toast && window.toast("อัปโหลดรูปพนักงานแล้ว");
  };

  const onDocs = (e) => {
    const files = [...e.target.files];
    Promise.all(files.map(f => new Promise(res => {
      const r = new FileReader();
      r.onload = () => res({ name: f.name, url: r.result, size: f.size, type: f.type, uploadedAt: new Date().toLocaleString("th-TH", { day: "2-digit", month: "short", year: "2-digit" }) });
      r.readAsDataURL(f);
    }))).then(loaded => {
      const map = (window.lsSyncGet && window.lsSyncGet("sss-emp-docs")) || {};
      const fresh = Array.isArray(map[emp.id]) ? map[emp.id] : docs;
      saveDocs([...fresh, ...loaded]);   // ต่อท้ายข้อมูลสด — ไฟล์ที่เครื่องอื่นแนบไม่หาย
    });
    e.target.value = "";
  };

  return (
    <div style={{display: "flex", flexDirection: "column", gap: 14}}>
      {/* Photo */}
      <div style={{display: "flex", gap: 16, alignItems: "center", padding: 12, background: "var(--surface-2)", borderRadius: 8}}>
        <div style={{position: "relative"}}>
          {photo ? (
            <img src={photo} alt={emp.name} style={{width: 76, height: 76, borderRadius: "50%", objectFit: "cover", border: "3px solid var(--surface)"}}/>
          ) : (
            <div style={{width: 76, height: 76, borderRadius: "50%", background: "var(--surface-3)", display: "grid", placeItems: "center", fontWeight: 600, fontSize: 24, color: "var(--ink-2)", border: "3px solid var(--surface)"}}>{emp.name.slice(0, 2)}</div>
          )}
          <label style={{position: "absolute", bottom: 0, right: 0, width: 26, height: 26, borderRadius: "50%", background: "var(--ink-1)", color: "var(--bg)", display: "grid", placeItems: "center", cursor: "pointer", border: "2px solid var(--surface)"}}>
            <I.upload size={11}/>
            <input type="file" accept="image/*" style={{display: "none"}} onChange={onPhoto}/>
          </label>
        </div>
        <div style={{flex: 1}}>
          <div style={{fontSize: 14, fontWeight: 600}}>{emp.name}</div>
          <div style={{fontSize: 12, color: "var(--ink-3)"}}>{emp.role} · {emp.dept}</div>
          <label className="btn sm" style={{cursor: "pointer", marginTop: 6}}>
            <I.upload className="icon" size={11}/>
            {photo ? "เปลี่ยนรูป" : "อัปโหลดรูปพนักงาน"}
            <input type="file" accept="image/*" style={{display: "none"}} onChange={onPhoto}/>
          </label>
        </div>
      </div>

      <div className="field-row cols-2">
        <div className="field"><label>รหัสพนักงาน</label><input className="input mono" value={emp.id} readOnly style={{background: "var(--surface-2)"}}/></div>
        <div className="field"><label>สถานะ</label>
          <select className="input" value={emp.status} onChange={e=>update({ status: e.target.value })}>
            <option>ทำงาน</option><option>ทดลองงาน</option><option>ลาออกแล้ว</option><option>พักงาน</option>
          </select>
        </div>
      </div>
      <div className="field"><label>ชื่อ-นามสกุล</label><input className="input" value={emp.name} onChange={e=>update({ name: e.target.value })}/></div>
      <div className="field-row cols-2">
        <div className="field"><label>ตำแหน่ง</label><input className="input" value={emp.role} onChange={e=>update({ role: e.target.value })}/></div>
        <div className="field"><label>แผนก</label>
          <select className="input" value={emp.dept} onChange={e=>update({ dept: e.target.value })}>
            <option>บริหาร</option><option>ขาย</option><option>ผลิต</option><option>บัญชี</option><option>ออกแบบ</option><option>ขนส่ง</option>
          </select>
        </div>
      </div>
      <div className="field-row cols-2">
        <div className="field"><label>เงินเดือน (บาท/เดือน)</label><input className="input" type="number" value={emp.salary} onChange={e=>update({ salary: +e.target.value })}/></div>
        <div className="field"><label>ค่าจ้างรายชั่วโมง</label><input className="input" type="number" value={emp.hourly} onChange={e=>update({ hourly: +e.target.value })}/></div>
      </div>
      <div className="field-row cols-2">
        <div className="field"><label>อัตรา OT (บาท/ชม.)</label><input className="input" type="number" value={emp.otRate} onChange={e=>update({ otRate: +e.target.value })}/></div>
        <div className="field"><label>วันเริ่มงาน</label><input className="input" value={emp.hireDate} onChange={e=>update({ hireDate: e.target.value })}/></div>
      </div>
      <div className="field-row cols-2">
        <div className="field"><label>ธนาคาร</label><input className="input" value={emp.bank || ""} onChange={e=>update({ bank: e.target.value })} placeholder="เช่น ไทยพาณิชย์ (SCB)"/></div>
        <div className="field"><label>เลขที่บัญชีพนักงาน</label><input className="input mono" value={emp.bankAcc || ""} onChange={e=>update({ bankAcc: e.target.value })} placeholder="XXX-X-XXXXX-X"/></div>
      </div>
      <label style={{display: "flex", alignItems: "center", gap: 8, fontSize: 13}}>
        <input type="checkbox" checked={emp.sso} onChange={e=>update({ sso: e.target.checked })}/>
        เข้าระบบประกันสังคม (หัก 5%)
      </label>

      {/* Documents */}
      <div style={{borderTop: "1px solid var(--line)", paddingTop: 14}}>
        <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 8}}>
          <div>
            <div style={{fontWeight: 600, fontSize: 13}}>ใบสมัคร + เอกสารพนักงาน</div>
            <div style={{fontSize: 11, color: "var(--ink-3)"}}>{docs.length} ไฟล์ · ใบสมัคร, สำเนาบัตร, วุฒิการศึกษา, ฯลฯ</div>
          </div>
          <label className="btn sm" style={{cursor: "pointer"}}>
            <I.upload className="icon" size={11}/>
            แนบเอกสาร
            <input type="file" accept="image/*,application/pdf" multiple style={{display: "none"}} onChange={onDocs}/>
          </label>
        </div>
        {docs.length === 0 ? (
          <label style={{cursor: "pointer", display: "block"}}>
            <input type="file" accept="image/*,application/pdf" multiple style={{display: "none"}} onChange={onDocs}/>
            <div className="attach-dropzone">
              <I.upload size={20}/>
              <div style={{marginTop: 4, fontSize: 12}}>คลิกแนบใบสมัคร / สำเนาบัตร / วุฒิการศึกษา</div>
              <div style={{fontSize: 11, marginTop: 2}}>JPG, PNG, PDF</div>
            </div>
          </label>
        ) : (
          <div style={{display: "flex", flexDirection: "column", gap: 6}}>
            {docs.map((d, i) => {
              const isImg = d.type && d.type.startsWith("image/");
              return (
                <div key={i} style={{display: "flex", gap: 10, padding: 8, border: "1px solid var(--line)", borderRadius: 6, alignItems: "center"}}>
                  {isImg ? (
                    <img src={d.url} alt={d.name} onClick={() => window.open(d.url, "_blank")} style={{width: 48, height: 48, objectFit: "cover", borderRadius: 4, cursor: "pointer", border: "1px solid var(--line)"}}/>
                  ) : (
                    <div onClick={() => window.open(d.url, "_blank")} style={{width: 48, height: 48, borderRadius: 4, background: "var(--surface-2)", border: "1px solid var(--line)", display: "grid", placeItems: "center", color: "var(--ink-3)", fontSize: 10, fontWeight: 600, cursor: "pointer"}}>PDF</div>
                  )}
                  <div style={{flex: 1, minWidth: 0}}>
                    <div style={{fontSize: 12.5, fontWeight: 500, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap"}}>{d.name}</div>
                    <div style={{fontSize: 10.5, color: "var(--ink-3)"}}>{(d.size/1024).toFixed(0)} KB · {d.uploadedAt}</div>
                  </div>
                  <button className="icon-btn" onClick={() => {
                    const t = docs[i];
                    const map = (window.lsSyncGet && window.lsSyncGet("sss-emp-docs")) || {};
                    const fresh = Array.isArray(map[emp.id]) ? map[emp.id] : docs;
                    saveDocs(fresh.filter(x => !(x && t && x.url === t.url && x.name === t.name)));
                  }} title="ลบ"><I.trash size={12}/></button>
                </div>
              );
            })}
          </div>
        )}
      </div>
    </div>
  );
}

function NewEmpModal({ onClose, onSave }) {
  const { Btn, Drawer } = window.UI;
  const [f, setF] = useStateMisc({
    id: "EMP-" + Date.now().toString(36).toUpperCase() + Math.floor(Math.random() * 90 + 10),
    name: "", role: "", dept: "ผลิต",
    payType: "monthly", payDay: 28,
    salary: 0, hourly: 0, otRate: 0,
    bank: "", bankAcc: "",
    sso: true, hireDate: "22 พ.ค. 2569", status: "ทดลองงาน"
  });
  const upd = (k, v) => setF(p => ({ ...p, [k]: v }));
  const save = () => {
    if (!f.name || !f.role) { window.toast && window.toast("กรอกชื่อและตำแหน่ง"); return; }
    onSave(f);
  };
  return (
    <Drawer open={true} onClose={onClose} title="เพิ่มพนักงานใหม่" wide
      footer={<><Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn><Btn kind="primary" icon={I.check} onClick={save}>บันทึก</Btn></>}>
      <div style={{display: "flex", flexDirection: "column", gap: 12}}>
        <div className="field-row cols-2">
          <div className="field"><label>รหัสพนักงาน *</label><input className="input mono" value={f.id} onChange={e=>upd("id", e.target.value)}/></div>
          <div className="field"><label>สถานะ</label>
            <select className="input" value={f.status} onChange={e=>upd("status", e.target.value)}>
              <option>ทดลองงาน</option><option>ทำงาน</option>
            </select>
          </div>
        </div>
        <div className="field"><label>ชื่อ-นามสกุล *</label><input className="input" value={f.name} onChange={e=>upd("name", e.target.value)} placeholder="เช่น สมชาย รักงาน"/></div>
        <div className="field-row cols-2">
          <div className="field"><label>ตำแหน่ง *</label><input className="input" value={f.role} onChange={e=>upd("role", e.target.value)} placeholder="ช่างเชื่อม, ผู้จัดการ, ฯลฯ"/></div>
          <div className="field"><label>แผนก</label>
            <select className="input" value={f.dept} onChange={e=>upd("dept", e.target.value)}>
              <option>บริหาร</option><option>ขาย</option><option>ผลิต</option><option>บัญชี</option><option>ออกแบบ</option><option>ขนส่ง</option>
            </select>
          </div>
        </div>
        <div className="field"><label>ประเภทการจ่ายค่าจ้าง</label>
          <div className="payseg" style={{display: "flex", width: "100%"}}>
            <button type="button" className={"payseg-btn" + (f.payType === "monthly" ? " active" : "")} style={{flex: 1}} onClick={()=>upd("payType", "monthly")}>เงินเดือน (รายเดือน)</button>
            <button type="button" className={"payseg-btn" + (f.payType === "hourly" ? " active" : "")} style={{flex: 1}} onClick={()=>upd("payType", "hourly")}>รายชั่วโมง/รายวัน</button>
          </div>
        </div>
        {f.payType === "monthly" ?
        <div className="field-row cols-2">
          <div className="field"><label>เงินเดือน (บาท/เดือน)</label><input className="input" type="number" value={f.salary} onChange={e=>upd("salary", +e.target.value)}/></div>
          <div className="field"><label>วันจ่ายเงินเดือน (วันที่)</label>
            <select className="input" value={f.payDay} onChange={e=>upd("payDay", +e.target.value)}>
              {Array.from({length: 31}, (_, i) => i + 1).map(d => <option key={d} value={d}>ทุกวันที่ {d}</option>)}
              <option value={0}>วันสุดท้ายของเดือน</option>
            </select>
          </div>
        </div> :
        <div className="field-row cols-2">
          <div className="field"><label>ค่าจ้างรายชั่วโมง</label><input className="input" type="number" value={f.hourly} onChange={e=>upd("hourly", +e.target.value)}/></div>
          <div className="field"><label>เงินเดือน (ถ้ามี — ใช้ประเมินค่าแรง)</label><input className="input" type="number" value={f.salary} onChange={e=>upd("salary", +e.target.value)}/></div>
        </div>
        }
        <div className="field-row cols-2">
          <div className="field"><label>อัตรา OT (บาท/ชม.)</label><input className="input" type="number" value={f.otRate} onChange={e=>upd("otRate", +e.target.value)}/></div>
          <div className="field"><label>วันเริ่มงาน</label><input className="input" value={f.hireDate} onChange={e=>upd("hireDate", e.target.value)}/></div>
        </div>
        <div className="field-row cols-2">
          <div className="field"><label>ธนาคาร</label><input className="input" value={f.bank} onChange={e=>upd("bank", e.target.value)} placeholder="เช่น ไทยพาณิชย์ (SCB)"/></div>
          <div className="field"><label>เลขที่บัญชีพนักงาน</label><input className="input mono" value={f.bankAcc} onChange={e=>upd("bankAcc", e.target.value)} placeholder="XXX-X-XXXXX-X"/></div>
        </div>
        <label style={{display: "flex", alignItems: "center", gap: 8, fontSize: 13}}>
          <input type="checkbox" checked={f.sso} onChange={e=>upd("sso", e.target.checked)}/>
          เข้าระบบประกันสังคม
        </label>
      </div>
    </Drawer>
  );
}

function NewLeaveModal({ onClose, onSave, employees }) {
  const { Btn, Drawer } = window.UI;
  const [f, setF] = useStateMisc({
    emp: employees[1]?.name || "", type: "ลาพักร้อน",
    period: "", reason: "", date: "22 พ.ค."
  });
  const upd = (k, v) => setF(p => ({ ...p, [k]: v }));
  return (
    <Drawer open={true} onClose={onClose} title="ยื่นใบลา"
      footer={<><Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn><Btn kind="primary" icon={I.send} onClick={() => { if(!f.period||!f.reason){window.toast&&window.toast("กรอกข้อมูลให้ครบ");return;} onSave(f); }}>ส่งใบลา</Btn></>}>
      <div style={{display: "flex", flexDirection: "column", gap: 12}}>
        <div className="field"><label>พนักงาน</label>
          <select className="input" value={f.emp} onChange={e=>upd("emp", e.target.value)}>
            {employees.map(e => <option key={e.id}>{e.name}</option>)}
          </select>
        </div>
        <div className="field"><label>ประเภทการลา</label>
          <select className="input" value={f.type} onChange={e=>upd("type", e.target.value)}>
            <option>ลาพักร้อน</option><option>ลาป่วย</option><option>ลากิจ</option><option>ลาคลอด</option><option>ลาบวช</option>
          </select>
        </div>
        <div className="field"><label>ช่วงวันที่</label><input className="input" value={f.period} onChange={e=>upd("period", e.target.value)} placeholder="เช่น 3-5 มิ.ย. 2569"/></div>
        <div className="field"><label>เหตุผล</label><textarea className="textarea" value={f.reason} onChange={e=>upd("reason", e.target.value)} placeholder="ระบุเหตุผล…"/></div>
      </div>
    </Drawer>
  );
}

function OrgNode({ name, role, big, small }) {
  return (
    <div style={{padding: big ? "12px 20px" : small ? "6px 12px" : "10px 14px", background: big ? "var(--accent)" : "var(--surface)", color: big ? "var(--accent-ink)" : "var(--ink-1)", border: "1px solid var(--line-strong)", borderRadius: 8, textAlign: "center", minWidth: 140}}>
      <div style={{fontSize: small ? 12 : 13, fontWeight: 500}}>{name}</div>
      <div style={{fontSize: small ? 10 : 11, opacity: big ? 0.7 : undefined, color: big ? undefined : "var(--ink-3)"}}>{role}</div>
    </div>
  );
}

// =============== Draggable org chart with photos ===============
function OrgChartDraggable() {
  const D = window.SSSData;
  const { Btn, Card } = window.UI;

  const defaultPositions = {
    "EMP-001": { x: 480, y: 40 },
    "EMP-005": { x: 150, y: 200 },
    "EMP-009": { x: 320, y: 200 },
    "EMP-021": { x: 490, y: 200 },
    "EMP-018": { x: 660, y: 200 },
    "EMP-024": { x: 830, y: 200 },
    "EMP-012": { x: 220, y: 360 },
    "EMP-013": { x: 360, y: 360 },
    "EMP-030": { x: 500, y: 360 },
    "EMP-027": { x: 660, y: 360 }
  };
  // Default connections (parent → child)
  const defaultConnections = [
    { from: "EMP-001", to: "EMP-005" },
    { from: "EMP-001", to: "EMP-009" },
    { from: "EMP-001", to: "EMP-021" },
    { from: "EMP-001", to: "EMP-018" },
    { from: "EMP-001", to: "EMP-024" },
    { from: "EMP-009", to: "EMP-012" },
    { from: "EMP-009", to: "EMP-013" },
    { from: "EMP-009", to: "EMP-030" },
    { from: "EMP-018", to: "EMP-027" }
  ];

  const POS_KEY = "sss-org-positions";
  const CONN_KEY = "sss-org-connections";
  const PHOTO_KEY = "sss-employee-photos";

  const loadPos = () => { try { return JSON.parse(localStorage.getItem(POS_KEY)) || defaultPositions; } catch { return defaultPositions; } };
  const loadConn = () => { try { return JSON.parse(localStorage.getItem(CONN_KEY)) || defaultConnections; } catch { return defaultConnections; } };
  const loadPhotos = () => (window.lsSyncGet ? (window.lsSyncGet(PHOTO_KEY) || {}) : (() => { try { return JSON.parse(localStorage.getItem(PHOTO_KEY)) || {}; } catch { return {}; } })());

  const [positions, setPositions] = useStateMisc(loadPos);
  const [connections, setConnections] = useStateMisc(loadConn);
  const [photos, setPhotos] = useStateMisc(loadPhotos);
  const [dragging, setDragging] = useStateMisc(null);
  const [editMode, setEditMode] = useStateMisc(false);
  const [tool, setTool] = useStateMisc("move"); // move | draw | erase
  const [drawFrom, setDrawFrom] = useStateMisc(null); // first selected emp when drawing
  const containerRef = React.useRef(null);

  const savePos = (p) => { localStorage.setItem(POS_KEY, JSON.stringify(p)); };
  const saveConn = (c) => { localStorage.setItem(CONN_KEY, JSON.stringify(c)); };
  const savePhotos = (p) => { localStorage.setItem(PHOTO_KEY, JSON.stringify(p)); };

  // Only show connections where both ends exist as employees
  const empIds = new Set(D.Employees.map(e => e.id));
  const validConnections = connections.filter(c => empIds.has(c.from) && empIds.has(c.to) && positions[c.from] && positions[c.to]);

  const onMouseDown = (e, empId) => {
    if (!editMode) return;
    if (tool === "draw") {
      e.preventDefault();
      if (!drawFrom) {
        setDrawFrom(empId);
        window.toast && window.toast("เลือกการ์ดที่ 2 เพื่อเชื่อม");
      } else if (drawFrom !== empId) {
        // Check duplicate
        const exists = connections.some(c => (c.from === drawFrom && c.to === empId) || (c.from === empId && c.to === drawFrom));
        if (exists) { window.toast && window.toast("มีเส้นเชื่อมอยู่แล้ว"); }
        else {
          const next = [...connections, { from: drawFrom, to: empId }];
          setConnections(next); saveConn(next);
          window.toast && window.toast("เชื่อมเส้นแล้ว");
        }
        setDrawFrom(null);
      } else {
        setDrawFrom(null);
      }
      return;
    }
    // Move mode
    e.preventDefault();
    const rect = containerRef.current.getBoundingClientRect();
    const pos = positions[empId] || { x: 100, y: 100 };
    setDragging({ id: empId, offsetX: e.clientX - rect.left - pos.x, offsetY: e.clientY - rect.top - pos.y });
  };

  const deleteConnection = (idx) => {
    const next = connections.filter((_, i) => i !== validConnections.indexOf(validConnections[idx]) === false ? false : true);
    // Actually map validConnections idx back to connections
    const target = validConnections[idx];
    const realNext = connections.filter(c => !(c.from === target.from && c.to === target.to));
    setConnections(realNext); saveConn(realNext);
    window.toast && window.toast("ลบเส้นแล้ว");
  };

  React.useEffect(() => {
    if (!dragging) return;
    const onMove = (e) => {
      const rect = containerRef.current.getBoundingClientRect();
      const x = Math.max(0, e.clientX - rect.left - dragging.offsetX);
      const y = Math.max(0, e.clientY - rect.top - dragging.offsetY);
      setPositions(p => ({ ...p, [dragging.id]: { ...p[dragging.id], x, y } }));
    };
    const onUp = () => { setDragging(null); setPositions(p => { savePos(p); return p; }); };
    window.addEventListener("mousemove", onMove);
    window.addEventListener("mouseup", onUp);
    return () => { window.removeEventListener("mousemove", onMove); window.removeEventListener("mouseup", onUp); };
  }, [dragging]);

  const onUploadPhoto = (empId, e) => {
    const file = e.target.files[0]; if (!file) return;
    const reader = new FileReader();
    reader.onload = () => {
      const next = { ...photos, [empId]: reader.result };
      setPhotos(next); savePhotos(next);
      window.toast && window.toast("อัปโหลดรูปแล้ว");
    };
    reader.readAsDataURL(file);
    e.target.value = "";
  };

  const resetAll = () => {
    if (!confirm("รีเซ็ตตำแหน่งและเส้นเชื่อมทั้งหมด?")) return;
    setPositions(defaultPositions); savePos(defaultPositions);
    setConnections(defaultConnections); saveConn(defaultConnections);
  };

  const clearLines = () => {
    if (!confirm("ลบเส้นเชื่อมทั้งหมด?")) return;
    setConnections([]); saveConn([]);
  };

  // Bounding box
  const allCoords = D.Employees.map(e => positions[e.id]).filter(Boolean);
  const maxX = allCoords.length ? Math.max(...allCoords.map(p => p.x)) + 200 : 800;
  const maxY = allCoords.length ? Math.max(...allCoords.map(p => p.y)) + 200 : 600;

  return (
    <Card title="ผังองค์กร · Organization Chart" sub={`${D.Employees.length} คน · ${validConnections.length} เส้นเชื่อม`}
      right={<>
        {editMode && <Btn size="sm" kind="ghost" onClick={clearLines}>ลบเส้นทั้งหมด</Btn>}
        {editMode && <Btn size="sm" kind="ghost" onClick={resetAll}>รีเซ็ต</Btn>}
        <Btn size="sm" kind={editMode ? "primary" : ""} icon={editMode ? I.check : I.edit} onClick={() => { setEditMode(!editMode); setDrawFrom(null); setTool("move"); }}>
          {editMode ? "เสร็จ" : "แก้ไข"}
        </Btn>
      </>}>

      {/* Tool palette */}
      {editMode && (
        <div style={{display: "flex", gap: 6, padding: 8, background: "var(--surface-2)", borderRadius: 8, marginBottom: 10, border: "1px solid var(--line)"}}>
          <button className={`btn sm ${tool === "move" ? "primary" : ""}`} onClick={() => { setTool("move"); setDrawFrom(null); }}>
            🖐 ลากย้าย
          </button>
          <button className={`btn sm ${tool === "draw" ? "primary" : ""}`} onClick={() => { setTool("draw"); setDrawFrom(null); }}>
            ✏️ วาดเส้นเชื่อม
          </button>
          <button className={`btn sm ${tool === "erase" ? "primary" : ""}`} onClick={() => { setTool("erase"); setDrawFrom(null); }}>
            🧹 ลบเส้น (คลิกที่เส้น)
          </button>
          <span className="spacer"/>
          {tool === "draw" && <span style={{fontSize: 12, color: "var(--info)", padding: "4px 8px"}}>
            {drawFrom ? `📍 เลือกการ์ดที่ 2 เพื่อเชื่อมกับ ${drawFrom}` : "เลือกการ์ดแรก..."}
          </span>}
          {tool === "erase" && <span style={{fontSize: 12, color: "var(--danger)", padding: "4px 8px"}}>🖱 คลิกเส้นที่ต้องการลบ</span>}
        </div>
      )}

      <div ref={containerRef} style={{
        position: "relative",
        width: "100%",
        minHeight: maxY,
        background: editMode ? "repeating-linear-gradient(0deg, var(--line-soft), var(--line-soft) 1px, transparent 1px, transparent 24px), repeating-linear-gradient(90deg, var(--line-soft), var(--line-soft) 1px, transparent 1px, transparent 24px)" : "var(--surface-2)",
        borderRadius: 8,
        overflow: "auto",
        cursor: dragging ? "grabbing" : tool === "draw" && editMode ? "crosshair" : "default"
      }}>
        {/* Connection lines */}
        <svg style={{position: "absolute", top: 0, left: 0, width: maxX, height: maxY, pointerEvents: editMode && tool === "erase" ? "auto" : "none"}}>
          {validConnections.map((conn, i) => {
            const a = positions[conn.from]; const b = positions[conn.to];
            const x1 = a.x + 70, y1 = a.y + 110;
            const x2 = b.x + 70, y2 = b.y;
            const midY = (y1 + y2) / 2;
            const path = `M ${x1} ${y1} L ${x1} ${midY} L ${x2} ${midY} L ${x2} ${y2}`;
            const eraseMode = editMode && tool === "erase";
            return (
              <g key={i}>
                <path d={path} stroke="var(--line-strong)" strokeWidth="1.5" fill="none"/>
                {eraseMode && (
                  <path d={path} stroke="transparent" strokeWidth="14" fill="none"
                    style={{cursor: "pointer", pointerEvents: "stroke"}}
                    onClick={() => deleteConnection(i)}
                    onMouseEnter={e => e.target.previousSibling.setAttribute("stroke", "var(--danger)")}
                    onMouseLeave={e => e.target.previousSibling.setAttribute("stroke", "var(--line-strong)")}/>
                )}
              </g>
            );
          })}
        </svg>

        {/* Employee nodes */}
        {D.Employees.map(emp => {
          const pos = positions[emp.id];
          if (!pos) {
            // Auto-place new emps in a grid
            const idx = D.Employees.indexOf(emp);
            const col = idx % 6, row = Math.floor(idx / 6);
            const newPos = { x: 50 + col * 170, y: 50 + row * 180 };
            positions[emp.id] = newPos;
          }
          const p = positions[emp.id];
          const isOwner = emp.id === "EMP-001";
          const photoUrl = photos[emp.id];
          const isDrawSelected = drawFrom === emp.id;
          return (
            <div key={emp.id} onMouseDown={(e) => onMouseDown(e, emp.id)}
              style={{
                position: "absolute", left: p.x, top: p.y, width: 140, padding: 10,
                background: isOwner ? "var(--accent)" : "var(--surface)",
                color: isOwner ? "var(--accent-ink)" : "var(--ink-1)",
                border: `2px solid ${isDrawSelected ? "var(--info)" : isOwner ? "var(--accent)" : "var(--line-strong)"}`,
                borderRadius: 10,
                boxShadow: dragging?.id === emp.id || isDrawSelected ? "0 8px 20px rgba(0,0,0,0.2)" : "var(--shadow-sm)",
                cursor: editMode ? (tool === "draw" ? "pointer" : dragging?.id === emp.id ? "grabbing" : "grab") : "default",
                userSelect: "none",
                transition: dragging?.id === emp.id ? "none" : "box-shadow 0.15s",
                textAlign: "center", zIndex: dragging?.id === emp.id ? 10 : 1
              }}>
              <div style={{position: "relative", width: 56, height: 56, margin: "0 auto 6px"}}>
                {photoUrl ? (
                  <img src={photoUrl} alt={emp.name} style={{width: 56, height: 56, borderRadius: "50%", objectFit: "cover", border: `2px solid ${isOwner ? "rgba(255,255,255,0.3)" : "var(--line)"}`}}/>
                ) : (
                  <div style={{width: 56, height: 56, borderRadius: "50%", background: isOwner ? "rgba(255,255,255,0.18)" : "var(--surface-3)", color: isOwner ? "var(--accent-ink)" : "var(--ink-2)", display: "grid", placeItems: "center", fontWeight: 600, fontSize: 18, border: `2px solid ${isOwner ? "rgba(255,255,255,0.3)" : "var(--line)"}`}}>{emp.name.slice(0, 2)}</div>
                )}
                {editMode && tool === "move" && (
                  <label style={{position: "absolute", bottom: -2, right: -2, width: 22, height: 22, borderRadius: "50%", background: "var(--ink-1)", color: "var(--bg)", display: "grid", placeItems: "center", cursor: "pointer", border: "2px solid var(--surface)", fontSize: 11}} title="อัปโหลดรูป" onMouseDown={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}>
                    <I.upload size={10}/>
                    <input type="file" accept="image/*" style={{display: "none"}} onChange={(e) => onUploadPhoto(emp.id, e)}/>
                  </label>
                )}
              </div>
              <div style={{fontSize: 12, fontWeight: 600, lineHeight: 1.2, marginBottom: 2}}>{emp.name}</div>
              <div style={{fontSize: 10.5, opacity: isOwner ? 0.75 : 1, color: isOwner ? undefined : "var(--ink-3)"}}>{emp.role}</div>
              <div className="mono" style={{fontSize: 9, opacity: 0.6, marginTop: 4}}>{emp.id}</div>
            </div>
          );
        })}
      </div>

      <div style={{marginTop: 10, padding: 10, background: "var(--info-bg)", color: "var(--info)", borderRadius: 6, fontSize: 12}}>
        💡 <b>วิธีใช้:</b> {editMode ? (
          tool === "move" ? "ลากการ์ดเพื่อย้าย · คลิกไอคอน 📤 เพื่ออัปโหลดรูป" :
          tool === "draw" ? "คลิกการ์ด 2 ใบ เพื่อสร้างเส้นเชื่อม" :
          "คลิกที่เส้นที่ต้องการลบ (เส้นจะเปลี่ยนเป็นสีแดงเมื่อเลื่อนเมาส์ผ่าน)"
        ) : "กดปุ่ม 'แก้ไข' เพื่อเข้าโหมดแก้ — มีเครื่องมือ ลากย้าย / วาดเส้น / ลบเส้น"}
      </div>
    </Card>
  );
}

// ============ Users + Permissions ============
function Users({ navigate }) {
  const D = window.SSSData;
  const { Btn, Badge, Card, PageHead, Tabs } = window.UI;
  const [tab, setTab] = useStateMisc("users");
  return (
    <>
      <PageHead title="ผู้ใช้และสิทธิ์การเข้าถึง" sub="จัดการ username · password · บทบาท · สิทธิ์เข้าถึง"
        right={<Btn icon={I.plus} kind="primary">เพิ่มผู้ใช้</Btn>}/>

      <Tabs items={[
        { key: "users", label: "ผู้ใช้", count: D.Users.length },
        { key: "roles", label: "บทบาทและสิทธิ์", count: D.Roles.length },
        { key: "audit", label: "Audit log" }
      ]} active={tab} onChange={setTab}/>

      {tab === "users" && (
        <Card flush>
          <table className="t">
            <thead><tr><th>Username</th><th>ชื่อ</th><th>อีเมล</th><th>บทบาท</th><th>เข้าสู่ระบบล่าสุด</th><th>สถานะ</th><th></th></tr></thead>
            <tbody>
              {D.Users.map(u => (
                <tr key={u.id}>
                  <td className="mono">{u.username}</td>
                  <td>{u.name}</td>
                  <td className="muted">{u.email}</td>
                  <td><Badge>{u.role}</Badge></td>
                  <td className="muted">{u.lastLogin}</td>
                  <td><Badge tone="success" dot>ใช้งานอยู่</Badge></td>
                  <td><div style={{display: "flex", gap: 4}}><Btn size="sm" kind="ghost" icon={I.edit}/><Btn size="sm" kind="ghost" icon={I.shield}>สิทธิ์</Btn></div></td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>
      )}

      {tab === "roles" && (
        <Card flush>
          <table className="t">
            <thead><tr><th>บทบาท</th><th className="right">ผู้ใช้</th><th>ขาย</th><th>ซื้อ</th><th>คลัง</th><th>เงินเดือน</th><th>บัญชี</th><th>ตั้งค่า</th><th></th></tr></thead>
            <tbody>
              {D.Roles.map(r => (
                <tr key={r.name}>
                  <td><b>{r.name}</b></td>
                  <td className="right">{r.users}</td>
                  <PermCell v={r.perms.sales}/>
                  <PermCell v={r.perms.purchase}/>
                  <PermCell v={r.perms.inventory}/>
                  <PermCell v={r.perms.payroll}/>
                  <PermCell v={r.perms.accounting}/>
                  <PermCell v={r.perms.settings}/>
                  <td><Btn size="sm" kind="ghost" icon={I.edit}/></td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>
      )}

      {tab === "audit" && (
        <Card flush>
          <table className="t">
            <thead><tr><th>เวลา</th><th>ผู้ใช้</th><th>การกระทำ</th><th>IP</th></tr></thead>
            <tbody>
              <tr><td className="mono" style={{fontSize: 12}}>22/05/26 09:12</td><td>piya</td><td>เข้าสู่ระบบ</td><td className="mono" style={{fontSize: 12}}>192.168.1.20</td></tr>
              <tr><td className="mono" style={{fontSize: 12}}>22/05/26 09:05</td><td>nanthaporn</td><td>สร้างใบเสนอราคา QO-2569-0117</td><td className="mono" style={{fontSize: 12}}>192.168.1.45</td></tr>
              <tr><td className="mono" style={{fontSize: 12}}>22/05/26 08:32</td><td>duangjai</td><td>แก้ไขสินค้า SS304-SH-1.5 · เปลี่ยนต้นทุน</td><td className="mono" style={{fontSize: 12}}>192.168.1.32</td></tr>
              <tr><td className="mono" style={{fontSize: 12}}>21/05/26 17:42</td><td>wanpen</td><td>ยื่น ภ.ง.ด.1 เม.ย. 2569 ทาง e-filing</td><td className="mono" style={{fontSize: 12}}>192.168.1.31</td></tr>
              <tr><td className="mono" style={{fontSize: 12}}>21/05/26 14:00</td><td>piya</td><td>อนุมัติ PO-2569-0097 (฿380,000)</td><td className="mono" style={{fontSize: 12}}>192.168.1.20</td></tr>
            </tbody>
          </table>
        </Card>
      )}
    </>
  );
}

function PermCell({ v }) {
  const tone = v === "ทั้งหมด" ? "success" : v === "—" ? "outline" : v === "ดู" ? "info" : "warning";
  return <td><window.UI.Badge tone={tone}>{v}</window.UI.Badge></td>;
}

// ============ Projects / Job costing ============
function Projects({ navigate }) {
  const D = window.SSSData;
  const { Btn, Badge, Card, PageHead, fmt0 } = window.UI;
  return (
    <>
      <PageHead title="โปรเจกต์/งาน · Job Costing" sub="ติดตามต้นทุนจริงเทียบกับงบประมาณของแต่ละงาน"
        right={<Btn icon={I.plus} kind="primary">สร้างโปรเจกต์</Btn>}/>

      <div className="grid cols-4 mb-lg">
        <window.UI.Stat label="โปรเจกต์เปิดอยู่" value={D.Projects.filter(p=>p.status!=='ส่งงาน').length} icon={I.briefcase}/>
        <window.UI.Stat label="งบประมาณรวม" value={`฿${fmt0(D.Projects.reduce((s,p)=>s+p.budget,0))}`} sub="WIP value" icon={I.calc}/>
        <window.UI.Stat label="ต้นทุนใช้ไป" value={`฿${fmt0(D.Projects.reduce((s,p)=>s+p.actual,0))}`} sub={`${(D.Projects.reduce((s,p)=>s+p.actual,0)/D.Projects.reduce((s,p)=>s+p.budget,0)*100).toFixed(0)}% ของงบ`} icon={I.receipt}/>
        <window.UI.Stat label="กำลังครบกำหนด" value={2} sub="ใน 7 วันข้างหน้า" dir="down" icon={I.bell}/>
      </div>

      <Card flush>
        <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>ความคืบหน้า</th><th>ครบกำหนด</th><th>สถานะ</th></tr></thead>
          <tbody>
            {D.Projects.map(p => {
              const left = p.budget - p.actual;
              const overBudget = p.actual > p.budget;
              return (
                <tr key={p.code}>
                  <td className="mono">{p.code}</td>
                  <td>{p.name}</td>
                  <td className="muted">{p.customer}</td>
                  <td>{p.lead}</td>
                  <td className="right amount">฿{fmt0(p.budget)}</td>
                  <td className="right amount">฿{fmt0(p.actual)}</td>
                  <td className="right amount" style={{color: overBudget ? "var(--danger)" : "var(--ink-1)"}}>฿{fmt0(left)}</td>
                  <td style={{minWidth: 140}}><window.ProgressBar pct={p.progress}/></td>
                  <td className="muted">{p.due}</td>
                  <td><Badge>{p.status}</Badge></td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </Card>
    </>
  );
}

// ============ Activity / team chat feed ============
function ActivityPage({ navigate }) {
  const D = window.SSSData;
  const { Btn, Badge, Card, PageHead, Tabs } = window.UI;
  const [tab, setTab] = useStateMisc("ops");
  const [msg, setMsg] = useStateMisc("");
  const [activityList, setActivityList] = useStateMisc(() => {
    try { return JSON.parse(localStorage.getItem("sss-activity-log") || "[]"); } catch { return []; }
  });

  React.useEffect(() => {
    const handler = () => {
      try { setActivityList(JSON.parse(localStorage.getItem("sss-activity-log") || "[]")); } catch {}
    };
    window.addEventListener("sss-activity-changed", handler);
    return () => window.removeEventListener("sss-activity-changed", handler);
  }, []);

  // Merge stored log with default Activity, dedupe by ts
  const mergedActivity = [...activityList, ...D.Activity.filter(a => !activityList.find(b => b.ts && b.ts === a.ts))];

  return (
    <>
      <PageHead title="กิจกรรมและแชท" sub="งานส่งของวันนี้ · งานประจำวัน · ฟีดความเคลื่อนไหว · แชทภายในทีม"/>

      <Tabs items={[
        { key: "ops", label: "งานวันนี้" },
        { key: "tasks", label: "งานประจำวัน" },
        { key: "feed", label: "ฟีดและแชท", count: mergedActivity.length }
      ]} active={tab} onChange={setTab}/>

      {tab === "ops" && (
        <div style={{display: "flex", flexDirection: "column", gap: 14}}>
          <window.DeliveryBoard/>
        </div>
      )}

      {tab === "tasks" && <window.DailyTasksPanel/>}

      {tab === "feed" && (
        <div className="feed-chat-grid">
          <Card title="ฟีดล่าสุด" sub={`${mergedActivity.length} รายการ`}>
            {mergedActivity.slice(0, 50).map((a, i) => (
              <div key={i} className="activity-item">
                <div className="avatar" style={{width: 32, height: 32, fontSize: 11}}>{(a.user || "?").slice(0,2)}</div>
                <div style={{flex: 1}}>
                  <div className="what"><b style={{color: "var(--ink-1)"}}>{a.user}</b> {a.action} <span style={{color: "var(--ink-1)"}}>{a.target}</span></div>
                  <div className="when">{a.when}</div>
                </div>
                {a.photo && <a href={a.photo} target="_blank" rel="noreferrer" title="ดูรูปหลักฐาน" style={{flexShrink: 0}}>
                  <img src={a.photo} alt="หลักฐาน" style={{width: 38, height: 38, objectFit: "cover", borderRadius: 7, border: "1px solid var(--line)", display: "block"}}/>
                </a>}
                <Badge tone={
                  a.type === "create" ? "info" : a.type === "approve" ? "success" :
                  a.type === "delete" ? "danger" :
                  a.type === "stock" ? "warning" : a.type === "expense" ? "outline" :
                  a.type === "tax" ? "info" : a.type === "comment" ? "" : "outline"
                }>{a.type}</Badge>
              </div>
            ))}
          </Card>

          <window.TeamChatPanel/>
        </div>
      )}
    </>
  );
}

function ChatMsg({ who, name, time, msg, me }) {
  return (
    <div style={{display: "flex", gap: 8, flexDirection: me ? "row-reverse" : "row"}}>
      {!me && <div className="avatar" style={{width: 26, height: 26, fontSize: 10}}>{who}</div>}
      <div style={{maxWidth: "75%"}}>
        {!me && <div style={{fontSize: 11, color: "var(--ink-3)", marginBottom: 2}}>{name} · {time}</div>}
        {me && <div style={{fontSize: 11, color: "var(--ink-3)", marginBottom: 2, textAlign: "right"}}>{time}</div>}
        <div style={{padding: "6px 10px", background: me ? "var(--accent)" : "var(--surface-2)", color: me ? "var(--accent-ink)" : "var(--ink-1)", borderRadius: me ? "10px 10px 2px 10px" : "10px 10px 10px 2px"}}>{msg}</div>
      </div>
    </div>
  );
}

// ============ Settings ============
function DocColorsSettings() {
  const { Btn, Card } = window.UI;
  const [themes, setThemes] = useStateMisc(() => window.loadDocThemes());
  const docTypes = Object.keys(window.DEFAULT_DOC_THEMES);
  const presets = [
    "#c2410c", "#dc2626", "#be123c", "#9f1239",
    "#15803d", "#0d9488", "#0369a1", "#1d4ed8",
    "#1e3a8a", "#4338ca", "#7e22ce", "#a21caf",
    "#0c0a09", "#44403c", "#78716c"
  ];

  const update = (key, color) => {
    const next = { ...themes, [key]: { ...themes[key], color } };
    setThemes(next);
    window.saveDocThemes(next);
  };
  const resetAll = () => {
    // เขียนค่าว่างแทน removeItem — คีย์นี้ sync แล้ว การลบเฉย ๆ จะถูกค่าเดิมจาก server เขียนกลับ
    localStorage.setItem("sss-doc-themes", "{}");
    setThemes(window.DEFAULT_DOC_THEMES);
    window.dispatchEvent(new Event("sss-themes-changed"));
  };

  return (
    <div className="grid cols-2">
      <Card title="สีหัวเอกสาร" sub="ตั้งสีต่างกันสำหรับเอกสารแต่ละประเภท" right={<Btn size="sm" kind="ghost" onClick={resetAll}>คืนค่าเริ่มต้น</Btn>}>
        <div style={{display: "flex", flexDirection: "column", gap: 12}}>
          {docTypes.map(t => (
            <div key={t} style={{display: "flex", alignItems: "center", gap: 12, padding: "8px 4px", borderBottom: "1px solid var(--line-soft)"}}>
              <div style={{width: 4, height: 36, background: themes[t].color, borderRadius: 2}}/>
              <div style={{flex: 1}}>
                <div style={{fontWeight: 500, fontSize: 13}}>{window.DOC_LABEL_TH[t]}</div>
                <div className="muted" style={{fontSize: 11}}>{t} · {themes[t].color}</div>
              </div>
              <div style={{display: "flex", gap: 4, flexWrap: "wrap", maxWidth: 280, justifyContent: "flex-end"}}>
                {presets.map(p => (
                  <button key={p} title={p} onClick={() => update(t, p)}
                    style={{
                      width: 22, height: 22, borderRadius: 4,
                      background: p, cursor: "pointer",
                      border: themes[t].color === p ? "2px solid var(--ink-1)" : "1px solid var(--line)",
                      padding: 0
                    }}/>
                ))}
                <input type="color" value={themes[t].color} onChange={e => update(t, e.target.value)}
                  style={{width: 28, height: 22, border: "1px solid var(--line)", borderRadius: 4, padding: 0, cursor: "pointer", background: "transparent"}}/>
              </div>
            </div>
          ))}
        </div>
      </Card>

      <Card title="ตัวอย่าง" sub="แสดงสีปัจจุบันของแต่ละเอกสาร">
        <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10}}>
          {docTypes.map(t => (
            <div key={t} style={{border: "1px solid var(--line)", borderTop: `4px solid ${themes[t].color}`, borderRadius: 6, padding: 12, background: "var(--surface)"}}>
              <div style={{fontSize: 10, color: themes[t].color, fontWeight: 700, letterSpacing: "0.05em", marginBottom: 2}}>{window.DOC_LABEL_TH[t].toUpperCase()}</div>
              <div className="mono" style={{fontSize: 10, color: "var(--ink-3)"}}>QO-2569-XXXX</div>
              <div style={{marginTop: 8, height: 4, background: themes[t].color, borderRadius: 2, opacity: 0.3}}/>
              <div style={{marginTop: 8, padding: 4, background: themes[t].color, color: "white", borderRadius: 3, fontSize: 10, textAlign: "right", fontWeight: 600}}>฿ 412,000.00</div>
            </div>
          ))}
        </div>
        <div style={{marginTop: 14, padding: 10, background: "var(--surface-2)", borderRadius: 6, fontSize: 12, color: "var(--ink-3)"}}>
          <b style={{color: "var(--ink-1)"}}>เคล็ดลับ:</b> เมื่อกด "พิมพ์" ในหน้าสร้างเอกสาร — ในกล่องพิมพ์ของเบราว์เซอร์ ให้ปิด "Headers and footers" และเลือก "Background graphics" เพื่อให้พิมพ์สีออกมาสวย
        </div>
      </Card>
    </div>
  );
}

window.DocColorsSettings = DocColorsSettings;

// ============ ตั้งค่าหมายเหตุเอกสารสำเร็จรูป ============
function DocNotesSettings() {
  const { Btn, Card } = window.UI;
  const [items, setItems] = useStateMisc(() => window.DocNotePresets ? window.DocNotePresets.load() : []);
  const upd = (i, v) => setItems(list => list.map((x, j) => j === i ? v : x));
  const add = () => setItems(list => [...list, "• "]);
  const del = (i) => setItems(list => list.filter((_, j) => j !== i));
  const save = () => {
    const cleaned = items.map(s => s.trim()).filter(Boolean);
    window.DocNotePresets.save(cleaned);
    setItems(cleaned);
    window.toast && window.toast("บันทึกหมายเหตุเอกสารแล้ว — จะขึ้นเป็นตัวเลือกตอนสร้างเอกสาร");
  };
  return (
    <Card title="ตั้งค่าหมายเหตุเอกสาร" sub="ข้อความสำเร็จรูปที่จะให้เลือกไปใส่ในช่องหมายเหตุเวลาสร้างเอกสาร"
      right={<div style={{display: "flex", gap: 6}}><Btn size="sm" kind="ghost" icon={I.refresh || I.calc} onClick={() => setItems([...(window.DocNotePresets.DEFAULTS)])}>ค่าเริ่มต้น</Btn><Btn size="sm" kind="primary" icon={I.check} onClick={save}>บันทึก</Btn></div>}>
      <div style={{display: "flex", flexDirection: "column", gap: 8}}>
        {items.map((it, i) => (
          <div key={i} style={{display: "flex", gap: 8, alignItems: "center"}}>
            <span style={{fontSize: 11, color: "var(--ink-3)", width: 20}}>{i + 1}</span>
            <input className="input" value={it} onChange={e => upd(i, e.target.value)} placeholder="• ข้อความหมายเหตุ" style={{flex: 1}}/>
            <button className="icon-btn" title="ลบ" onClick={() => del(i)}><I.trash size={13}/></button>
          </div>
        ))}
        <Btn size="sm" kind="ghost" icon={I.plus} onClick={add}>เพิ่มข้อความหมายเหตุ</Btn>
      </div>
    </Card>
  );
}
window.DocNotesSettings = DocNotesSettings;

// ── ตราประทับบริษัท — ใช้แนบท้ายเอกสารขาย/ซื้อ (ติ๊ก "แนบลายเซ็น+ตรา" ตอนออกเอกสาร) ──
function StampSettings() {
  const { Btn, Card } = window.UI;
  const [, force] = useStateMisc(0);
  const assets = (window.lsSyncGet && window.lsSyncGet("sss-doc-sign-assets")) || {};
  const onPickAsset = (e, field, maxPx) => {
    const file = e.target.files[0]; e.target.value = "";
    if (!file) return;
    if (!/image\/(png|jpe?g)/.test(file.type)) { window.toast && window.toast("รองรับเฉพาะ .jpg และ .png (แนะนำ .png พื้นโปร่งใส)"); return; }
    const rd = new FileReader();
    rd.onload = () => {
      const img = new Image();
      img.onload = () => {
        try {
          const s = Math.min(1, (maxPx || 480) / Math.max(img.width, img.height));
          const c = document.createElement("canvas");
          c.width = Math.max(1, Math.round(img.width * s));
          c.height = Math.max(1, Math.round(img.height * s));
          c.getContext("2d").drawImage(img, 0, 0, c.width, c.height);
          const url = file.type === "image/png" ? c.toDataURL("image/png") : c.toDataURL("image/jpeg", 0.85);
          const next = Object.assign({}, (window.lsSyncGet && window.lsSyncGet("sss-doc-sign-assets")) || {});
          next[field] = url;
          window.lsSyncSet && window.lsSyncSet("sss-doc-sign-assets", next);
          force(n => n + 1);
          window.toast && window.toast((field === "logo" ? "บันทึกโลโก้บริษัทแล้ว" : "บันทึกตราประทับบริษัทแล้ว") + " (ซิงค์ทุกเครื่อง)");
        } catch (err) { window.toast && window.toast("อ่านรูปไม่สำเร็จ"); }
      };
      img.src = rd.result;
    };
    rd.readAsDataURL(file);
  };
  const onPick = (e) => onPickAsset(e, "stamp", 480);
  const removeAsset = (field) => {
    const next = Object.assign({}, (window.lsSyncGet && window.lsSyncGet("sss-doc-sign-assets")) || {});
    delete next[field];
    window.lsSyncSet && window.lsSyncSet("sss-doc-sign-assets", next);
    force(n => n + 1);
  };
  const remove = () => removeAsset("stamp");
  return (
    <Card title="โลโก้ & ตราประทับบริษัท" sub="โลโก้ขึ้นหัวเอกสารทุกใบ · ตราประทับใช้เมื่อติ๊ก 'แนบลายเซ็น+ตราประทับ' ตอนออกเอกสาร" className="mb-lg">
      <div style={{display: "flex", gap: 14, alignItems: "center", flexWrap: "wrap", marginBottom: 16, paddingBottom: 14, borderBottom: "1px solid var(--line)"}}>
        <img src={assets.logo || "assets/logo-ink.png"} alt="โลโก้" style={{height: 64, maxWidth: 220, objectFit: "contain", background: "#0c0a09", border: "1px solid var(--line)", borderRadius: 10, padding: 8}}/>
        <div style={{display: "flex", flexDirection: "column", gap: 8}}>
          <label className="btn" style={{cursor: "pointer", width: "fit-content"}}>
            <input type="file" accept=".png,.jpg,.jpeg,image/png,image/jpeg" style={{display: "none"}} onChange={(e) => onPickAsset(e, "logo", 560)}></input>
            🏷️ อัพโหลดโลโก้ใหม่ (.png พื้นโปร่งใสแนะนำ)
          </label>
          {assets.logo && <Btn size="sm" kind="ghost" onClick={() => removeAsset("logo")}>กลับไปใช้โลโก้เดิม</Btn>}
          <div style={{fontSize: 11.5, color: "var(--ink-3)"}}>แสดงบนหัวเอกสารทุกใบ — พื้นหลังหัวเอกสารเป็นสีเข้ม โลโก้สีขาว/สว่างชัดสุด</div>
        </div>
      </div>
      <div style={{display: "flex", gap: 14, alignItems: "center", flexWrap: "wrap"}}>
        {assets.stamp
          ? <img src={assets.stamp} alt="ตราประทับ" style={{width: 110, height: 110, objectFit: "contain", background: "white", border: "1px solid var(--line)", borderRadius: 10, padding: 6}}/>
          : <div style={{width: 110, height: 110, border: "1.5px dashed var(--line-strong)", borderRadius: "50%", display: "grid", placeItems: "center", color: "var(--ink-4)", fontSize: 11, textAlign: "center"}}>ยังไม่มี<br/>ตราประทับ</div>}
        <div style={{display: "flex", flexDirection: "column", gap: 8}}>
          <label className="btn" style={{cursor: "pointer", width: "fit-content"}}>
            <input type="file" accept=".png,.jpg,.jpeg,image/png,image/jpeg" style={{display: "none"}} onChange={onPick}></input>
            📤 อัพโหลดตราประทับ (.png แนะนำ / .jpg)
          </label>
          {assets.stamp && <Btn size="sm" kind="ghost" onClick={remove}>ลบตราประทับ</Btn>}
          <div style={{fontSize: 11.5, color: "var(--ink-3)"}}>ลายเซ็นของผู้ใช้แต่ละคน ตั้งได้ที่เมนู <b>ผู้ใช้และสิทธิ์ → แก้ไขผู้ใช้</b></div>
        </div>
      </div>
    </Card>
  );
}

function Settings({ navigate }) {
  const D = window.SSSData;
  const { Btn, Card, PageHead, Tabs, Switch } = window.UI;
  const [tab, setTab] = useStateMisc("company");
  return (
    <>
      <PageHead title="ตั้งค่าระบบ" sub="ข้อมูลบริษัท · หัวบิล · เลขรันเอกสาร · การแจ้งเตือน · การเชื่อมต่อ"/>

      <Tabs items={[
        { key: "company", label: "ข้อมูลบริษัท" },
        { key: "doc", label: "เอกสาร & เลขรัน" },
        { key: "colors", label: "สีเอกสาร" },
        { key: "notes", label: "ตั้งค่าหมายเหตุเอกสาร" },
        { key: "tax", label: "ภาษี & VAT" },
        { key: "notify", label: "การแจ้งเตือน" },
        { key: "integr", label: "การเชื่อมต่อ" }
      ]} active={tab} onChange={setTab}/>

      {tab === "company" && <>
        <CompanySettings/>
        <StampSettings/>
      </>}

      {tab === "doc" && (
        <Card title="รูปแบบเลขรันเอกสาร" right={<Btn size="sm" kind="primary">บันทึก</Btn>}>
          <div className="label mb">รูปแบบ: <code>[Prefix]-[YYBE]-[####]</code> เช่น QO-2569-0117</div>
          <table className="t" style={{border: "1px solid var(--line)", borderRadius: 8}}>
            <thead><tr><th>เอกสาร</th><th>Prefix</th><th>ค่าปัจจุบัน</th><th>เลขถัดไป</th><th>Reset ทุก</th></tr></thead>
            <tbody>
              {[
                ["ใบเสนอราคา", "QO", "QO-2569-0117", "QO-2569-0118", "ปี"],
                ["ใบสั่งซื้อ", "PO", "PO-2569-0098", "PO-2569-0099", "ปี"],
                ["ใบส่งสินค้า", "DN", "DN-2569-0188", "DN-2569-0189", "ปี"],
                ["ใบแจ้งหนี้", "INV", "INV-2569-0204", "INV-2569-0205", "ปี"],
                ["ใบกำกับภาษี", "TX", "TX-2569-0204", "TX-2569-0205", "ปี"],
                ["ใบวางบิล", "BN", "BN-2569-0044", "BN-2569-0045", "ปี"],
                ["ค่าใช้จ่าย", "EX", "EX-2569-0156", "EX-2569-0157", "ปี"],
                ["ใบสำคัญจ่าย", "PV", "PV-2569-0078", "PV-2569-0079", "ปี"]
              ].map(r => (
                <tr key={r[1]}><td>{r[0]}</td><td className="mono"><input className="input" style={{width: 80, height: 26}} defaultValue={r[1]}/></td><td className="mono">{r[2]}</td><td className="mono" style={{color: "var(--ink-3)"}}>{r[3]}</td><td>{r[4]}</td></tr>
              ))}
            </tbody>
          </table>
        </Card>
      )}

      {tab === "colors" && <DocColorsSettings/>}
      {tab === "notes" && <DocNotesSettings/>}

      {tab === "tax" && (
        <Card title="การตั้งค่าภาษี" right={<Btn size="sm" kind="primary">บันทึก</Btn>}>
          <div className="field-row cols-2">
            <div className="field"><label>อัตรา VAT</label><div style={{display: "flex", gap: 8, alignItems: "center"}}><input className="input" defaultValue="7" style={{width: 80}}/><span className="muted">%</span><Switch on={true}/><span>เก็บ VAT</span></div></div>
            <div className="field"><label>วิธีเก็บภาษี</label><select className="input"><option>คำนวณก่อนลด</option><option>คำนวณหลังลด</option></select></div>
            <div className="field"><label>เริ่มงวด VAT</label><select className="input"><option>วันที่ 1 ของเดือน</option></select></div>
            <div className="field"><label>เลข Outlet (ถ้ามี)</label><input className="input" defaultValue="00000"/></div>
          </div>
          <div className="divider"/>
          <div className="label mb">อัตราหัก ณ ที่จ่ายมาตรฐาน</div>
          <table className="t">
            <thead><tr><th>ประเภท</th><th>แบบ</th><th>อัตรา</th></tr></thead>
            <tbody>
              <tr><td>ค่าบริการบุคคลธรรมดา</td><td>ภ.ง.ด.3</td><td>3%</td></tr>
              <tr><td>ค่าบริการนิติบุคคล</td><td>ภ.ง.ด.53</td><td>3%</td></tr>
              <tr><td>ค่าเช่าอสังหาริมทรัพย์</td><td>ภ.ง.ด.3/53</td><td>5%</td></tr>
              <tr><td>ค่าโฆษณา</td><td>ภ.ง.ด.3/53</td><td>2%</td></tr>
              <tr><td>ค่าขนส่ง</td><td>ภ.ง.ด.3/53</td><td>1%</td></tr>
            </tbody>
          </table>
        </Card>
      )}

      {tab === "notify" && (
        <Card title="การแจ้งเตือน">
          <div style={{display: "flex", flexDirection: "column", gap: 14}}>
            {[
              { label: "ภาษีรายเดือนใกล้ครบกำหนด (7 วันก่อน)", on: true },
              { label: "ลูกค้าค้างชำระเกินกำหนด", on: true },
              { label: "สินค้าใกล้หมดสต็อก (ตามขั้นต่ำ)", on: true },
              { label: "ใบเสนอราคารออนุมัติ > 24 ชม.", on: true },
              { label: "PO รออนุมัติ > 12 ชม.", on: true },
              { label: "เงินเดือนใกล้ถึงรอบจ่าย (3 วันก่อน)", on: true },
              { label: "ส่งรายงานสรุปรายเดือนทางอีเมล (ทุกวันที่ 1)", on: false },
              { label: "พนักงานครบกำหนดทดลองงาน", on: true }
            ].map(n => (
              <div key={n.label} style={{display: "flex", alignItems: "center", gap: 12}}>
                <Switch on={n.on}/>
                <span style={{fontSize: 13}}>{n.label}</span>
              </div>
            ))}
          </div>
          <div className="divider"/>
          <div className="field-row cols-2">
            <div className="field"><label>ส่งแจ้งเตือนไปที่</label><input className="input" defaultValue="piya@triplescreative.co.th, wanpen@triplescreative.co.th"/></div>
            <div className="field"><label>ช่องทาง</label><div style={{display: "flex", gap: 8, paddingTop: 4}}><Switch on={true}/> Email <Switch on={true}/> LINE <Switch on={false}/> SMS</div></div>
          </div>
        </Card>
      )}

      {tab === "integr" && (
        <div className="grid cols-2">
          {[
            { name: "K-Cyber Banking", desc: "โอนเงินเดือน/Vendor แบบ bulk", on: true },
            { name: "e-Filing กรมสรรพากร", desc: "ยื่นภาษีออนไลน์ตรงจากระบบ", on: true },
            { name: "e-Tax Invoice & e-Receipt", desc: "ส่งใบกำกับภาษีอิเล็กทรอนิกส์", on: true },
            { name: "LINE Notify", desc: "แจ้งเตือนเข้ากลุ่ม LINE บริษัท", on: true },
            { name: "Google Calendar", desc: "Sync ปฏิทินภาษี + กำหนดส่ง", on: false },
            { name: "Microsoft 365 / Outlook", desc: "ส่งใบเสนอราคาทางอีเมล", on: true },
            { name: "Shopee / Lazada", desc: "Sync สต็อกสำหรับช่องทางออนไลน์", on: false },
            { name: "Fusion 360 / SolidWorks", desc: "นำเข้า BOM จากแบบ 3D CAD", on: false }
          ].map(it => (
            <Card key={it.name}>
              <div style={{display: "flex", justifyContent: "space-between", alignItems: "center"}}>
                <div>
                  <div style={{fontWeight: 500, marginBottom: 2}}>{it.name}</div>
                  <div className="muted" style={{fontSize: 12}}>{it.desc}</div>
                </div>
                <Switch on={it.on}/>
              </div>
            </Card>
          ))}
        </div>
      )}
    </>
  );
}

window.Customers = Customers;
window.Vendors = Vendors;
window.HR = HR;
window.Users = Users;
window.Projects = Projects;
window.ActivityPage = ActivityPage;
window.Settings = Settings;
window.NewCustomerDrawer = NewCustomerDrawer;
window.NewVendorDrawer = NewVendorDrawer;
