/* global React, I, UI, SSSData, bahtText */
const { Btn, Badge, Card, PageHead, Tabs, Drawer, Workflow, fmt0, fmtM } = window.UI;
const { useState } = React;

// ============ Generic doc list page ============
function DocListPage({ title, sub, columns, rows, statusFilter, onRowClick, onCreate, createLabel, kpis, docType }) {
  const [tab, setTab] = useState("all");
  const [q, setQ] = useState("");
  const [dateF, setDateF] = useState({ mode: "all" });
  const [selected, setSelected] = useState(new Set());
  const statuses = statusFilter || [];

  const filtered = rows.filter(r => {
    const matchesTab = tab === "all" || r.status === tab;
    const matchesQ = !q || JSON.stringify(r).toLowerCase().includes(q.toLowerCase());
    const matchesDate = !window.DocDates || window.DocDates.match(dateF, r.date);
    return matchesTab && matchesQ && matchesDate;
  });

  const idKey = columns.find(c => c.key === "no") ? "no" : columns[0].key;
  const allSelected = filtered.length > 0 && filtered.every(r => selected.has(r[idKey]));
  const someSelected = selected.size > 0 && !allSelected;

  const toggleAll = () => {
    if (allSelected) {
      setSelected(new Set());
    } else {
      setSelected(new Set(filtered.map(r => r[idKey])));
    }
  };
  const toggleOne = (id) => {
    const next = new Set(selected);
    if (next.has(id)) next.delete(id); else next.add(id);
    setSelected(next);
  };

  const printSelected = async () => {
    const opts = await window.printWithOptions();
    if (!opts) return;
    // Build combined HTML — render each selected row's doc paper if possible
    // Strategy: open the first .doc-paper in DOM as template; here we just show stack
    const selectedRows = filtered.filter(r => selected.has(r[idKey]));
    window.printBulkDocs && window.printBulkDocs(selectedRows, opts, docType, title);
  };

  return (
    <>
      <PageHead
        title={title}
        sub={sub}
        right={<>
          <Btn icon={I.download} kind="ghost" onClick={() => window.exportRowsCSV(title.split("·")[0].trim(), columns, filtered)}>ส่งออก Excel</Btn>
          <Btn icon={I.plus} kind="primary" onClick={onCreate}>{createLabel}</Btn>
        </>}
      />
      {kpis && (
        <div className="grid cols-4 mb-lg">
          {kpis.map((k, i) => (
            <UI.Stat key={i} label={k.label} value={k.value} sub={k.sub} deltaDir={k.dir} delta={k.delta} icon={k.icon}/>
          ))}
        </div>
      )}
      <Card flush padded={false}>
        <div style={{padding: 12, borderBottom: "1px solid var(--line)", display: "flex", gap: 10, alignItems: "center"}}>
          <Tabs
            items={[{ key: "all", label: "ทั้งหมด", count: rows.length }, ...statuses.map(s => ({ key: s, label: s, count: rows.filter(r => r.status === s).length }))]}
            active={tab}
            onChange={setTab}
          />
          <span className="spacer"/>
          {selected.size > 0 && (
            <>
              <span style={{fontSize: 12, color: "var(--ink-3)"}}>เลือก {selected.size} รายการ</span>
              <Btn size="sm" kind="ghost" onClick={() => setSelected(new Set())}>ยกเลิก</Btn>
              <Btn size="sm" icon={I.print} kind="primary" onClick={printSelected}>พิมพ์ที่เลือก ({selected.size})</Btn>
            </>
          )}
          {selected.size === 0 && <>
            <div className="search" style={{width: 260}}>
              <I.search size={14}/>
              <input placeholder="ค้นหา…" value={q} onChange={e => setQ(e.target.value)}/>
            </div>
            {window.DateFilter && <window.DateFilter value={dateF} onChange={setDateF}/>}
          </>}
        </div>
        <div className="table-wrap">
          <table className="t">
            <thead><tr>
              <th style={{width: 36, paddingLeft: 14}}>
                <input type="checkbox" checked={allSelected} ref={el => el && (el.indeterminate = someSelected)} onChange={toggleAll}/>
              </th>
              {columns.map(c => <th key={c.key} className={c.right ? "right" : ""}>{c.label}</th>)}
            </tr></thead>
            <tbody>
              {filtered.map((r, i) => (
                <tr key={i} className="row-clickable" onClick={(e) => {
                  if (e.target.type === "checkbox") return;
                  onRowClick && onRowClick(r);
                }}>
                  <td style={{paddingLeft: 14}} onClick={e => e.stopPropagation()}>
                    <input type="checkbox" checked={selected.has(r[idKey])} onChange={() => toggleOne(r[idKey])}/>
                  </td>
                  {columns.map(c => (
                    <td key={c.key} className={c.right ? "right" : c.cls || ""}>
                      {c.render ? c.render(r) : r[c.key]}
                    </td>
                  ))}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </Card>
    </>
  );
}

// ============ Delivery Note Detail ============
function DeliveryNoteDetail({ navigate }) {
  const D = window.SSSData;
  const dn = D.DeliveryNotes[0]; // DN-2569-0188 — Innofoods
  const lines = [
    { sku: "SS316-SH-2.0", name: "แผ่นสแตนเลส 316L หนา 2.0 มม. 4x8 ฟุต", qty: 22, unit: "แผ่น" },
    { sku: "SS-TUBE-32", name: "ท่อสแตนเลส 304 1-1/4\" ยาว 6 ม.", qty: 18, unit: "เส้น" },
    { sku: "PROD-RAIL-SS", name: "ราวบันไดสแตนเลส 304 ขนาดมาตรฐาน", qty: 2, unit: "ชุด" },
    { sku: "—", name: "อุปกรณ์ประกอบ (ตามแบบ JOB-2569-020)", qty: 1, unit: "lot" }
  ];
  const C = window.SSSData.Company;
  const S = window.DeliveryStore;
  const linkedDD = S ? S.load().find(x => x.ref === dn.no) : null;

  const createDailyJob = async () => {
    const list = S.load();
    const existing = list.find(x => x.ref === dn.no);
    if (existing) {
      const go = await window.confirmDialog({
        title: "มีงานส่งของที่ผูกกับใบนี้แล้ว",
        message: `ใบส่งสินค้า <b class="mono">${dn.no}</b> ผูกกับงานส่ง <b class="mono">${existing.no}</b> (${S.fmtThai(existing.date)}) อยู่แล้ว`,
        confirmText: "ไปที่ส่งของประจำวัน"
      });
      if (go) navigate("daily-delivery");
      return;
    }
    const ok = await window.confirmDialog({
      title: "สร้างงานส่งของประจำวัน",
      message: `สร้างงานส่งวันนี้จากใบส่งสินค้า <b class="mono">${dn.no}</b> — ${dn.customer}`,
      bullets: [
        `คัดลอกรายการสินค้าทั้งหมด ${lines.length} รายการ`,
        `ผูกอ้างอิงกับ ${dn.no} ให้อัตโนมัติ`,
        "แจ้งเตือนพนักงานทุกคนทุกหน้าจอ"
      ],
      confirmText: "สร้างงานส่งวันนี้"
    });
    if (!ok) return;
    const rec = S.normalize({
      id: "TD-" + Date.now(), no: S.genNo(list), date: S.todayStr(), time: "10:00",
      customer: dn.customer,
      address: "88/45 ถ.รัตนาธิเบศร์ ต.บางกระสอ อ.เมือง จ.นนทบุรี 11000",
      assignee: "", assigneeName: dn.driver || "",
      note: `จากใบส่งสินค้า ${dn.no}`, ref: dn.no, status: "รอส่ง",
      items: lines.map(l => ({ name: l.name, qty: l.qty, unit: l.unit, photo: null, checked: false })),
      photosBefore: [], photosAfter: [], signature: null, receiverName: "", deliveredAt: ""
    });
    S.save([...list, rec]);
    window.DeliveryAlertAPI && window.DeliveryAlertAPI.triggerNow();
    window.logActivity && window.logActivity("สร้างงานส่งของ", `${rec.no} จากใบส่งสินค้า ${dn.no}`, "delivery");
    window.toast && window.toast(`สร้างงานส่ง ${rec.no} จาก ${dn.no} แล้ว — แจ้งเตือนทุกคนแล้ว`);
    setTimeout(() => navigate("daily-delivery"), 450);
  };

  return (
    <>
      <PageHead
        title={<span style={{display: "flex", alignItems: "center", gap: 12}}>
          <Btn kind="ghost" size="sm" onClick={() => navigate("delivery-notes")}><I.chevronLeft size={14} className="icon"/>กลับ</Btn>
          ใบส่งสินค้า <span className="mono" style={{fontSize: 16, color: "var(--ink-3)", fontWeight: 500}}>{dn.no}</span>
        </span>}
        sub={`ลูกค้า: ${dn.customer} · ${dn.date}`}
        right={<>
          <Btn icon={I.truck} kind="ghost" onClick={createDailyJob}>{linkedDD ? `งานส่งวันนี้: ${linkedDD.no}` : "สร้างงานส่งประจำวัน"}</Btn>
          <Btn icon={I.arrowRight} kind="ghost" onClick={async () => {
            const ok = await window.confirmDialog({
              title: "แปลงเป็นใบส่งสินค้า/ใบแจ้งหนี้",
              message: `สร้างใบส่งสินค้า/ใบแจ้งหนี้จากใบส่งของ <b class="mono">${dn.no}</b> — ${dn.customer}`,
              bullets: [
                "สร้างเอกสารเลข INV-2569-0205",
                `คัดลอกรายการสินค้าทั้งหมด ${lines.length} รายการ`,
                `ผูกอ้างอิงกับ ${dn.no} ให้อัตโนมัติ`,
                "เปิดใบส่งสินค้า/ใบแจ้งหนี้ใหม่ทันที"
              ],
              confirmText: "แปลงเป็นใบแจ้งหนี้"
            });
            if (!ok) return;
            window.logActivity && window.logActivity("แปลงเอกสาร", `ใบส่งของ ${dn.no} → INV-2569-0205`, "create");
            window.toast && window.toast(`สร้างใบส่งสินค้า/ใบแจ้งหนี้ INV-2569-0205 จาก ${dn.no} แล้ว`);
            setTimeout(() => navigate("invoices/INV-2569-0204"), 600);
          }}>แปลงเป็นใบส่งสินค้า/ใบแจ้งหนี้</Btn>
          <Btn icon={I.msg} kind="ghost" onClick={() => window.toast && window.toast(`ส่งลิงก์ใบส่งสินค้า ${dn.no} ทาง LINE ให้ ${dn.customer} แล้ว`)}>แจ้งลูกค้า (LINE)</Btn>
          <Btn icon={I.print} kind="ghost" onClick={() => window.printDocPaperWithOptions()}>พิมพ์</Btn>
          <Btn icon={I.download} kind="ghost" onClick={() => window.printDocPaperWithOptions()}>PDF</Btn>
          <Btn icon={I.check} kind="primary" onClick={async () => {
            const ok = await window.confirmDialog({
              title: "บันทึกการเซ็นรับสินค้า",
              message: `ยืนยันว่าลูกค้า <b>${dn.customer}</b> เซ็นรับสินค้าตาม <b class="mono">${dn.no}</b> ครบถ้วนแล้ว`,
              confirmText: "บันทึกเซ็นรับ"
            });
            if (!ok) return;
            window.logActivity && window.logActivity("เซ็นรับสินค้า", `${dn.no} — ${dn.customer}`, "update");
            window.toast && window.toast(`บันทึกการเซ็นรับ ${dn.no} แล้ว`);
          }}>บันทึกเซ็นรับ</Btn>
        </>}
      />

      <div className="grid" style={{gridTemplateColumns: "1fr 320px", gap: 14, alignItems: "flex-start"}}>
        <div>
          <Card padded={false} className="mb-lg" flush>
            <div style={{padding: "14px 16px"}}>
              <Workflow steps={["เตรียมสินค้า", "ขึ้นรถ", "กำลังจัดส่ง", "ส่งถึงที่หมาย", "ลูกค้าเซ็นรับ"]} current={2}/>
            </div>
          </Card>

          {/* Tracking strip */}
          <Card title="ติดตามการจัดส่ง" sub="GPS realtime" className="mb-lg">
            <div style={{display: "flex", gap: 14}}>
              <div style={{flex: 1, height: 160, background: "var(--surface-2)", border: "1px dashed var(--line-strong)", borderRadius: 8, display: "grid", placeItems: "center", color: "var(--ink-3)", position: "relative", overflow: "hidden"}}>
                <div style={{position: "absolute", inset: 0, backgroundImage: "linear-gradient(0deg, var(--line) 1px, transparent 1px), linear-gradient(90deg, var(--line) 1px, transparent 1px)", backgroundSize: "30px 30px", opacity: 0.5}}/>
                <div style={{position: "absolute", left: "20%", top: "55%"}}>
                  <div style={{width: 24, height: 24, borderRadius: "50%", background: "var(--accent)", color: "var(--accent-ink)", display: "grid", placeItems: "center", boxShadow: "0 0 0 6px rgba(12,10,9,0.1)"}}><I.truck size={12}/></div>
                  <div style={{fontSize: 10, marginTop: 2, fontWeight: 600}}>รถ SSS-01</div>
                </div>
                <div style={{position: "absolute", left: "75%", top: "30%"}}>
                  <div style={{width: 16, height: 16, borderRadius: "50%", background: "var(--surface)", border: "2px solid var(--ink-1)"}}/>
                  <div style={{fontSize: 10, marginTop: 2}}>ปลายทาง</div>
                </div>
                <div style={{position: "absolute", left: "10%", top: "70%"}}>
                  <div style={{width: 12, height: 12, borderRadius: "50%", background: "var(--ink-3)"}}/>
                  <div style={{fontSize: 10, marginTop: 2, color: "var(--ink-3)"}}>โกดัง SSS</div>
                </div>
                <svg style={{position: "absolute", inset: 0, width: "100%", height: "100%"}}>
                  <path d="M 50 130 Q 200 60, 380 65" stroke="var(--ink-1)" strokeWidth="2" strokeDasharray="4 4" fill="none"/>
                </svg>
              </div>
              <div style={{width: 200, display: "flex", flexDirection: "column", gap: 10, fontSize: 12.5}}>
                <div><div className="label">ขับโดย</div><div style={{fontWeight: 500}}>{dn.driver}</div></div>
                <div><div className="label">ทะเบียน</div><div className="mono">{dn.plate}</div></div>
                <div><div className="label">ระยะทาง</div><div>34.2 กม. · 28 นาที</div></div>
                <div><div className="label">ETA</div><div style={{fontWeight: 600}}>14:48 น.</div></div>
                <Btn size="sm" icon={I.send} kind="ghost">ส่งลิงก์ติดตามให้ลูกค้า</Btn>
              </div>
            </div>
          </Card>

          {/* Doc preview */}
          <div className="doc-paper" style={{borderTop: `5px solid ${window.getDocColor("delivery-note")}`}}>
            <div style={{display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 20, marginBottom: 24}}>
              <div style={{display: "flex", gap: 20}}>
                <div style={{background: window.getDocColor("delivery-note"), borderRadius: 6, alignSelf: "stretch", minHeight: 56, maxHeight: 80, display: "flex", alignItems: "center", justifyContent: "center", padding: "8px 16px", flexShrink: 0}}><img src="assets/logo-ink.png" alt={C.name} style={{width: 132, maxHeight: "100%", objectFit: "contain", display: "block"}}/></div>
                <div>
                  <div style={{fontWeight: 700, fontSize: 14}}>{C.name}</div>
                  <div style={{fontSize: 11, color: "#57534e"}}>{C.nameEn}</div>
                  <div style={{fontSize: 11, color: "#57534e", marginTop: 4, maxWidth: 320}}>{C.address}</div>
                  <div style={{fontSize: 11, color: "#57534e"}}>โทร {C.phone}</div>
                </div>
              </div>
              <div style={{textAlign: "right"}}>
                <h1 style={{color: window.getDocColor("delivery-note")}}>ใบส่งสินค้า</h1>
                <div style={{fontSize: 10, color: "#78716c", letterSpacing: "0.06em"}}>DELIVERY NOTE</div>
                <div style={{marginTop: 8, fontSize: 12}}>
                  <div>เลขที่ <b className="mono">{dn.no}</b></div>
                  <div>วันที่ <b>{dn.date}</b></div>
                </div>
              </div>
            </div>

            <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, marginBottom: 16, fontSize: 12}}>
              <div style={{border: "1px solid #e7e5e4", padding: 10, borderRadius: 4}}>
                <div style={{fontSize: 10, color: "#78716c", textTransform: "uppercase", letterSpacing: "0.05em", marginBottom: 2}}>ผู้รับสินค้า</div>
                <div style={{fontWeight: 600}}>{dn.customer}</div>
                <div style={{color: "#57534e"}}>88/45 ถ.รัตนาธิเบศร์ ต.บางกระสอ อ.เมือง จ.นนทบุรี 11000</div>
                <div style={{color: "#57534e"}}>ผู้ติดต่อ: คุณพัชรา 02-987-6543</div>
              </div>
              <div style={{border: "1px solid #e7e5e4", padding: 10, borderRadius: 4}}>
                <div style={{fontSize: 10, color: "#78716c", textTransform: "uppercase", letterSpacing: "0.05em", marginBottom: 2}}>การจัดส่ง</div>
                <div>คนขับ: {dn.driver}</div>
                <div>ทะเบียน: {dn.plate}</div>
                <div>อ้างอิง: INV-2569-0204 · JOB-2569-020</div>
              </div>
            </div>

            <table>
              <thead><tr><th style={{width: 30}}>#</th><th>SKU</th><th>รายการ</th><th className="right" style={{width: 80}}>จำนวน</th><th style={{width: 60}}>หน่วย</th><th style={{width: 80}}>หมายเหตุ</th></tr></thead>
              <tbody>
                {lines.map((l, i) => (
                  <tr key={i}>
                    <td>{i + 1}</td>
                    <td className="mono">{l.sku}</td>
                    <td>{l.name}</td>
                    <td className="right">{l.qty}</td>
                    <td>{l.unit}</td>
                    <td></td>
                  </tr>
                ))}
              </tbody>
            </table>

            <div style={{marginTop: 14, padding: "8px 12px", background: "#fef9f3", border: "1px solid #fed7aa", borderRadius: 4, fontSize: 11.5, color: "#7c2d12"}}>
              <b>หมายเหตุ:</b> ลูกค้าโปรดตรวจรับสินค้าให้ครบถ้วนก่อนเซ็นรับ หากชำรุดเสียหายแจ้งทันที สินค้าที่รับเรียบร้อยแล้วถือว่าครบถ้วน
            </div>

            <div style={{display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 40, marginTop: 48, fontSize: 11.5}}>
              <div style={{textAlign: "center"}}>
                <div style={{borderTop: "1px solid #44403c", paddingTop: 6, marginTop: 30}}>ผู้ส่งของ · สุชาติ ขนส่ง</div>
              </div>
              <div style={{textAlign: "center"}}>
                <div style={{borderTop: "1px solid #44403c", paddingTop: 6, marginTop: 30}}>ผู้รับของ · ______________________</div>
              </div>
              <div style={{textAlign: "center"}}>
                <div style={{borderTop: "1px solid #44403c", paddingTop: 6, marginTop: 30}}>วันที่/เวลารับ · ______________</div>
              </div>
            </div>
          </div>
        </div>

        {/* Side */}
        <div style={{display: "flex", flexDirection: "column", gap: 14}}>
          <Card title="สถานะ" right={<Badge>{dn.status}</Badge>}>
            <div style={{display: "flex", flexDirection: "column", gap: 10, fontSize: 13}}>
              <Row label="ออกใบส่งของ" value={`${dn.date} 09:20`}/>
              <Row label="ขึ้นรถ" value={`${dn.date} 13:15`}/>
              <Row label="ออกจากโกดัง" value={`${dn.date} 14:20`}/>
              <Row label="คาดถึงปลายทาง" value="14:48 (ประมาณ)"/>
            </div>
          </Card>

          <Card title="ผูกกับ">
            <div style={{display: "flex", flexDirection: "column", gap: 8, fontSize: 13}}>
              <div><div className="label">ใบแจ้งหนี้</div><Badge>INV-2569-0204</Badge></div>
              <div><div className="label">โปรเจกต์</div><Badge>JOB-2569-020</Badge></div>
              <div><div className="label">ใบกำกับภาษี</div><Badge>TX-2569-0204</Badge></div>
              <div>
                <div className="label">งานส่งของประจำวัน</div>
                {linkedDD
                  ? <button className="badge outline mono" style={{cursor: "pointer"}} title="เปิดหน้าส่งของประจำวัน" onClick={() => navigate("daily-delivery")}>{linkedDD.no} · {linkedDD.status}</button>
                  : <div style={{display: "flex", alignItems: "center", gap: 8}}>
                      <span style={{fontSize: 12, color: "var(--ink-3)"}}>ยังไม่ได้สร้าง</span>
                      <Btn size="sm" kind="ghost" icon={I.plus} onClick={createDailyJob}>สร้างงานส่ง</Btn>
                    </div>}
              </div>
            </div>
          </Card>

          <Card title="หลักฐานการรับ" right={<Btn size="sm" kind="ghost" icon={I.plus}>เพิ่ม</Btn>}>
            <div className="attach-grid">
              <Attach name="signature.png" size="80 KB" ext="PNG"/>
              <Attach name="photo-delivery.jpg" size="1.2 MB" ext="JPG"/>
            </div>
          </Card>
        </div>
      </div>
    </>
  );
}

// ============ Receipts (ใบเสร็จรับเงิน) ============
function Receipts({ navigate }) {
  const D = window.SSSData;
  const total = D.Receipts.reduce((s, r) => s + r.amount, 0);
  return (
    <DocListPage
      title="ใบเสร็จรับเงิน · Receipts"
      sub="ออกใบเสร็จเมื่อได้รับเงินจากลูกค้า · เชื่อมกับใบแจ้งหนี้อัตโนมัติ"
      docType="receipt" rows={D.Receipts}
      statusFilter={["ออกแล้ว"]}
      createLabel="ออกใบเสร็จ"
      onCreate={() => window.openNewDoc && window.openNewDoc("receipt")}
      onRowClick={(r) => navigate("receipts/" + r.no)}
      kpis={[
        { label: "ใบเสร็จเดือนนี้", value: D.Receipts.length, sub: `ทุกใบ ออกครบ`, icon: I.receipt },
        { label: "รับเงินสดเดือนนี้", value: `฿${fmt0(total)}`, sub: "+18% vs เดือนก่อน", dir: "up", icon: I.money },
        { label: "ช่องทางหลัก", value: "โอน 68%", sub: "เช็ค 24% · เงินสด 8%", icon: I.calc },
        { label: "Average ticket size", value: `฿${fmt0(total / D.Receipts.length)}`, sub: "ต่อใบเสร็จ", icon: I.invoice }
      ]}
      columns={[
        { key: "no", label: "เลขที่", render: r => <span className="mono">{r.no}</span> },
        { key: "date", label: "วันที่" },
        { key: "customer", label: "ลูกค้า" },
        { key: "ref", label: "อ้างอิงใบแจ้งหนี้", render: r => <span className="mono" style={{fontSize: 11, color: "var(--ink-3)"}}>{r.ref}</span> },
        { key: "method", label: "วิธีรับชำระ" },
        { key: "amount", label: "ยอดรับ", right: true, render: r => <span className="amount">฿{fmt0(r.amount)}</span> },
        { key: "status", label: "สถานะ", render: r => <Badge tone="success">{r.status}</Badge> }
      ]}
    />
  );
}

// ============ Receipt Detail (printable) ============
function ReceiptDetail({ navigate }) {
  const D = window.SSSData;
  const r = D.Receipts[0]; // RC-2569-0156
  const C = D.Company;
  const vat = r.amount * 7 / 107;
  const base = r.amount - vat;

  return (
    <>
      <PageHead
        title={<span style={{display: "flex", alignItems: "center", gap: 12}}>
          <Btn kind="ghost" size="sm" onClick={() => navigate("receipts")}><I.chevronLeft size={14} className="icon"/>กลับ</Btn>
          ใบเสร็จรับเงิน <span className="mono" style={{fontSize: 16, color: "var(--ink-3)", fontWeight: 500}}>{r.no}</span>
        </span>}
        sub={`รับจาก: ${r.customer} · ${r.date}`}
        right={<>
          <Btn icon={I.msg} kind="ghost" onClick={() => window.toast && window.toast(`ส่งใบเสร็จ ${r.no} ทางอีเมลให้ ${r.customer} แล้ว`)}>ส่งอีเมล</Btn>
          <Btn icon={I.print} kind="ghost" onClick={() => window.printDocPaperWithOptions()}>พิมพ์</Btn>
          <Btn icon={I.download} kind="primary" onClick={() => window.printDocPaperWithOptions()}>ดาวน์โหลด PDF</Btn>
        </>}
      />

      <div className="grid" style={{gridTemplateColumns: "1fr 320px", gap: 14, alignItems: "flex-start"}}>
        <div className="doc-paper" style={{borderTop: `5px solid ${window.getDocColor("receipt")}`}}>
          <div style={{display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 20, marginBottom: 24}}>
            <div style={{display: "flex", gap: 20}}>
              <div style={{background: window.getDocColor("receipt"), borderRadius: 6, alignSelf: "stretch", minHeight: 56, maxHeight: 80, display: "flex", alignItems: "center", justifyContent: "center", padding: "8px 16px", flexShrink: 0}}><img src="assets/logo-ink.png" alt={C.name} style={{width: 132, maxHeight: "100%", objectFit: "contain", display: "block"}}/></div>
              <div>
                <div style={{fontWeight: 700, fontSize: 14}}>{C.name}</div>
                <div style={{fontSize: 11, color: "#57534e"}}>{C.nameEn}</div>
                <div style={{fontSize: 11, color: "#57534e", marginTop: 4, maxWidth: 320}}>{C.address}</div>
                <div style={{fontSize: 11, color: "#57534e"}}>โทร {C.phone} · เลขผู้เสียภาษี {C.taxId}</div>
              </div>
            </div>
            <div style={{textAlign: "right"}}>
              <h1 style={{color: window.getDocColor("receipt")}}>ใบเสร็จรับเงิน</h1>
              <div style={{fontSize: 10, color: "#78716c", letterSpacing: "0.06em"}}>OFFICIAL RECEIPT</div>
              <div style={{marginTop: 8, fontSize: 12}}>
                <div>เลขที่ <b className="mono">{r.no}</b></div>
                <div>วันที่ <b>{r.date}</b></div>
              </div>
              <div style={{marginTop: 12}}><span className="doc-stamp">PAID · ชำระแล้ว</span></div>
            </div>
          </div>

          <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, marginBottom: 16, fontSize: 12}}>
            <div style={{border: "1px solid #e7e5e4", padding: 10, borderRadius: 4}}>
              <div style={{fontSize: 10, color: "#78716c", textTransform: "uppercase", letterSpacing: "0.05em", marginBottom: 2}}>ได้รับเงินจาก</div>
              <div style={{fontWeight: 600}}>{r.customer}</div>
              <div style={{color: "#57534e"}}>เลขผู้เสียภาษี {r.taxId}</div>
            </div>
            <div style={{border: "1px solid #e7e5e4", padding: 10, borderRadius: 4}}>
              <div style={{fontSize: 10, color: "#78716c", textTransform: "uppercase", letterSpacing: "0.05em", marginBottom: 2}}>วิธีรับชำระ</div>
              <div style={{fontWeight: 600}}>{r.method}</div>
              <div style={{color: "#57534e"}}>อ้างอิง: {r.ref}</div>
            </div>
          </div>

          <table>
            <thead><tr><th style={{width: 30}}>#</th><th>รายการ</th><th className="right" style={{width: 140}}>จำนวนเงิน (บาท)</th></tr></thead>
            <tbody>
              <tr><td>1</td>
                <td>
                  <div style={{fontWeight: 500}}>รับชำระค่าสินค้าและบริการ</div>
                  <div style={{fontSize: 10, color: "#78716c"}}>ตามใบแจ้งหนี้ {r.ref}</div>
                </td>
                <td className="right">{fmtM(r.amount)}</td>
              </tr>
            </tbody>
          </table>

          <div style={{display: "flex", justifyContent: "flex-end", marginTop: 14}}>
            <div className="totals">
              <div className="row"><span>มูลค่าก่อน VAT</span><span>{fmtM(base)}</span></div>
              <div className="row"><span>ภาษีมูลค่าเพิ่ม 7%</span><span>{fmtM(vat)}</span></div>
              <div className="row grand"><span>รวมรับเงิน</span><span>฿ {fmtM(r.amount)}</span></div>
            </div>
          </div>

          <div style={{marginTop: 10, padding: "8px 12px", background: "#f7f6f4", borderRadius: 4, fontSize: 11.5, color: "#44403c", fontStyle: "italic"}}>
            ({window.UI.bahtText(r.amount)})
          </div>

          <div style={{marginTop: 16, padding: "10px 12px", background: "#f0f9f4", border: "1px solid #86efac", borderRadius: 4, fontSize: 11.5, color: "#166534"}}>
            <b>✓ ได้รับเงินครบถ้วนเรียบร้อยแล้ว</b> — ขอบคุณที่ใช้บริการ SSS Stainless & Metal
          </div>

          <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 40, marginTop: 48, fontSize: 11.5}}>
            <div style={{textAlign: "center"}}>
              <div style={{borderTop: "1px solid #44403c", paddingTop: 6, marginTop: 30}}>ผู้รับเงิน · วันเพ็ญ สุขใจ (บัญชี)</div>
            </div>
            <div style={{textAlign: "center"}}>
              <div style={{borderTop: "1px solid #44403c", paddingTop: 6, marginTop: 30}}>ตราประทับบริษัท</div>
            </div>
          </div>
        </div>

        <div style={{display: "flex", flexDirection: "column", gap: 14}}>
          <Card title="รายละเอียดการรับเงิน">
            <div style={{display: "flex", flexDirection: "column", gap: 8, fontSize: 13}}>
              <Row label="ยอดรับ" value={`฿${fmtM(r.amount)}`}/>
              <Row label="VAT 7%" value={`฿${fmtM(vat)}`}/>
              <Row label="วิธีรับ" value={r.method}/>
              <Row label="วันที่ฝาก" value="21 พ.ค. 2569"/>
              <Row label="เลขอ้างอิงธนาคาร" value="KB202569052081"/>
            </div>
          </Card>

          <Card title="กระทบยอด" sub="reconciliation">
            <div style={{fontSize: 13, lineHeight: 1.7}}>
              <div>✓ ใบแจ้งหนี้: <b className="mono">{r.ref}</b></div>
              <div>✓ ตรงกับ statement KBank</div>
              <div>✓ บันทึกเข้าระบบบัญชีแล้ว</div>
              <div>✓ อัพเดทยอดลูกหนี้แล้ว</div>
            </div>
          </Card>

          <Card title="ส่งใบเสร็จให้ลูกค้า">
            <div style={{display: "flex", flexDirection: "column", gap: 8}}>
              <Btn icon={I.msg} kind="ghost" onClick={() => window.toast && window.toast(`ส่งใบเสร็จ ${r.no} ทางอีเมลแล้ว`)}>ส่งอีเมล (puchara@...)</Btn>
              <Btn icon={I.send} kind="ghost" onClick={() => window.toast && window.toast(`ส่งใบเสร็จ ${r.no} ทาง LINE แล้ว`)}>ส่งทาง LINE</Btn>
              <Btn icon={I.download} onClick={() => window.printDocPaperWithOptions()}>ดาวน์โหลด PDF</Btn>
            </div>
          </Card>
        </div>
      </div>
    </>
  );
}

