/* global React, I, UI */
// =============== หน้า "ส่งของประจำวัน" — จัดการภายใน + ประวัติ + export ===============
const { useState: useStateDD, useEffect: useEffectDD, useMemo: useMemoDD } = React;

function useDeliveries() {
  const [list, setList] = useStateDD(() => window.DeliveryStore.load());
  useEffectDD(() => {
    const h = () => setList(window.DeliveryStore.load());
    const evts = ["sss-deliveries-changed", "sss-data-synced", "sss-db-loaded"];
    evts.forEach(e => window.addEventListener(e, h));
    return () => evts.forEach(e => window.removeEventListener(e, h));
  }, []);
  const update = (next) => { setList(next); window.DeliveryStore.save(next); };
  return [list, update];
}

// ---------- การ์ดงานส่ง (วันนี้) ----------
const DD_CARD_COLORS = ["var(--c-blue)", "var(--c-violet)", "var(--c-cyan)", "var(--c-amber)", "var(--c-lime)", "var(--c-pink)"];
function ddCardColor(key) { let h = 0; const s = String(key || ""); for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) >>> 0; return DD_CARD_COLORS[h % DD_CARD_COLORS.length]; }
function DDCard({ d, onCheck, onEdit, onDelete, onView, onLinkDN, navigate }) {
  const { Btn, Badge } = window.UI;
  const sent = d.status === "ส่งแล้ว";
  const itemsChecked = (d.items || []).filter(it => it.checked).length;
  const cc = ddCardColor(d.customer || d.no); // สีประจำการ์ด (แยกตามลูกค้า กันหลง)
  return (
    <div style={{border: "1px solid var(--line)", borderRadius: 16, background: "var(--surface)", borderLeft: `6px solid ${cc}`, overflow: "hidden", boxShadow: "var(--shadow-sm)"}}>
      <div style={{padding: "16px 18px", display: "flex", gap: 16, alignItems: "flex-start", flexWrap: "wrap"}}>
        <div style={{minWidth: 62, textAlign: "center", background: `color-mix(in oklab, ${cc} 12%, transparent)`, borderRadius: 12, padding: "8px 6px"}}>
          <div style={{fontSize: 22, fontWeight: 800, color: cc, lineHeight: 1.1}}>{d.time}</div>
          <div style={{fontSize: 10, color: "var(--ink-3)", marginTop: 2}}>นัดส่ง</div>
        </div>
        <div style={{flex: 1, minWidth: 240}}>
          <div style={{display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap"}}>
            <span style={{fontWeight: 800, fontSize: 20, color: cc, letterSpacing: "-0.01em"}}>{d.customer}</span>
            <Badge>{d.status}</Badge>
            <span className="badge outline mono" style={{fontSize: 10}}>{d.no}</span>
            {d.ref && (
              <button className="badge outline mono" style={{fontSize: 10, cursor: "pointer", display: "inline-flex", alignItems: "center", gap: 4}}
                title={`เปิดใบส่งสินค้า ${d.ref}`} onClick={() => navigate && navigate("delivery-notes/" + d.ref)}>
                <I.doc size={10}/>{d.ref}
              </button>
            )}
          </div>
          {d.address && <div style={{fontSize: 12.5, color: "var(--ink-3)", marginTop: 4, display: "flex", alignItems: "center", gap: 4}}><I.truck size={12}/>{d.address}</div>}

          {/* รายการสินค้าแบบมีรูปใหญ่ */}
          <div style={{display: "flex", gap: 12, flexWrap: "wrap", marginTop: 12}}>
            {(d.items || []).map((it, i) => (
              <div key={i} onClick={() => it.photo && onView(it.photo)} style={{width: 280, display: "flex", gap: 12, alignItems: "center", padding: 10, border: "1px solid var(--line)", borderRadius: 14, background: "var(--surface-2)", cursor: it.photo ? "zoom-in" : "default"}}>
                {it.photo
                  ? <img src={it.photo} alt={it.name} style={{width: 104, height: 104, objectFit: "cover", borderRadius: 11, border: "1px solid var(--line)", flexShrink: 0}}/>
                  : <div style={{width: 104, height: 104, borderRadius: 11, border: "1px dashed var(--line-strong)", display: "grid", placeItems: "center", fontSize: 11, color: "var(--ink-4)", flexShrink: 0}}>ไม่มีรูป</div>}
                <div style={{minWidth: 0, flex: 1}}>
                  <div style={{fontSize: 14.5, fontWeight: 700, lineHeight: 1.3, overflow: "hidden", textOverflow: "ellipsis", display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", whiteSpace: "normal"}}>{it.name}</div>
                  <div style={{fontSize: 12.5, color: "var(--ink-3)", marginTop: 4}}><b style={{color: "var(--ink-1)", fontSize: 22}}>{it.qty}</b> {it.unit}</div>
                  {it.checked && <div style={{fontSize: 11.5, color: "var(--success)", fontWeight: 700, marginTop: 2}}>✓ ตรวจแล้ว</div>}
                </div>
              </div>
            ))}
          </div>

          {d.note && <div style={{fontSize: 12, padding: "5px 10px", background: "var(--info-bg)", color: "var(--info)", borderRadius: 5, marginTop: 8, display: "inline-block"}}>📝 {d.note}</div>}

          <div style={{display: "flex", alignItems: "center", gap: 12, marginTop: 8, fontSize: 11.5, color: "var(--ink-3)", flexWrap: "wrap"}}>
            <span style={{display: "inline-flex", alignItems: "center", gap: 6}}>
              <span className="avatar" style={{width: 20, height: 20, fontSize: 8}}>{(d.assigneeName || "?").slice(0, 2)}</span>
              {d.assigneeName}
            </span>
            <span>ตรวจนับ {itemsChecked}/{(d.items || []).length}</span>
            <span style={{display: "inline-flex", alignItems: "center", gap: 4}}><I.camera size={12}/>ก่อนส่ง {(d.photosBefore || []).length} · หลังส่ง {(d.photosAfter || []).length}</span>
            {sent && <span style={{color: "var(--success)", fontWeight: 600}}>✓ ส่งแล้ว {d.deliveredAt && `เวลา ${d.deliveredAt} น.`} {d.receiverName && `· ผู้รับ: ${d.receiverName}`}</span>}
          </div>
        </div>
        <div style={{display: "flex", flexDirection: "column", gap: 6, alignItems: "stretch", minWidth: 148}}>
          {!sent && <Btn size="sm" kind="primary" icon={I.check} onClick={onCheck}>ตรวจ + ส่งของ</Btn>}
          {sent && <Btn size="sm" kind="ghost" icon={I.edit} onClick={onCheck}>ดู / แก้ไขบันทึก</Btn>}
          <Btn size="sm" icon={I.print} onClick={() => window.printDeliveryA5(d)}>พิมพ์ใบส่งของ A5</Btn>
          <Btn size="sm" kind="ghost" icon={I.paperclip} onClick={onLinkDN}>{d.ref ? "เปลี่ยนใบที่ผูก" : "ผูกใบส่งของ"}</Btn>
          <div style={{display: "flex", gap: 6}}>
            <Btn size="sm" kind="ghost" icon={I.edit} onClick={onEdit} style={{flex: 1}}>แก้ไข</Btn>
            <button className="icon-btn" title="ลบ" onClick={onDelete}><I.trash size={13}/></button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ---------- เลือกรูปจากโปรเจกต์ (แกลเลอรี + รูปใบสั่งงาน) มาแนบรายการส่งของ ----------
function ProjectPhotoPicker({ defaultCode, onPick, onClose }) {
  const D = window.SSSData;
  const PX = window.ProjX;
  const projects = [...(PX && PX.upLoad ? PX.upLoad() : []), ...(D.Projects || [])];
  const [code, setCode] = useStateDD(defaultCode || (projects[0] && projects[0].code) || "");
  const x = PX && code ? PX.pxGet(code) : {};
  const proj = projects.find(p => p.code === code) || {};
  // รวมรูปทุกแหล่งของโปรเจกต์: แกลเลอรี · ใบสั่งงาน · อัปเดตงาน · รูปจากการส่งของที่ผูกโปรเจกต์
  const imgs = (() => {
    const out = [];
    const urlOf = (p) => (p && typeof p === "object") ? (p.url || p.src || "") : (p || "");
    const push = (p, name, src) => { const u = urlOf(p); if (u) out.push({ url: u, name: (p && p.name) || name || src, src }); };
    (x.gallery || []).forEach(g => push(g, g && g.name, "แกลเลอรี"));
    (proj.gallery || []).forEach(g => push(g, g && g.name, "แกลเลอรี"));
    (proj.photos || []).forEach(g => push(g, g && g.name, "รูปโปรเจกต์"));
    (x.workOrders || []).forEach(wo => (wo.photos || []).forEach(p => push(p, (p && p.name) || ("ใบสั่งงาน " + wo.no), "ใบสั่งงาน")));
    [...(x.updates || []), ...(proj.updates || [])].forEach(u => (u.proof || u.photos || []).forEach(p => push(p, "อัปเดตงาน", "อัปเดตงาน")));
    if (code) {
      const dels = (window.DeliveryStore && window.DeliveryStore.load ? window.DeliveryStore.load() : []).filter(d => {
        const hay = (d.ref || "") + " " + (d.note || "") + " " + (d.projectCode || "");
        return hay.includes(code);
      });
      dels.forEach(d => {
        [...(d.photos || []), ...(d.photosBefore || []), ...(d.photosAfter || [])].forEach(p => push(p, "รูปส่งของ", "ส่งของ"));
        (d.items || []).forEach(it => push(it && it.photo, it && it.name, "ส่งของ"));
      });
    }
    const seen = new Set();
    return out.filter(im => im.url && !seen.has(im.url) && seen.add(im.url));
  })();

  return (
    <div className="scrim" style={{display: "flex", alignItems: "center", justifyContent: "center", padding: 18, zIndex: 240}} onClick={onClose}>
      <div style={{background: "var(--surface)", borderRadius: 14, width: 620, maxWidth: "96vw", maxHeight: "90vh", display: "flex", flexDirection: "column", overflow: "hidden"}} onClick={e => e.stopPropagation()}>
        <div style={{padding: "14px 18px", borderBottom: "1px solid var(--line)", display: "flex", alignItems: "center", gap: 10}}>
          <div style={{flex: 1}}>
            <div style={{fontSize: 14.5, fontWeight: 700}}>เลือกรูปจากโปรเจกต์</div>
            <div style={{fontSize: 11.5, color: "var(--ink-3)"}}>{imgs.length > 0 ? `มีรูปให้เลือก ${imgs.length} รูป — แตะเพื่อแนบ` : "รวมจากแกลเลอรี · ใบสั่งงาน · อัปเดตงาน · การส่งของ"}</div>
          </div>
          <button className="icon-btn" onClick={onClose}><I.close size={14}/></button>
        </div>
        <div style={{padding: "12px 18px 0"}}>
          <div className="field"><label>โปรเจกต์</label>
            <select className="input mono" value={code} onChange={e => setCode(e.target.value)}>
              {projects.length === 0 && <option value="">— ไม่มีโปรเจกต์ —</option>}
              {projects.map(p => <option key={p.code} value={p.code}>{p.code} · {p.name}</option>)}
            </select>
          </div>
        </div>
        <div style={{padding: 18, overflow: "auto"}}>
          {imgs.length === 0 ? (
            <div style={{padding: 30, textAlign: "center", color: "var(--ink-3)", fontSize: 12.5, border: "1px dashed var(--line)", borderRadius: 10}}>โปรเจกต์นี้ยังไม่มีรูป — อัปโหลดรูปแบบ/หน้างานในโปรเจกต์ หรือใบสั่งงานก่อน</div>
          ) : (
            <div style={{display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(110px, 1fr))", gap: 8}}>
              {imgs.map((im, i) => (
                <div key={i} onClick={() => onPick(im.url)} title={im.name}
                  style={{aspectRatio: "1", borderRadius: 8, overflow: "hidden", border: "1px solid var(--line)", cursor: "pointer", position: "relative"}}>
                  <img src={im.url} alt={im.name} style={{width: "100%", height: "100%", objectFit: "cover"}}/>
                  {im.src && <span style={{position: "absolute", left: 4, bottom: 4, fontSize: 9.5, fontWeight: 600, background: "rgba(0,0,0,0.62)", color: "#fff", padding: "1px 6px", borderRadius: 5}}>{im.src}</span>}
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

// ---------- Modal เพิ่ม/แก้ไขงานส่ง (อัพโหลดรูปต่อรายการ) ----------
function DDEditModal({ initial, onClose, onSave }) {
  const D = window.SSSData;
  const { Btn } = window.UI;
  const S = window.DeliveryStore;
  const [f, setF] = useStateDD(initial || {
    customer: D.Customers[0].name,
    address: "",
    date: S.todayStr(),
    time: "10:00",
    assignee: "EMP-024",
    assigneeName: D.Employees.find(e => e.id === "EMP-024")?.name || "",
    note: "", ref: "",
    items: [{ name: "", qty: 1, unit: "ชิ้น", photo: null, checked: false }]
  });
  const [projPick, setProjPick] = useStateDD(null); // index ของรายการที่กำลังเลือกรูปจากโปรเจกต์
  const noteCode = ((f.note || "").match(/JOB-\d{4}-\d+/) || [])[0] || (/^JOB-/.test(f.ref || "") ? f.ref : "");
  const upd = (k, v) => setF(p => ({ ...p, [k]: v }));
  const updItem = (i, k, v) => setF(p => ({ ...p, items: p.items.map((it, j) => j === i ? { ...it, [k]: v } : it) }));

  const pickItemPhoto = async (i, e) => {
    const file = e.target.files[0];
    e.target.value = "";
    if (!file) return;
    const url = await S.resizeImage(file, 700);
    if (url) updItem(i, "photo", url);
  };

  const save = () => {
    const items = f.items.filter(it => it.name.trim());
    if (items.length === 0) { window.toast && window.toast("กรอกรายการสินค้าอย่างน้อย 1 รายการ"); return; }
    onSave({ ...f, items });
    onClose();
  };

  return (
    <div className="scrim" style={{display: "flex", alignItems: "center", justifyContent: "center", padding: 18, zIndex: 220}} onClick={onClose}>
      <div style={{background: "var(--surface)", borderRadius: 14, width: 640, maxWidth: "96vw", maxHeight: "94vh", display: "flex", flexDirection: "column", overflow: "hidden"}} onClick={e => e.stopPropagation()}>
        <div style={{padding: "16px 20px 12px", borderBottom: "1px solid var(--line)", display: "flex", alignItems: "center"}}>
          <div style={{flex: 1}}>
            <div style={{fontSize: 15, fontWeight: 700}}>{initial && initial.id ? `แก้ไขงานส่ง ${initial.no}` : "ลงรายการส่งของ"}</div>
            <div style={{fontSize: 12, color: "var(--ink-3)"}}>นัดส่ง {S.fmtThai(f.date || S.todayStr())}{(f.date || S.todayStr()) > S.todayStr() ? " (นัดล่วงหน้า — เตือนเมื่อถึงวัน)" : ""} · บันทึกแล้วระบบจะแจ้งเตือนทุกคน</div>
          </div>
          <button className="icon-btn" onClick={onClose}><I.close size={14}/></button>
        </div>

        <div style={{padding: "14px 20px", overflow: "auto", display: "flex", flexDirection: "column", gap: 12}}>
          <div className="field"><label>ลูกค้า</label>
            <select className="input" value={f.customer} onChange={e => {
              const name = e.target.value;
              setF(p => ({ ...p, customer: name, address: (p.address || "").trim() ? p.address : (window.DeliveryStore ? window.DeliveryStore.lastAddress(name) : "") }));
            }}>
              {D.Customers.map(c => <option key={c.id}>{c.name}</option>)}
              {!D.Customers.some(c => c.name === f.customer) && <option>{f.customer}</option>}
            </select>
          </div>
          <div className="field-row cols-2">
            <div className="field"><label>วันที่นัดส่ง (ตั้งล่วงหน้าได้)</label><input className="input" type="date" value={f.date || S.todayStr()} onChange={e => upd("date", e.target.value)}></input></div>
            <div className="field"><label>เวลานัดส่ง</label>{window.UI.TimeField ? <window.UI.TimeField value={f.time} onChange={v => upd("time", v)} minuteStep={5}/> : <input className="input" type="time" value={f.time} onChange={e => upd("time", e.target.value)}></input>}</div>
          </div>
          <div className="field"><label>ที่อยู่ / สถานที่ส่ง</label><input className="input" value={f.address} onChange={e => upd("address", e.target.value)} placeholder="เช่น 88/45 ถ.รัตนาธิเบศร์ นนทบุรี"></input></div>

          <div>
            <div className="label mb" style={{display: "flex", alignItems: "center", justifyContent: "space-between"}}>
              <span>รายการสินค้า — แนบรูปให้พนักงานดูและตรวจจำนวน</span>
            </div>
            <div style={{display: "flex", flexDirection: "column", gap: 8}}>
              {f.items.map((it, i) => (
                <div key={i} style={{display: "grid", gridTemplateColumns: "56px 1fr 72px 84px 30px", gap: 8, alignItems: "center", padding: 8, border: "1px solid var(--line)", borderRadius: 8, background: "var(--surface-2)"}}>
                  <div style={{display: "flex", flexDirection: "column", gap: 3, alignItems: "center"}}>
                    <label title="อัพโหลด/ถ่ายรูปสินค้า" style={{width: 56, height: 50, borderRadius: 6, overflow: "hidden", cursor: "pointer", border: it.photo ? "1px solid var(--line)" : "1.5px dashed var(--line-strong)", display: "grid", placeItems: "center", background: "var(--surface)", position: "relative"}}>
                      <input type="file" accept="image/*" style={{display: "none"}} onChange={e => pickItemPhoto(i, e)}></input>
                      {it.photo
                        ? <img src={it.photo} alt="" style={{width: "100%", height: "100%", objectFit: "cover", position: "absolute", inset: 0}}/>
                        : <span style={{display: "flex", flexDirection: "column", alignItems: "center", gap: 1, color: "var(--ink-3)"}}><I.camera size={15}/><span style={{fontSize: 8}}>รูป</span></span>}
                    </label>
                    <button type="button" className="btn" onClick={() => setProjPick(i)} title="เลือกรูปจากโปรเจกต์"
                      style={{padding: "1px 5px", fontSize: 8.5, lineHeight: 1.4, height: "auto", minHeight: 0}}>โปรเจกต์</button>
                  </div>
                  <window.UI.ProductAutocomplete placeholder="ชื่อสินค้า — พิมพ์เพื่อค้นหา" value={it.name}
                    onChange={v => updItem(i, "name", v)}
                    onPick={p => setF(prev => ({ ...prev, items: prev.items.map((x, j) => j === i ? { ...x, name: p.name, unit: p.unit || x.unit } : x) }))}/>
                  <input className="input" type="number" min="1" value={it.qty} onChange={e => updItem(i, "qty", +e.target.value)}></input>
                  <input className="input" placeholder="หน่วย" value={it.unit} onChange={e => updItem(i, "unit", e.target.value)}></input>
                  <button className="icon-btn" onClick={() => setF(p => ({ ...p, items: p.items.filter((_, j) => j !== i) }))}><I.trash size={12}/></button>
                </div>
              ))}
            </div>
            <div style={{marginTop: 8}}>
              <Btn size="sm" icon={I.plus} onClick={() => setF(p => ({ ...p, items: [...p.items, { name: "", qty: 1, unit: "ชิ้น", photo: null, checked: false }] }))}>เพิ่มรายการ</Btn>
            </div>
          </div>

          <div className="field-row cols-2">
            <div className="field"><label>พนักงานผู้ส่ง</label>
              <select className="input" value={f.assignee} onChange={e => {
                const emp = D.Employees.find(emp => emp.id === e.target.value);
                setF(p => ({ ...p, assignee: e.target.value, assigneeName: emp?.name || "" }));
              }}>
                {D.Employees.map(emp => <option key={emp.id} value={emp.id}>{emp.name} ({emp.role})</option>)}
              </select>
            </div>
            <div className="field"><label>ผูกกับใบส่งของ (ถ้ามี)</label>
              <select className="input mono" value={f.ref || ""} onChange={e => upd("ref", e.target.value)}>
                <option value="">— ไม่ผูกเอกสาร —</option>
                {(D.DeliveryNotes || []).map(dn => <option key={dn.no} value={dn.no}>{dn.no} · {dn.customer}</option>)}
                {f.ref && !(D.DeliveryNotes || []).some(dn => dn.no === f.ref) && <option value={f.ref}>{f.ref}</option>}
              </select>
            </div>
          </div>
          <div className="field"><label>หมายเหตุถึงพนักงาน (ผู้ติดต่อ, จุดส่ง, ข้อควรระวัง)</label>
            <textarea className="textarea" value={f.note} onChange={e => upd("note", e.target.value)} style={{minHeight: 56}}></textarea>
          </div>
        </div>

        <div style={{padding: "12px 20px", borderTop: "1px solid var(--line)", background: "var(--surface-2)", display: "flex", gap: 8, justifyContent: "flex-end"}}>
          <Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn>
          <Btn kind="primary" icon={I.check} onClick={save}>{initial && initial.id ? "บันทึกการแก้ไข" : "บันทึก + แจ้งเตือนทุกคน"}</Btn>
        </div>
      </div>
      {projPick !== null && <ProjectPhotoPicker defaultCode={noteCode} onClose={() => setProjPick(null)}
        onPick={(url) => { updItem(projPick, "photo", url); setProjPick(null); window.toast && window.toast("ใส่รูปจากโปรเจกต์แล้ว"); }}/>}
    </div>
  );
}

// ---------- Modal ผูกงานส่งกับใบส่งของ (DN) ----------
function DDLinkDNModal({ d, onClose, onSave }) {
  const D = window.SSSData;
  const { Btn, Badge } = window.UI;
  const [sel, setSel] = useStateDD(d.ref || "");
  const notes = D.DeliveryNotes || [];
  return (
    <div className="scrim" style={{display: "flex", alignItems: "center", justifyContent: "center", padding: 18, zIndex: 220}} onClick={onClose}>
      <div style={{background: "var(--surface)", borderRadius: 14, width: 480, maxWidth: "96vw", maxHeight: "90vh", display: "flex", flexDirection: "column", overflow: "hidden"}} onClick={e => e.stopPropagation()}>
        <div style={{padding: "16px 20px 12px", borderBottom: "1px solid var(--line)", display: "flex", alignItems: "center"}}>
          <div style={{flex: 1}}>
            <div style={{fontSize: 15, fontWeight: 700}}>ผูกกับใบส่งของ</div>
            <div style={{fontSize: 12, color: "var(--ink-3)"}}>งานส่ง <span className="mono">{d.no}</span> · {d.customer}</div>
          </div>
          <button className="icon-btn" onClick={onClose}><I.close size={14}/></button>
        </div>
        <div style={{padding: "12px 20px", overflow: "auto", display: "flex", flexDirection: "column", gap: 6}}>
          <label style={{display: "flex", gap: 10, alignItems: "center", padding: "9px 12px", border: `1.5px solid ${sel === "" ? "var(--ink-1)" : "var(--line)"}`, borderRadius: 8, cursor: "pointer", background: "var(--surface-2)"}}>
            <input type="radio" name="dd-link-dn" checked={sel === ""} onChange={() => setSel("")}></input>
            <span style={{fontSize: 13, color: "var(--ink-3)"}}>ไม่ผูกเอกสาร</span>
          </label>
          {notes.map(dn => (
            <label key={dn.no} style={{display: "flex", gap: 10, alignItems: "center", padding: "9px 12px", border: `1.5px solid ${sel === dn.no ? "var(--ink-1)" : "var(--line)"}`, borderRadius: 8, cursor: "pointer"}}>
              <input type="radio" name="dd-link-dn" checked={sel === dn.no} onChange={() => setSel(dn.no)}></input>
              <div style={{flex: 1, minWidth: 0}}>
                <div style={{display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap"}}>
                  <span className="mono" style={{fontSize: 12, fontWeight: 600}}>{dn.no}</span>
                  <Badge>{dn.status}</Badge>
                </div>
                <div style={{fontSize: 12, color: "var(--ink-3)", marginTop: 2}}>{dn.customer} · {dn.date}</div>
              </div>
            </label>
          ))}
        </div>
        <div style={{padding: "12px 20px", borderTop: "1px solid var(--line)", background: "var(--surface-2)", display: "flex", gap: 8, justifyContent: "flex-end"}}>
          <Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn>
          <Btn kind="primary" icon={I.check} onClick={() => { onSave(sel); onClose(); }}>บันทึกการผูก</Btn>
        </div>
      </div>
    </div>
  );
}

// ---------- ประวัติย้อนหลัง ----------
function DDHistory({ list, onView, onReprint, onCheck }) {
  const { Badge, Btn } = window.UI;
  const S = window.DeliveryStore;
  const groups = useMemoDD(() => {
    const m = {};
    list.forEach(d => { (m[d.date] = m[d.date] || []).push(d); });
    return Object.keys(m).sort().reverse().map(date => ({ date, rows: m[date].sort((a, b) => (a.time || "").localeCompare(b.time || "")) }));
  }, [list]);

  if (groups.length === 0) return <div style={{padding: 30, textAlign: "center", color: "var(--ink-3)", fontSize: 13}}>ยังไม่มีประวัติการส่งของ</div>;

  return (
    <div style={{display: "flex", flexDirection: "column", gap: 16}}>
      {groups.map(g => {
        const sent = g.rows.filter(d => d.status === "ส่งแล้ว").length;
        return (
          <div key={g.date}>
            <div style={{display: "flex", alignItems: "center", gap: 10, marginBottom: 8}}>
              <div style={{fontSize: 13, fontWeight: 700}}>{S.fmtThai(g.date)}{g.date === S.todayStr() ? " (วันนี้)" : ""}</div>
              <span style={{fontSize: 11.5, color: "var(--ink-3)"}}>{g.rows.length} รายการ · ส่งสำเร็จ {sent}</span>
              <div style={{flex: 1, height: 1, background: "var(--line)"}}></div>
            </div>
            <div style={{display: "flex", flexDirection: "column", gap: 6}}>
              {g.rows.map(d => (
                <div key={d.id} style={{display: "flex", gap: 12, alignItems: "center", padding: "9px 12px", border: "1px solid var(--line)", borderRadius: 8, background: "var(--surface)", flexWrap: "wrap"}}>
                  <span className="mono" style={{fontSize: 11, color: "var(--ink-3)", minWidth: 84}}>{d.no}</span>
                  <span style={{fontSize: 12, minWidth: 42, fontWeight: 600}}>{d.time}</span>
                  <div style={{flex: 1, minWidth: 180}}>
                    <div style={{fontSize: 12.5, fontWeight: 600}}>{d.customer}</div>
                    <div style={{fontSize: 11, color: "var(--ink-3)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", maxWidth: 380}}>
                      {(d.items || []).map(i => `${i.qty} ${i.unit} ${i.name}`).join(" · ")}
                    </div>
                  </div>
                  <div style={{display: "flex", gap: 3}}>
                    {[...(d.photosBefore || []), ...(d.photosAfter || [])].slice(0, 3).map((p, i) => (
                      <img key={i} src={p.url} alt="" onClick={() => onView(p.url)} style={{width: 30, height: 30, objectFit: "cover", borderRadius: 4, border: "1px solid var(--line)", cursor: "zoom-in"}}/>
                    ))}
                  </div>
                  {d.signature && <img src={d.signature} alt="ลายเซ็น" onClick={() => onView(d.signature)} style={{width: 56, height: 26, objectFit: "contain", background: "white", borderRadius: 4, border: "1px solid var(--line)", cursor: "zoom-in"}}/>}
                  <Badge>{d.status}</Badge>
                  <span style={{fontSize: 11, color: "var(--ink-3)", minWidth: 90}}>{d.status === "ส่งแล้ว" ? `ผู้รับ: ${d.receiverName || "—"}` : `ผู้ส่ง: ${d.assigneeName || "—"}`}</span>
                  <div style={{display: "flex", gap: 4}}>
                    <button className="icon-btn" title="ดู / แก้ไขบันทึก" onClick={() => onCheck(d)}><I.search size={13}/></button>
                    <button className="icon-btn" title="พิมพ์ใบส่งของ A5" onClick={() => onReprint(d)}><I.print size={13}/></button>
                  </div>
                </div>
              ))}
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ---------- หน้าใหญ่ ----------
function DailyDeliveryPage({ navigate }) {
  const { Btn, Badge, Stat, Card, PageHead, Tabs } = window.UI;
  const S = window.DeliveryStore;
  const A = window.DeliveryAlertAPI;
  const [list, update] = useDeliveries();
  const [tab, setTab] = useStateDD("today");
  const [showNew, setShowNew] = useStateDD(false);
  const [editing, setEditing] = useStateDD(null);
  const [checking, setChecking] = useStateDD(null);
  const [linking, setLinking] = useStateDD(null);
  const [viewer, setViewer] = useStateDD(null);
  const [freq, setFreqUI] = useStateDD(() => A.getFreq());

  const today = list.filter(d => d.date === S.todayStr());
  const sentToday = today.filter(d => d.status === "ส่งแล้ว").length;
  const upcoming = list.filter(d => (d.date || "") > S.todayStr())
    .sort((a, b) => (a.date || "").localeCompare(b.date || "") || (a.time || "").localeCompare(b.time || ""));
  const upcomingByDate = {};
  upcoming.forEach(d => { (upcomingByDate[d.date] = upcomingByDate[d.date] || []).push(d); });
  const daysAhead = (iso) => Math.round((new Date(iso + "T00:00:00") - new Date(S.todayStr() + "T00:00:00")) / 86400000);
  const aheadLabel = (iso) => { const n = daysAhead(iso); return n === 1 ? "พรุ่งนี้" : `อีก ${n} วัน`; };

  const patchDelivery = (id, patch) => update(list.map(d => d.id === id ? { ...d, ...patch } : d));

  const addDelivery = (f) => {
    const date = f.date || S.todayStr();
    const rec = window.DeliveryStore.normalize({
      ...f, id: "TD-" + Date.now(), no: S.genNo(list), date, status: "รอส่ง",
      photosBefore: [], photosAfter: [], signature: null, receiverName: "", deliveredAt: ""
    });
    update([...list, rec]);
    const future = date > S.todayStr();
    if (!future) A.triggerNow(); // เด้งเตือนทุก user ทุกหน้าจอ (เฉพาะงานวันนี้)
    window.logActivity && window.logActivity("ลงรายการส่งของ", `${rec.no} · ${rec.customer}${future ? " (นัด " + S.fmtThai(date) + ")" : ""}`, "delivery");
    window.toast && window.toast(future ? `นัดส่งล่วงหน้า ${S.fmtThai(date)} · ${rec.no} — จะเตือนทุกคนเมื่อถึงวัน` : `บันทึก ${rec.no} แล้ว — แจ้งเตือนทุกคนทุกหน้าจอ`);
  };

  const removeDelivery = async (d) => {
    const ok = await (window.confirmDelete ? window.confirmDelete(`งานส่ง ${d.no}`, d.customer) : Promise.resolve(confirm("ลบ?")));
    if (ok) update(list.filter(x => x.id !== d.id));
  };

  const exportSummary = () => {
    const rows = [...list].sort((a, b) => (b.date + b.time).localeCompare(a.date + a.time)).map(d => ({
      date: S.fmtThai(d.date), no: d.no, time: d.time, customer: d.customer, address: d.address,
      items: (d.items || []).map(i => `${i.name} x${i.qty} ${i.unit}`).join(" | "),
      qty: (d.items || []).reduce((s, i) => s + (Number(i.qty) || 0), 0),
      assignee: d.assigneeName, status: d.status,
      deliveredAt: d.deliveredAt || "—", receiver: d.receiverName || "—",
      photos: `ก่อน ${(d.photosBefore || []).length} / หลัง ${(d.photosAfter || []).length}`,
      signed: d.signature ? "เซ็นแล้ว" : "—"
    }));
    window.exportRowsCSV("สรุปส่งของประจำวัน", [
      { key: "date", label: "วันที่" }, { key: "no", label: "เลขที่ใบส่งของ" }, { key: "time", label: "เวลานัด" },
      { key: "customer", label: "ลูกค้า" }, { key: "address", label: "สถานที่ส่ง" }, { key: "items", label: "รายการ" },
      { key: "qty", label: "จำนวนรวม" }, { key: "assignee", label: "พนักงานผู้ส่ง" }, { key: "status", label: "สถานะ" },
      { key: "deliveredAt", label: "เวลาส่งจริง" }, { key: "receiver", label: "ผู้เซ็นรับ" },
      { key: "photos", label: "รูปถ่าย" }, { key: "signed", label: "ลายเซ็น" }
    ], rows);
  };

  const pickFreq = (min) => { A.setFreq(min); setFreqUI(min); window.toast && window.toast(`ตั้งเตือน${A.freqLabel(min)}แล้ว`); };

  return (
    <>
      <PageHead
        title="ส่งของประจำวัน"
        sub={`จัดการภายใน · วันนี้ ${S.fmtThai(S.todayStr())} · เหลือส่ง ${today.length - sentToday} รายการ`}
        right={<>
          <Btn icon={I.download} kind="ghost" onClick={exportSummary}>ส่งออกสรุป (Excel)</Btn>
          <Btn icon={I.plus} kind="primary" onClick={() => setShowNew(true)}>ลงรายการส่งวันนี้</Btn>
        </>}
      />

      <div className="stat-grid" style={{display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(170px, 1fr))", gap: 12, marginBottom: 16}}>
        <Stat label="งานส่งวันนี้" value={today.length} sub={`รวม ${today.reduce((s, d) => s + (d.items || []).length, 0)} รายการสินค้า`} icon={I.truck}/>
        <Stat label="ส่งสำเร็จแล้ว" value={sentToday} sub={today.length ? `${Math.round(sentToday / today.length * 100)}% ของวันนี้` : "—"} icon={I.check}/>
        <Stat label="รอส่ง / กำลังส่ง" value={today.length - sentToday} sub="ระบบเตือนซ้ำจนส่งครบ" icon={I.clock}/>
        <div className="stat">
          <div className="label"><I.bell size={14}/>เตือนกันลืม (ทุก user)</div>
          <div style={{display: "flex", gap: 4, flexWrap: "wrap", marginTop: 8}}>
            {A.FREQ_OPTIONS.map(o => (
              <button key={o.min} className={`btn sm ${freq === o.min ? "primary" : ""}`} onClick={() => pickFreq(o.min)}>{o.label.replace("ทุก ", "")}</button>
            ))}
          </div>
          <div className="delta"><span>เด้งทุกหน้าจอ{A.freqLabel(freq)} จนส่งครบ</span></div>
        </div>
      </div>

      <Tabs items={[
        { key: "today", label: "งานส่งวันนี้", count: today.length },
        { key: "upcoming", label: "กำลังจะถึง", count: upcoming.length },
        { key: "history", label: "บันทึกย้อนหลัง", count: list.length }
      ]} active={tab} onChange={setTab}/>

      <div style={{marginTop: 14}}>
        {tab === "today" && (
          today.length === 0
            ? <div style={{padding: 40, textAlign: "center", color: "var(--ink-3)", fontSize: 13, border: "1px dashed var(--line)", borderRadius: 10}}>
                ยังไม่มีงานส่งของวันนี้ — กด "ลงรายการส่งวันนี้" เพื่อเริ่ม ระบบจะแจ้งเตือนทุกคนอัตโนมัติ
              </div>
            : <div style={{display: "flex", flexDirection: "column", gap: 10}}>
                {[...today].sort((a, b) => (a.time || "").localeCompare(b.time || "")).map(d => (
                  <DDCard key={d.id} d={d}
                    onCheck={() => setChecking(d)}
                    onEdit={() => setEditing(d)}
                    onDelete={() => removeDelivery(d)}
                    onLinkDN={() => setLinking(d)}
                    navigate={navigate}
                    onView={setViewer}/>
                ))}
              </div>
        )}
        {tab === "upcoming" && (
          upcoming.length === 0
            ? <div style={{padding: 40, textAlign: "center", color: "var(--ink-3)", fontSize: 13, border: "1px dashed var(--line)", borderRadius: 10}}>
                ยังไม่มีงานนัดส่งล่วงหน้า — ตอนลงรายการ ตั้ง "วันที่นัดส่ง" เป็นวันในอนาคต ระบบจะเตือนทุกคนเมื่อถึงวันนั้น
              </div>
            : <div style={{display: "flex", flexDirection: "column", gap: 16}}>
                {Object.keys(upcomingByDate).sort().map(date => (
                  <div key={date}>
                    <div style={{display: "flex", alignItems: "center", gap: 8, margin: "0 2px 8px"}}>
                      <span style={{fontSize: 13.5, fontWeight: 700}}>{S.fmtThai(date)}</span>
                      <Badge tone="info">{aheadLabel(date)}</Badge>
                      <span style={{fontSize: 12, color: "var(--ink-3)"}}>{upcomingByDate[date].length} งาน</span>
                    </div>
                    <div style={{display: "flex", flexDirection: "column", gap: 10}}>
                      {upcomingByDate[date].map(d => (
                        <DDCard key={d.id} d={d} onCheck={() => setChecking(d)} onEdit={() => setEditing(d)}
                          onDelete={() => removeDelivery(d)} onLinkDN={() => setLinking(d)} navigate={navigate} onView={setViewer}/>
                      ))}
                    </div>
                  </div>
                ))}
              </div>
        )}
        {tab === "history" && (
          <DDHistory list={list} onView={setViewer}
            onReprint={(d) => window.printDeliveryA5(d)}
            onCheck={(d) => setChecking(d)}/>
        )}
      </div>

      {showNew && <DDEditModal onClose={() => setShowNew(false)} onSave={addDelivery}/>}
      {editing && <DDEditModal initial={editing} onClose={() => setEditing(null)} onSave={(f) => patchDelivery(editing.id, f)}/>}
      {linking && <DDLinkDNModal d={linking} onClose={() => setLinking(null)} onSave={(ref) => {
        patchDelivery(linking.id, { ref });
        window.toast && window.toast(ref ? `ผูก ${linking.no} กับใบส่งของ ${ref} แล้ว` : `ยกเลิกการผูกเอกสารของ ${linking.no} แล้ว`);
      }}/>}
      {checking && <window.DeliveryCheckModal delivery={checking} onClose={() => setChecking(null)}
        onSave={(patch) => { patchDelivery(checking.id, patch); setChecking(null); }}/>}

      {viewer && (
        <div onClick={() => setViewer(null)} style={{position: "fixed", inset: 0, zIndex: 300, background: "rgba(0,0,0,0.8)", display: "flex", alignItems: "center", justifyContent: "center", padding: 30, cursor: "zoom-out"}}>
          <img src={viewer} alt="preview" style={{maxWidth: "92%", maxHeight: "92%", borderRadius: 8, background: "white"}}/>
        </div>
      )}
    </>
  );
}

window.DailyDeliveryPage = DailyDeliveryPage;
window.DDEditModal = DDEditModal;

// สร้าง "ใบส่งของประจำวัน" จากที่อื่น (เช่น ใบสั่งงาน) — ทำงานเหมือนการเพิ่มในหน้าส่งของ
// (gen เลขที่/ไอดี/วันที่ + แจ้งเตือนทุกคน + ลง log) แล้วหน้าส่งของจะอัปเดตเองผ่าน event
window.createDelivery = function (f) {
  const S = window.DeliveryStore;
  const list = S.load();
  const date = f.date || S.todayStr();
  const rec = S.normalize({
    ...f, id: "TD-" + Date.now(), no: S.genNo(list), date, status: "รอส่ง",
    photosBefore: [], photosAfter: [], signature: null, receiverName: "", deliveredAt: ""
  });
  S.save([...list, rec]);
  const future = date > S.todayStr();
  try { if (!future) window.DeliveryAlertAPI && window.DeliveryAlertAPI.triggerNow(); } catch (e) {}
  window.logActivity && window.logActivity("ลงรายการส่งของ", `${rec.no} · ${rec.customer}`, "delivery");
  window.toast && window.toast(future ? `นัดส่งล่วงหน้า ${S.fmtThai(date)} · ${rec.no}` : `ออกใบส่งของ ${rec.no} แล้ว — แจ้งเตือนทุกคนทุกหน้าจอ`);
  return rec;
};