window.DeliveryNoteDetail = DeliveryNoteDetail;
window.Receipts = Receipts;
window.ReceiptDetail = ReceiptDetail;

// ============ Quotation list ============
function Quotations({ navigate }) {
  const D = window.SSSData;
  return (
    <DocListPage
      title="ใบเสนอราคา · Quotations"
      sub="ออก ติดตาม และแปลงเป็นใบสั่งซื้อหรือใบแจ้งหนี้"
      docType="quotation" rows={D.Quotations}
      statusFilter={["ร่าง", "ส่งแล้ว", "รออนุมัติ", "อนุมัติแล้ว", "แปลงเป็นใบสั่ง", "ปฏิเสธ"]}
      createLabel="สร้างใบเสนอราคา"
      onCreate={() => window.openNewDoc && window.openNewDoc("quotation")}
      onRowClick={(r) => navigate("quotations/" + r.no)}
      kpis={[
        { label: "เปิดอยู่ทั้งหมด", value: D.Quotations.length, sub: "เดือนนี้", icon: I.doc },
        { label: "รออนุมัติ", value: D.Quotations.filter(q => q.status === "รออนุมัติ").length, sub: `฿${fmt0(D.Quotations.filter(q => q.status === "รออนุมัติ").reduce((s,q)=>s+q.amount,0))}`, icon: I.clock },
        { label: "อนุมัติแล้ว", value: D.Quotations.filter(q => q.status === "อนุมัติแล้ว").length, sub: "รอแปลงเป็นใบสั่ง", icon: I.check },
        { label: "Conversion rate", value: "62%", sub: "QO → Invoice เดือนนี้", icon: I.arrowRight }
      ]}
      columns={[
        { key: "no", label: "เลขที่", cls: "doc-no", render: r => <span className="mono">{r.no}</span> },
        { key: "date", label: "วันที่ออก" },
        { key: "customer", label: "ลูกค้า" },
        { key: "owner", label: "ผู้สร้าง" },
        { key: "validity", label: "ยืนราคา" },
        { key: "amount", label: "จำนวนเงิน", right: true, render: r => <span className="amount">฿{fmt0(r.amount)}</span> },
        { key: "status", label: "สถานะ", render: r => <Badge>{r.status}</Badge> }
      ]}
    />
  );
}

// ============ Quotation detail (also doubles as invoice/PO doc preview) ============
function QuotationDetail({ navigate }) {
  const D = window.SSSData;
  const [tab, setTab] = useState("preview");
  const [, forceQ] = useState(0);
  const q = D.Quotations[0]; // QO-2569-0117 — Innofoods kitchen
  const lines = [
    { sku: "SS316-SH-2.0", name: "แผ่นสแตนเลส 316L หนา 2.0 มม. 4x8 ฟุต", qty: 22, unit: "แผ่น", price: 11200, total: 246400 },
    { sku: "SS-TUBE-32", name: "ท่อสแตนเลส 304 1-1/4\" ยาว 6 ม.", qty: 18, unit: "เส้น", price: 1620, total: 29160 },
    { sku: "SVC-CAD-3D", name: "ค่าบริการออกแบบ 3D CAD — Layout ครัวอุตสาหกรรม", qty: 24, unit: "ชม.", price: 1200, total: 28800 },
    { sku: "SVC-CNC-LASER", name: "ค่าบริการตัด CNC Fiber Laser", qty: 36, unit: "ชม.", price: 850, total: 30600 },
    { sku: "SVC-WELD-TIG", name: "ค่าบริการเชื่อม TIG — ประกอบโครงเคาน์เตอร์", qty: 80, unit: "ชม.", price: 650, total: 52000 }
  ];
  const subtotal = lines.reduce((s, l) => s + l.total, 0);
  const discount = 4000;
  const afterDisc = subtotal - discount;
  const vat = afterDisc * 0.07;
  const grand = afterDisc + vat;

  return (
    <>
      <PageHead
        title={<span style={{display: "flex", alignItems: "center", gap: 12}}>
          <Btn kind="ghost" size="sm" onClick={() => navigate("quotations")}><I.chevronLeft size={14} className="icon"/>กลับ</Btn>
          ใบเสนอราคา <span className="mono" style={{fontSize: 16, color: "var(--ink-3)", fontWeight: 500}}>{q.no}</span>
        </span>}
        sub={`ลูกค้า: ${q.customer} · สร้างเมื่อ ${q.date}`}
        right={<>
          <Btn icon={I.edit} kind="ghost" onClick={() => window.openNewDoc && window.openNewDoc("quotation", { editing: true, docNo: q.no, partyName: q.customer, notes: "", lines: lines.map(l => ({ sku: l.sku, name: l.name, qty: l.qty, unit: l.unit, price: l.price })) })}>แก้ไขเอกสาร</Btn>
          <Btn icon={I.msg} kind="ghost" onClick={() => window.toast && window.toast(`ส่งใบเสนอราคา ${q.no} ทางอีเมลให้ ${q.customer} แล้ว`)}>ส่งทางอีเมล</Btn>
          <Btn icon={I.print} kind="ghost" onClick={() => window.printDocPaperWithOptions()}>พิมพ์</Btn>
          <Btn icon={I.download} kind="ghost" onClick={() => window.printDocPaperWithOptions()}>PDF</Btn>
          <Btn icon={I.truck} kind="ghost" onClick={async () => {
            const ok = await window.confirmDialog({
              title: "แปลงใบเสนอราคาเป็นใบส่งของ",
              message: `สร้างใบส่งสินค้าจาก <b class="mono">${q.no}</b>`,
              bullets: [
                "สร้างใบส่งสินค้าเลข DN-2569-0189",
                "คัดลอกรายการสินค้าทั้งหมด",
                "พร้อมระบุคนขับและทะเบียนรถ",
                "เปิดใบส่งของใหม่ทันที"
              ],
              confirmText: "สร้างใบส่งของ"
            });
            if (ok) {
              window.logActivity && window.logActivity("แปลงเอกสาร", "ใบเสนอราคา " + q.no + " → DN-2569-0189", "create");
              window.DocStatus2Store && window.DocStatus2Store.set("quotation", q.no, "แปลงเป็นใบส่งสินค้าแล้ว (DN-2569-0189)");
              forceQ(n => n + 1);
              window.toast && window.toast("สร้างใบส่งสินค้า DN-2569-0189 จาก " + q.no + " แล้ว");
              setTimeout(() => navigate("delivery-notes/DN-2569-0188"), 600);
            }
          }}>แปลงเป็นใบส่งของ</Btn>
          <Btn icon={I.arrowRight} kind="primary" onClick={() => {
            window.openNewDoc && window.openNewDoc("invoice", {
              fromDoc: q.no, partyName: q.customer,
              lines: lines.map(l => ({ sku: l.sku, name: l.name, qty: l.qty, unit: l.unit, price: l.price }))
            });
            window.DocStatusStore && window.DocStatusStore.set("quotation", q.no, "แปลงเป็นใบสั่ง");
            window.DocStatus2Store && window.DocStatus2Store.set("quotation", q.no, "แปลงเป็นใบส่งสินค้า/ใบแจ้งหนี้แล้ว (INV-2569-0205)");
            forceQ(n => n + 1);
          }}>แปลงเป็นใบส่งสินค้า/ใบแจ้งหนี้</Btn>
        </>}
      />

      <div className="grid" style={{gridTemplateColumns: "1fr 320px", gap: 14, alignItems: "flex-start"}}>
        <div>
          {/* Workflow */}
          <Card padded={false} className="mb-lg" flush>
            <div style={{padding: "14px 16px"}}>
              <Workflow steps={["ร่าง", "ส่งให้ลูกค้า", "รออนุมัติ", "อนุมัติ", "แปลงเป็นใบสั่ง/ใบแจ้งหนี้"]} current={({"ร่าง": 0, "ส่งแล้ว": 1, "รออนุมัติ": 2, "อนุมัติแล้ว": 3, "แปลงเป็นใบสั่ง": 4, "ปฏิเสธ": 2})[q.status] ?? 2}/>
            </div>
          </Card>

          <Tabs
            items={[
              { key: "preview", label: "ตัวอย่างเอกสาร" },
              { key: "items", label: "รายการสินค้า" },
              { key: "history", label: "ประวัติ" },
              { key: "comments", label: "ความเห็น" }
            ]}
            active={tab}
            onChange={setTab}
          />

          {tab === "preview" && <DocPaper q={q} lines={lines} subtotal={subtotal} discount={discount} afterDisc={afterDisc} vat={vat} grand={grand} docType="ใบเสนอราคา" docTypeEn="QUOTATION"/>}
          {tab === "items" && <ItemsEditor lines={lines}/>}
          {tab === "history" && <HistoryList/>}
          {tab === "comments" && <Comments docNo={q.no}/>}
        </div>

        {/* Side panel */}
        <div style={{display: "flex", flexDirection: "column", gap: 14}}>
          <Card title="สถานะ" right={<Badge>{q.status || "ร่าง"}</Badge>}>
            {(() => { const s2 = window.DocStatus2Store && window.DocStatus2Store.get("quotation", q.no); return s2 ? (
              <div style={{display: "flex", alignItems: "center", gap: 8, padding: "7px 10px", marginBottom: 10, background: "var(--success-bg, var(--surface-2))", border: "1px solid var(--success)", borderRadius: 8, fontSize: 12.5}}>
                <I.check size={14} stroke="var(--success)"/>
                <span style={{flex: 1}}><b style={{color: "var(--success)"}}>สถานะที่ 2:</b> {window.docLinkify ? window.docLinkify(s2, navigate) : s2}</span>
              </div>
            ) : null; })()}
            <div className="field">
              <label style={{fontSize: 11, color: "var(--ink-3)", display: "block", marginBottom: 4}}>เปลี่ยนสถานะเอกสาร</label>
              <select className="input" style={{height: 32}} value={q.status || "รออนุมัติ"}
                onChange={e => {
                  const s = e.target.value;
                  window.DocStatusStore && window.DocStatusStore.set("quotation", q.no, s);
                  forceQ(n => n + 1);
                  window.logActivity && window.logActivity("เปลี่ยนสถานะ", `${q.no} → ${s}`, "update");
                  window.toast && window.toast(`เปลี่ยนสถานะ ${q.no} เป็น "${s}" แล้ว`);
                }}>
                {["ร่าง", "ส่งแล้ว", "รออนุมัติ", "อนุมัติแล้ว", "แปลงเป็นใบสั่ง", "ปฏิเสธ"].map(s => <option key={s} value={s}>{s}</option>)}
              </select>
            </div>
          </Card>
          <Card title="สรุปยอด">
            <div style={{display: "flex", flexDirection: "column", gap: 6, fontSize: 13}}>
              <Row label="รวมเป็นเงิน" value={`฿${fmtM(subtotal)}`}/>
              <Row label="ส่วนลด" value={`฿${fmtM(discount)}`}/>
              <Row label="หลังหักส่วนลด" value={`฿${fmtM(afterDisc)}`}/>
              <Row label="ภาษีมูลค่าเพิ่ม 7%" value={`฿${fmtM(vat)}`}/>
              <div style={{borderTop: "1px solid var(--line)", marginTop: 6, paddingTop: 8, display: "flex", justifyContent: "space-between", fontWeight: 600, fontSize: 16}}>
                <span>ยอดรวมสุทธิ</span>
                <span className="amount">฿{fmtM(grand)}</span>
              </div>
            </div>
          </Card>

          <Card title="ลูกค้า" right={<Btn size="sm" kind="ghost" onClick={() => navigate("customers")}>เปิดโปรไฟล์</Btn>}>
            <div style={{fontSize: 13, lineHeight: 1.6}}>
              <div style={{fontWeight: 500, marginBottom: 4}}>{q.customer}</div>
              <div className="muted">เลขผู้เสียภาษี 0105562088001</div>
              <div className="muted">คุณพัชรา ศิลปกร</div>
              <div className="muted">02-987-6543</div>
              <div className="muted">เครดิต 60 วัน · ค้างชำระ ฿0</div>
            </div>
          </Card>

          <Card title="ผู้ดำเนินการ">
            <div style={{display: "flex", flexDirection: "column", gap: 8, fontSize: 13}}>
              <div style={{display: "flex", alignItems: "center", gap: 8}}>
                <div className="avatar" style={{width: 28, height: 28, fontSize: 10}}>ปศ</div>
                <div><div style={{fontWeight: 500}}>ปิยะ ศรีสวัสดิ์</div><div className="muted" style={{fontSize: 11}}>ผู้สร้าง · 21 พ.ค. 2569</div></div>
              </div>
              <div style={{display: "flex", alignItems: "center", gap: 8}}>
                <div className="avatar" style={{width: 28, height: 28, fontSize: 10, background: "var(--warning-bg)", color: "var(--warning)"}}>?</div>
                <div><div style={{fontWeight: 500}}>วันเพ็ญ สุขใจ</div><div className="muted" style={{fontSize: 11}}>รออนุมัติ</div></div>
              </div>
            </div>
          </Card>

          <Card title="ไฟล์แนบ" right={<Btn size="sm" kind="ghost" icon={I.plus}>เพิ่ม</Btn>}>
            <div style={{display: "flex", flexDirection: "column", gap: 8}}>
              <Attach name="kitchen-layout-v3.dwg" size="2.4 MB" ext="DWG"/>
              <Attach name="3d-render-prelim.pdf" size="8.1 MB" ext="PDF"/>
              <Attach name="spec-316L.pdf" size="640 KB" ext="PDF"/>
            </div>
          </Card>
        </div>
      </div>
    </>
  );
}

function Row({ label, value }) {
  return <div style={{display: "flex", justifyContent: "space-between"}}><span className="muted">{label}</span><span className="amount">{value}</span></div>;
}

function Attach({ name, size, ext }) {
  return (
    <div className="attach">
      <div className="ext">{ext}</div>
      <div className="name" style={{overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap"}}>{name}</div>
      <div className="meta">{size}</div>
    </div>
  );
}

function DocPaper({ q, lines, subtotal, discount, afterDisc, vat, grand, docType, docTypeEn }) {
  const C = window.SSSData.Company;
  const color = window.getDocColor("quotation");
  return (
    <div className="doc-paper" style={{borderTop: `5px solid ${color}`}}>
      <div style={{display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 20, marginBottom: 24}}>
        <div style={{display: "flex", gap: 20}}>
          <div style={{background: color, borderRadius: 6, alignSelf: "stretch", minHeight: 56, maxHeight: 80, display: "flex", alignItems: "center", justifyContent: "center", padding: "8px 16px", flexShrink: 0}}><img src="assets/logo-ink.png" alt={C.name} style={{width: 132, maxHeight: "100%", objectFit: "contain", display: "block"}}/></div>
          <div>
            <div style={{fontWeight: 700, fontSize: 14}}>{C.name}</div>
            <div style={{fontSize: 11, color: "#57534e"}}>{C.nameEn}</div>
            <div style={{fontSize: 11, color: "#57534e", marginTop: 4, maxWidth: 320}}>{C.address}</div>
            <div style={{fontSize: 11, color: "#57534e"}}>โทร {C.phone} · เลขผู้เสียภาษี {C.taxId}</div>
          </div>
        </div>
        <div style={{textAlign: "right"}}>
          <h1 style={{color}}>{docType}</h1>
          <div style={{fontSize: 10, color: "#78716c", letterSpacing: "0.06em"}}>{docTypeEn}</div>
          <div style={{marginTop: 8, fontSize: 12}}>
            <div>เลขที่ <b className="mono">{q.no}</b></div>
            <div>วันที่ <b>{q.date}</b></div>
            <div>ยืนราคา <b>{q.validity}</b></div>
          </div>
        </div>
      </div>

      <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, marginBottom: 16, fontSize: 12}}>
        <div style={{border: "1px solid #e7e5e4", padding: 10, borderRadius: 4}}>
          <div style={{fontSize: 10, color: "#78716c", textTransform: "uppercase", letterSpacing: "0.05em", marginBottom: 2}}>ลูกค้า</div>
          <div style={{fontWeight: 600}}>{q.customer}</div>
          <div style={{color: "#57534e"}}>88/45 ถ.รัตนาธิเบศร์ ต.บางกระสอ อ.เมือง จ.นนทบุรี 11000</div>
          <div style={{color: "#57534e"}}>เลขผู้เสียภาษี 0105562088001</div>
        </div>
        <div style={{border: "1px solid #e7e5e4", padding: 10, borderRadius: 4}}>
          <div style={{fontSize: 10, color: "#78716c", textTransform: "uppercase", letterSpacing: "0.05em", marginBottom: 2}}>ติดต่อ / เงื่อนไข</div>
          <div>ผู้ติดต่อ: คุณพัชรา ศิลปกร</div>
          <div>เงื่อนไขการชำระ: เครดิต 60 วัน</div>
          <div>การส่งสินค้า: ส่งฟรีในเขตกรุงเทพและปริมณฑล</div>
        </div>
      </div>

      <table>
        <thead>
          <tr>
            <th style={{width: 30}}>#</th>
            <th>รายการ</th>
            <th style={{width: 60}} className="right">จำนวน</th>
            <th style={{width: 60}}>หน่วย</th>
            <th style={{width: 90}} className="right">ราคา/หน่วย</th>
            <th style={{width: 110}} className="right">รวมเป็นเงิน</th>
          </tr>
        </thead>
        <tbody>
          {lines.map((l, i) => (
            <tr key={i}>
              <td>{i + 1}</td>
              <td>
                <div style={{fontWeight: 500}}>{l.name}</div>
                <div style={{fontSize: 10, color: "#78716c"}} className="mono">{l.sku}</div>
              </td>
              <td className="right">{l.qty}</td>
              <td>{l.unit}</td>
              <td className="right">{fmtM(l.price)}</td>
              <td className="right">{fmtM(l.total)}</td>
            </tr>
          ))}
        </tbody>
      </table>

      <div style={{display: "flex", justifyContent: "space-between", marginTop: 16, gap: 30}}>
        <div style={{flex: 1, fontSize: 11.5, color: "#57534e", lineHeight: 1.55}}>
          <div style={{textTransform: "uppercase", fontSize: 10, fontWeight: 600, color: "#44403c", letterSpacing: "0.05em", marginBottom: 4}}>หมายเหตุ</div>
          <div>• ราคาข้างต้นเป็นราคาก่อนภาษีมูลค่าเพิ่ม</div>
          <div>• ระยะเวลาผลิตประมาณ 25-30 วันทำการ หลังได้รับ PO + เงินมัดจำ 50%</div>
          <div>• ส่วนที่เหลือชำระภายใน 60 วันหลังส่งมอบงาน</div>
          <div>• แบบ 3D ที่ส่งให้ลูกค้าถือเป็นทรัพย์สินของ SSS จนกว่าจะชำระครบ</div>
        </div>
        <div className="totals">
          <div className="row"><span>รวมเป็นเงิน</span><span>{fmtM(subtotal)}</span></div>
          <div className="row"><span>ส่วนลด</span><span>{fmtM(discount)}</span></div>
          <div className="row"><span>หลังหักส่วนลด</span><span>{fmtM(afterDisc)}</span></div>
          <div className="row"><span>ภาษีมูลค่าเพิ่ม 7%</span><span>{fmtM(vat)}</span></div>
          <div className="row grand"><span>ยอดสุทธิ</span><span>฿ {fmtM(grand)}</span></div>
        </div>
      </div>

      <div style={{marginTop: 10, padding: "8px 12px", background: "#f7f6f4", borderRadius: 4, fontSize: 11.5, color: "#44403c", fontStyle: "italic"}}>
        ({bahtText(grand)})
      </div>

      <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 40, marginTop: 48, fontSize: 11.5}}>
        <div style={{textAlign: "center"}}>
          <div style={{borderTop: "1px solid #44403c", paddingTop: 6, marginTop: 30}}>ผู้เสนอราคา · ปิยะ ศรีสวัสดิ์</div>
        </div>
        <div style={{textAlign: "center"}}>
          <div style={{borderTop: "1px solid #44403c", paddingTop: 6, marginTop: 30}}>ลูกค้าอนุมัติ · วันที่ ______________</div>
        </div>
      </div>
    </div>
  );
}

function ItemsEditor({ lines }) {
  return (
    <Card flush>
      <div className="table-wrap">
        <table className="t">
          <thead><tr><th>SKU</th><th>รายการ</th><th className="right">จำนวน</th><th>หน่วย</th><th className="right">ราคา/หน่วย</th><th className="right">รวม</th><th></th></tr></thead>
          <tbody>
            {lines.map((l, i) => (
              <tr key={i}>
                <td className="mono">{l.sku}</td>
                <td>{l.name}</td>
                <td className="right">{l.qty}</td>
                <td>{l.unit}</td>
                <td className="right">฿{fmtM(l.price)}</td>
                <td className="right">฿{fmtM(l.total)}</td>
                <td><Btn kind="ghost" size="sm" icon={I.edit}/></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      <div style={{padding: 12, display: "flex", gap: 8}}>
        <Btn icon={I.plus} size="sm">เพิ่มรายการ</Btn>
        <Btn icon={I.barcode} size="sm" kind="ghost">สแกนบาร์โค้ดเพิ่ม</Btn>
      </div>
    </Card>
  );
}

function HistoryList() {
  return (
    <Card>
      <div style={{display: "flex", flexDirection: "column", gap: 14, position: "relative"}}>
        {[
          { who: "ปิยะ ศ.", what: "สร้างเอกสารฉบับร่าง", when: "21 พ.ค. 2569 · 09:42" },
          { who: "ปิยะ ศ.", what: "แก้ไขรายการสินค้า — เพิ่มบริการ 3D CAD 24 ชม.", when: "21 พ.ค. 2569 · 10:08" },
          { who: "ปิยะ ศ.", what: "ส่งให้ลูกค้าทางอีเมล puchara@innofoods.co.th", when: "21 พ.ค. 2569 · 11:05" },
          { who: "ระบบ", what: "ส่ง reminder อัตโนมัติให้ผู้อนุมัติ (วันเพ็ญ)", when: "21 พ.ค. 2569 · 14:00" },
          { who: "—", what: "รออนุมัติ", when: "ปัจจุบัน" }
        ].map((h, i) => (
          <div key={i} style={{display: "flex", gap: 12}}>
            <div className="avatar" style={{width: 28, height: 28, fontSize: 10}}>{h.who.slice(0,2)}</div>
            <div><div style={{fontSize: 13}}><b>{h.who}</b> · {h.what}</div><div className="muted" style={{fontSize: 11}}>{h.when}</div></div>
          </div>
        ))}
      </div>
    </Card>
  );
}

const CMT_MONTHS = ["ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค."];
function Comments({ docNo }) {
  const D = window.SSSData;
  const CK = "sss-comments-" + (docNo || "doc");
  const SEED = [
    { id: 1, by: "ปิยะ ศรีสวัสดิ์", at: "21 พ.ค. 2569 11:30", text: "ลูกค้า new — ขอ markup เผื่อ contingency 5% ครับ @วันเพ็ญ สุขใจ ช่วยรีวิวด่วน", imgs: [], docs: [] },
    { id: 2, by: "วันเพ็ญ สุขใจ", at: "21 พ.ค. 2569 14:15", text: "เช็คแล้วครับ ส่วนลดที่ให้ 4,000 บาท อยู่ในกรอบที่อนุมัติได้ ✓", imgs: [], docs: [] }
  ];
  const [list, setList] = useState(() => { try { return JSON.parse(localStorage.getItem(CK) || "null") || SEED; } catch { return SEED; } });
  const [msg, setMsg] = useState("");
  const [imgs, setImgs] = useState([]);
  const [docs, setDocs] = useState([]);
  const [picker, setPicker] = useState(null); // "people" | "docs"
  const [viewer, setViewer] = useState(null);

  const people = [...(D.Employees || []), ...((D.Users || []).filter(u => !(D.Employees || []).some(e => e.name === u.name)))];
  const allDocs = [...(D.Quotations || []), ...(D.Invoices || []), ...(D.TaxInvoices || []), ...(D.PurchaseOrders || [])].map(d => d.no).filter(Boolean);
  const save = (l) => { setList(l); try { localStorage.setItem(CK, JSON.stringify(l)); } catch {} };

  const pickImg = async (e) => {
    const fs = [...e.target.files]; e.target.value = "";
    const urls = await Promise.all(fs.map(f => window.DeliveryStore ? window.DeliveryStore.resizeImage(f, 1000) : new Promise(r => { const rd = new FileReader(); rd.onload = () => r(rd.result); rd.readAsDataURL(f); })));
    setImgs(p => [...p, ...urls.map((u, i) => ({ url: u, name: fs[i].name }))]);
  };
  const send = () => {
    if (!msg.trim() && !imgs.length && !docs.length) { window.toast && window.toast("พิมพ์ความเห็นหรือแนบรูป/เอกสาร"); return; }
    const sess = window.Session ? window.Session.get() : null;
    const me = (sess && sess.name) || (D.Company.currentUser && D.Company.currentUser.name) || "ฉัน";
    const n = new Date();
    const at = `${n.getDate()} ${CMT_MONTHS[n.getMonth()]} ${n.getFullYear() + 543} ${String(n.getHours()).padStart(2, "0")}:${String(n.getMinutes()).padStart(2, "0")}`;
    save([...list, { id: Date.now(), by: me, at, text: msg.trim(), imgs, docs }]);
    const mentioned = people.filter(p => msg.includes("@" + p.name));
    if (mentioned.length) window.toast && window.toast(`ส่งความเห็นและแจ้งเตือน ${mentioned.map(p => p.name).join(", ")} แล้ว`);
    else window.toast && window.toast("ส่งความเห็นแล้ว");
    setMsg(""); setImgs([]); setDocs([]);
  };
  const renderText = (t) => {
    if (!t) return null;
    const tokens = t.split(/(@[^\s@#]+(?:\s[^\s@#]+)?|#[A-Z]+-[0-9-]+)/g);
    return tokens.map((tok, i) => {
      if (people.some(p => "@" + p.name === tok)) return <span key={i} style={{ color: "var(--brand, #7c3aed)", fontWeight: 600 }}>{tok}</span>;
      if (/^#[A-Z]+-[0-9-]+$/.test(tok)) return <span key={i} style={{ color: "var(--info)", fontWeight: 600 }}>{tok}</span>;
      return <React.Fragment key={i}>{tok}</React.Fragment>;
    });
  };

  return (
    <Card>
      <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
        {list.map(c => (
          <div key={c.id} className="activity-item" style={{ alignItems: "flex-start" }}>
            {window.RankAvatar ? <window.RankAvatar name={c.by} size={30}/> : <div className="avatar" style={{ width: 30, height: 30, fontSize: 10 }}>{c.by.slice(0, 2)}</div>}
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 13 }}><b>{c.by}</b> <span className="muted" style={{ fontSize: 11 }}>· {c.at}</span></div>
              {c.text && <div style={{ fontSize: 13, lineHeight: 1.5, whiteSpace: "pre-wrap" }}>{renderText(c.text)}</div>}
              {(c.docs || []).length > 0 && <div style={{ display: "flex", gap: 6, flexWrap: "wrap", marginTop: 5 }}>{c.docs.map(d => <span key={d} className="badge outline mono" style={{ fontSize: 11, cursor: "pointer" }} onClick={() => window.toast && window.toast("อ้างอิงเอกสาร " + d)}>📎 {d}</span>)}</div>}
              {(c.imgs || []).length > 0 && <div style={{ display: "flex", gap: 6, flexWrap: "wrap", marginTop: 6 }}>{c.imgs.map((im, j) => <img key={j} src={im.url} alt={im.name} onClick={() => setViewer(im.url)} style={{ width: 72, height: 72, objectFit: "cover", borderRadius: 6, border: "1px solid var(--line)", cursor: "zoom-in" }}/>)}</div>}
            </div>
          </div>
        ))}

        {/* แถบแนบที่จะส่ง */}
        {(imgs.length > 0 || docs.length > 0) && (
          <div style={{ display: "flex", gap: 6, flexWrap: "wrap", padding: "6px 0" }}>
            {docs.map(d => <span key={d} className="badge outline mono" style={{ fontSize: 11 }}>📎 {d} <span style={{ cursor: "pointer" }} onClick={() => setDocs(p => p.filter(x => x !== d))}>×</span></span>)}
            {imgs.map((im, j) => <span key={j} style={{ position: "relative" }}><img src={im.url} alt="" style={{ width: 44, height: 44, objectFit: "cover", borderRadius: 5, border: "1px solid var(--line)" }}/><span onClick={() => setImgs(p => p.filter((_, k) => k !== j))} style={{ position: "absolute", top: -6, right: -6, width: 16, height: 16, borderRadius: "50%", background: "var(--ink-1)", color: "white", fontSize: 11, display: "grid", placeItems: "center", cursor: "pointer" }}>×</span></span>)}
          </div>
        )}

        <div style={{ position: "relative" }}>
          <div style={{ display: "flex", gap: 6, marginBottom: 6 }}>
            <button className="icon-btn" title="แท็กพนักงาน/ผู้ใช้" onClick={() => setPicker(picker === "people" ? null : "people")}>@</button>
            <button className="icon-btn" title="อ้างอิงเอกสาร" onClick={() => setPicker(picker === "docs" ? null : "docs")}>#</button>
            <label className="icon-btn" title="แนบรูป" style={{ cursor: "pointer" }}><I.camera size={14}/><input type="file" accept="image/*" multiple style={{ display: "none" }} onChange={pickImg}/></label>
          </div>
          {picker === "people" && (
            <div style={{ position: "absolute", bottom: "calc(100% - 0px)", left: 0, zIndex: 30, background: "var(--surface)", border: "1px solid var(--line-strong)", borderRadius: 10, boxShadow: "var(--shadow-lg)", width: 260, maxHeight: 240, overflowY: "auto", padding: 4 }}>
              {people.map(p => (
                <button key={p.id} onClick={() => { setMsg(m => (m ? m + " " : "") + "@" + p.name + " "); setPicker(null); }} style={{ display: "flex", alignItems: "center", gap: 8, width: "100%", padding: "6px 8px", border: 0, background: "transparent", cursor: "pointer", borderRadius: 6, textAlign: "left", fontFamily: "var(--font)" }}>
                  {window.RankAvatar ? <window.RankAvatar name={p.name} size={24}/> : null}
                  <span style={{ fontSize: 12.5 }}>{p.name} <span className="muted" style={{ fontSize: 11 }}>{p.role}</span></span>
                </button>
              ))}
            </div>
          )}
          {picker === "docs" && (
            <div style={{ position: "absolute", bottom: "100%", left: 0, zIndex: 30, background: "var(--surface)", border: "1px solid var(--line-strong)", borderRadius: 10, boxShadow: "var(--shadow-lg)", width: 240, maxHeight: 240, overflowY: "auto", padding: 4 }}>
              {allDocs.map(d => (
                <button key={d} onClick={() => { setDocs(p => p.includes(d) ? p : [...p, d]); setPicker(null); }} className="mono" style={{ display: "block", width: "100%", padding: "6px 8px", border: 0, background: "transparent", cursor: "pointer", borderRadius: 6, textAlign: "left", fontSize: 12 }}>📎 {d}</button>
              ))}
            </div>
          )}
          <div style={{ display: "flex", gap: 8 }}>
            <input className="input" placeholder="พิมพ์ความเห็น… ใช้ @ แท็กคน · # แนบเอกสาร" value={msg} onChange={e => setMsg(e.target.value)} onKeyDown={e => e.key === "Enter" && send()}/>
            <Btn icon={I.send} kind="primary" onClick={send}>ส่ง</Btn>
          </div>
        </div>
      </div>
      {viewer && <div className="scrim" style={{ display: "flex", alignItems: "center", justifyContent: "center", padding: 24, zIndex: 240 }} onClick={() => setViewer(null)}><img src={viewer} alt="" style={{ maxWidth: "92vw", maxHeight: "90vh", borderRadius: 8 }}/></div>}
    </Card>
  );
}

// ============ Invoices ============
function Invoices({ navigate }) {
  const D = window.SSSData;
  const outstanding = D.Invoices.filter(i => i.status !== "ชำระแล้ว").reduce((s, i) => s + (i.amount - i.paid), 0);
  const overdue = D.Invoices.filter(i => i.status === "เกินกำหนด").reduce((s, i) => s + (i.amount - i.paid), 0);
  return (
    <DocListPage
      title="ใบส่งสินค้า / ใบแจ้งหนี้ · Delivery Note / Invoice"
      sub="ติดตามลูกหนี้และการชำระเงิน"
      docType="invoice" rows={D.Invoices}
      statusFilter={["ค้างชำระ", "ชำระบางส่วน", "ชำระแล้ว", "เกินกำหนด"]}
      createLabel="สร้างใบส่งสินค้า/ใบแจ้งหนี้"
      onCreate={() => window.openNewDoc && window.openNewDoc("invoice")}
      onRowClick={(r) => navigate("invoices/" + r.no)}
      kpis={[
        { label: "ลูกหนี้ค้างชำระทั้งหมด", value: `฿${fmt0(outstanding)}`, sub: `${D.Invoices.filter(i=>i.status!=='ชำระแล้ว').length} ใบ`, icon: I.invoice },
        { label: "เกินกำหนด", value: `฿${fmt0(overdue)}`, sub: `${D.Invoices.filter(i=>i.status==='เกินกำหนด').length} ใบ · ต้องติดตาม`, dir: "down", icon: I.bell },
        { label: "เก็บได้เดือนนี้", value: `฿${fmt0(D.Invoices.filter(i=>i.status==='ชำระแล้ว').reduce((s,i)=>s+i.amount,0))}`, sub: "+12% จากเดือนก่อน", dir: "up", icon: I.check },
        { label: "อายุลูกหนี้เฉลี่ย (DSO)", value: "42 วัน", sub: "เป้าหมาย 45 วัน", dir: "up", icon: I.clock }
      ]}
      columns={[
        { key: "no", label: "เลขที่", render: r => <span className="mono">{r.no}</span> },
        { key: "date", label: "วันที่ออก" },
        { key: "due", label: "ครบกำหนด" },
        { key: "customer", label: "ลูกค้า" },
        { key: "amount", label: "จำนวนเงิน", right: true, render: r => <span className="amount">฿{fmt0(r.amount)}</span> },
        { key: "paid", label: "ชำระแล้ว", right: true, render: r => <span className="amount muted">฿{fmt0(r.paid)}</span> },
        { key: "outstanding", label: "คงเหลือ", right: true, render: r => <span className="amount">฿{fmt0(r.amount - r.paid)}</span> },
        { key: "status", label: "สถานะ", render: r => <Badge>{r.status}</Badge> }
      ]}
    />
  );
}

// ============ Delivery Notes ============
function DeliveryNotes({ navigate }) {
  const D = window.SSSData;
  return (
    <DocListPage
      title="ใบส่งสินค้า · Delivery Notes"
      sub="ติดตามการจัดส่งและการเซ็นรับ"
      docType="delivery-note" rows={D.DeliveryNotes}
      statusFilter={["กำลังจัดส่ง", "ส่งแล้ว", "ลูกค้ามารับเอง"]}
      createLabel="สร้างใบส่งสินค้า"
      onCreate={() => window.openNewDoc && window.openNewDoc("delivery-note")}
      onRowClick={(r) => navigate("delivery-notes/" + r.no)}
      kpis={[
        { label: "เที่ยวขนส่งวันนี้", value: 6, sub: "รถ 2 คัน · ขับ 2 คน", icon: I.truck },
        { label: "กำลังจัดส่ง", value: D.DeliveryNotes.filter(d=>d.status==='กำลังจัดส่ง').length, sub: "ติดตามตำแหน่งรถ", icon: I.move },
        { label: "เซ็นรับครบเดือนนี้", value: D.DeliveryNotes.filter(d=>d.status==='ส่งแล้ว').length, sub: "100% on-time", dir: "up", icon: I.check },
        { label: "ระยะทางขับเดือนนี้", value: "1,840 กม.", sub: "ค่าน้ำมัน ฿8,420", icon: I.truck }
      ]}
      columns={[
        { key: "no", label: "เลขที่", render: r => <span className="mono">{r.no}</span> },
        { key: "date", label: "วันที่" },
        { key: "customer", label: "ลูกค้า" },
        { key: "items", label: "จำนวนรายการ", right: true },
        { key: "driver", label: "คนขับ" },
        { key: "plate", label: "ทะเบียนรถ" },
        { key: "status", label: "สถานะ", render: r => <Badge>{r.status}</Badge> }
      ]}
    />
  );
}

// ============ Tax Invoices ============
function TaxInvoices({ navigate }) {
  const D = window.SSSData;
  return (
    <DocListPage
      title="ใบกำกับภาษี · Tax Invoices"
      sub="ใบกำกับภาษีเต็มรูป / อย่างย่อ — รวมเข้า ภ.พ.30 อัตโนมัติ"
      docType="tax-invoice" rows={D.TaxInvoices}
      statusFilter={[]}
      createLabel="สร้างใบกำกับภาษี"
      onCreate={() => window.openNewDoc && window.openNewDoc("tax-invoice")}
      onRowClick={(r) => navigate("tax-invoices/" + r.no)}
      kpis={[
        { label: "ใบกำกับภาษีเดือนนี้", value: D.TaxInvoices.length, sub: "เต็มรูป 4 · ย่อ 1", icon: I.receipt },
        { label: "ฐานภาษี (ก่อน VAT)", value: `฿${fmt0(D.TaxInvoices.reduce((s,t)=>s+t.base,0))}`, sub: "ขายในประเทศ", icon: I.calc },
        { label: "VAT ขาย (output)", value: `฿${fmt0(D.TaxInvoices.reduce((s,t)=>s+t.vat,0))}`, sub: "ก่อนหักภาษีซื้อ", icon: I.tax },
        { label: "VAT สุทธิที่ต้องนำส่ง", value: "฿67,246", sub: "ภ.พ.30 ครบ 15 มิ.ย.", dir: "down", icon: I.bell }
      ]}
      columns={[
        { key: "no", label: "เลขที่", render: r => <span className="mono">{r.no}</span> },
        { key: "date", label: "วันที่" },
        { key: "customer", label: "ลูกค้า" },
        { key: "type", label: "ประเภท", render: r => <Badge tone={r.type === "เต็มรูป" ? "" : "outline"}>{r.type}</Badge> },
        { key: "base", label: "ฐานภาษี", right: true, render: r => <span className="amount">฿{fmtM(r.base)}</span> },
        { key: "vat", label: "VAT 7%", right: true, render: r => <span className="amount">฿{fmtM(r.vat)}</span> },
        { key: "amount", label: "รวมทั้งสิ้น", right: true, render: r => <span className="amount">฿{fmtM(r.amount)}</span> }
      ]}
    />
  );
}

// ============ Billing Notes ============
function BillingNotes({ navigate }) {
  const D = window.SSSData;
  return (
    <DocListPage
      title="ใบวางบิล · Billing Notes"
      sub="รวมใบแจ้งหนี้หลายใบ ส่งวางบิลลูกค้า"
      docType="billing-note" rows={D.BillingNotes}
      statusFilter={["ส่งแล้ว", "ลูกค้านัดรับ", "เก็บเงินแล้ว"]}
      createLabel="สร้างใบวางบิล"
      onCreate={() => window.openNewDoc && window.openNewDoc("billing-note")}
      onRowClick={(r) => navigate("billing-notes/" + r.no)}
      kpis={[
        { label: "ใบวางบิลเปิดอยู่", value: D.BillingNotes.filter(b=>b.status!=='เก็บเงินแล้ว').length, sub: `฿${fmt0(D.BillingNotes.filter(b=>b.status!=='เก็บเงินแล้ว').reduce((s,b)=>s+b.amount,0))}`, icon: I.invoice },
        { label: "นัดเก็บสัปดาห์นี้", value: 3, sub: "พุธ-ศุกร์", icon: I.clock },
        { label: "เก็บได้เดือนนี้", value: `฿${fmt0(D.BillingNotes.filter(b=>b.status==='เก็บเงินแล้ว').reduce((s,b)=>s+b.amount,0))}`, sub: "1 ใบ", dir: "up", icon: I.check },
        { label: "Average days to collect", value: "12 วัน", sub: "นับจากวันวางบิล", icon: I.calc }
      ]}
      columns={[
        { key: "no", label: "เลขที่", render: r => <span className="mono">{r.no}</span> },
        { key: "date", label: "วันที่" },
        { key: "customer", label: "ลูกค้า" },
        { key: "invoices", label: "Invoice รวม", render: r => <div style={{display: "flex", gap: 4, flexWrap: "wrap"}}>{r.invoices.map(i => <span key={i} className="badge outline mono" style={{fontSize: 10}}>{i}</span>)}</div> },
        { key: "amount", label: "ยอดรวม", right: true, render: r => <span className="amount">฿{fmt0(r.amount)}</span> },
        { key: "dueDate", label: "กำหนดเก็บ" },
        { key: "status", label: "สถานะ", render: r => <Badge>{r.status}</Badge> }
      ]}
    />
  );
}

window.Quotations = Quotations;
window.QuotationDetail = QuotationDetail;
window.Invoices = Invoices;
window.DeliveryNotes = DeliveryNotes;
window.TaxInvoices = TaxInvoices;
window.BillingNotes = BillingNotes;
window.DocListPage = DocListPage;
window.DocPaper = DocPaper;
