/* global React, I, UI */
// ═══ จอสถานีงาน · Station Display ═══════════════════════════════════════════
// เปิดค้างบนจอ/แท็บเล็ตประจำสถานี (เลือกสถานีครั้งเดียว จอจำเอง ต่อเครื่อง)
//   🏭 เครื่องตัด  = คิวเครื่องจักร + เช็คเบิกแผ่น + กดสถานะ ตัดแล้ว
//   📐🔩🎨✨🔧 ช่าง = การ์ดงานประเภทนั้นจากใบสั่งงานทุกใบ + ปุ่ม รับเรื่อง/กำลังทำ/เสร็จ
// ข้อมูลตัวเดียวกับหน้าโปรเจกต์/คิวเครื่องจักร — กดที่สถานีแล้วทุกเครื่องเห็นตาม (sync ~5 วิ)
const { useState: useStateST, useEffect: useEffectST } = React;

const ST_KEY = "sss-station-id";   // จอเครื่องนี้เป็นสถานีอะไร — ตั้งใจ "ไม่ sync" (ตั้งค่าต่อจอ)
const ST_LIST = [
  { id: "machine", label: "เครื่องตัด · คิวเครื่องจักร", emoji: "🏭", color: "#b91c1c", desc: "คิวตัดวันนี้ · เบิกแผ่น · กดตัดแล้ว" },
  { id: "bend",    label: "งานพับ/ม้วน",   emoji: "📐", color: "#b45309", desc: "การ์ดพับ/ม้วนจากใบสั่งงานทุกใบ" },
  { id: "weld",    label: "งานเชื่อม/ประกอบ", emoji: "🔩", color: "#475569", desc: "การ์ดเชื่อม/ประกอบทุกใบ" },
  { id: "paint",   label: "งานทำสี",       emoji: "🎨", color: "#7c3aed", desc: "การ์ดทำสี + สีของแต่ละชิ้น" },
  { id: "decor",   label: "งานตกแต่ง",     emoji: "✨", color: "#db2777", desc: "เจียร์ / ขัด / เก็บงาน" },
  { id: "custom",  label: "งานกำหนดเอง",   emoji: "🔧", color: "#57534e", desc: "การ์ดที่ตั้งชื่อเอง เช่น งานออกแบบ" },
];
const stStation = (id) => ST_LIST.find(s => s.id === id) || null;
const stActor = () => (window.Session && window.Session.get() && window.Session.get().name)
  || (window.SSSData.Company.currentUser && window.SSSData.Company.currentUser.name) || "";
const stToday = () => (window.ProjX && window.ProjX.pxTodayISO ? window.ProjX.pxTodayISO() : new Date().toISOString().slice(0, 10));
const stThai = (iso) => (window.ProjX ? window.ProjX.pxThaiDate(iso) : iso || "—");
const stLS = (k, d) => (window.lsRead ? window.lsRead(k, d) : d);
function stLSSet(k, v) { if (window.lsSyncSet) window.lsSyncSet(k, v); else { try { localStorage.setItem(k, JSON.stringify(v)); } catch (e) {} } }

// โปรเจกต์ทั้งหมด (ผู้ใช้สร้าง + ระบบ) ที่ไม่ถูกซ่อน
function stProjects() {
  const D = window.SSSData, PX = window.ProjX;
  const users = PX && PX.upLoad ? (PX.upLoad() || []) : [];
  const base = (D.Projects || []).filter(p => !users.some(u => u.code === p.code));
  return [...users, ...base].filter(p => !((PX ? PX.pxGet(p.code) : {}) || {}).hidden);
}

// การ์ดของประเภทที่เลือก จากใบสั่งงานทุกใบ (พับรวมม้วนเดิม)
function stCards(typeId) {
  const PX = window.ProjX;
  const types = typeId === "bend" ? ["bend", "roll"] : [typeId];
  const out = [];
  stProjects().forEach(p => {
    const ex = PX ? PX.pxGet(p.code) : {};
    (ex.workOrders || []).forEach(wo => (wo.cards || []).forEach((c, ci) => {
      if (!types.includes(c.type)) return;
      out.push({ project: p, wo, card: c, ci });
    }));
  });
  const rank = (c) => c.status === "กำลังทำ" ? 0 : c.status === "เสร็จแล้ว" ? 2 : 1;
  out.sort((a, b) => rank(a.card) - rank(b.card) || String(a.card.due || a.wo.due || "").localeCompare(String(b.card.due || b.wo.due || "")));
  return out;
}

// บันทึกการ์ด (สถานะ/รับเรื่อง) กลับเข้าใบสั่งงาน + ซิงค์คิวเครื่อง/งานส่งของ
function stSaveCard(project, woNo, cardId, patch) {
  const PX = window.ProjX;
  const ex = PX.pxGet(project.code) || {};
  const wos = (ex.workOrders || []).map(w => w.no !== woNo ? w
    : { ...w, cards: (w.cards || []).map(c => c.id === cardId ? { ...c, ...patch } : c) });
  PX.pxSet(project.code, { workOrders: wos });
  const wo2 = wos.find(w => w.no === woNo);
  try { window.WOCards.syncQueue(woNo, wo2.cards, project); } catch (e) {}
  try { window.WOCards.syncDeliveries(woNo, wo2.cards, project); } catch (e) {}
  try { window.dispatchEvent(new Event("sss-projects-changed")); } catch (e) {}
}

// หาการ์ดต้นทางของงานคิวเครื่อง (id: MQC-<เลขใบ>-<idการ์ด>)
function stCardOfJob(job) {
  const m = /^MQC-(.+)-([^-]+)$/.exec(String(job.id || ""));
  if (!m) return null;
  const PX = window.ProjX;
  for (const p of stProjects()) {
    const ex = PX ? PX.pxGet(p.code) : {};
    for (const wo of (ex.workOrders || [])) {
      if (wo.no !== m[1]) continue;
      const card = (wo.cards || []).find(c => c.id === m[2]);
      if (card) return { project: p, wo, card };
    }
  }
  return null;
}

// ── ปุ่มสถานะตัวใหญ่ (จอโรงงาน — กดง่าย เห็นไกล) ──
function STBtn({ on, color, children, onClick, ghost }) {
  return (
    <button onClick={onClick} style={{
      padding: "12px 20px", borderRadius: 12, fontFamily: "inherit", fontSize: 16, fontWeight: 800, cursor: "pointer",
      border: `2px solid ${on ? color : "var(--line-strong)"}`,
      background: on ? color : (ghost ? "transparent" : "var(--surface)"),
      color: on ? "#fff" : "var(--ink-2)", flexShrink: 0 }}>
      {children}
    </button>
  );
}

function STPhotoRow({ photos }) {
  if (!photos || !photos.length) return null;
  return (
    <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
      {photos.slice(0, 6).map((u, i) => (
        <img key={i} src={u} alt="" onClick={() => window.openPhotoZoom && window.openPhotoZoom(photos, i)}
          style={{ width: 110, height: 90, objectFit: "contain", background: "#fff", borderRadius: 10, border: "1px solid var(--line)", cursor: "zoom-in" }}/>
      ))}
      {photos.length > 6 && <span onClick={() => window.openPhotoZoom && window.openPhotoZoom(photos, 6)}
        style={{ width: 110, height: 90, borderRadius: 10, border: "1.5px dashed var(--line-strong)", display: "grid", placeItems: "center", fontSize: 15, color: "var(--ink-3)", cursor: "pointer" }}>+{photos.length - 6}</span>}
    </div>
  );
}

// ── กริยาประจำสถานี — ปุ่ม/ข้อความพูดภาษาเดียวกับหน้างาน ──
const ST_VERB = { bend: "พับ", roll: "ม้วน", weld: "เชื่อม/ประกอบ", paint: "ทำสี", decor: "เก็บงาน", custom: "ทำงาน" };
const stVerb = (t) => ST_VERB[t] || "ทำงาน";
const stKey = (r) => r.wo.no + "/" + r.card.id;

// บันทึกลำดับลากของการ์ดหลายใบ (จัดกลุ่มต่อโปรเจกต์ เขียนทีเดียว — ไม่ยิง sync รัว)
function stSetCardOrds(rows, pos) {
  const PX = window.ProjX;
  const byProject = {};
  rows.forEach(r => {
    const ord = pos[stKey(r)];
    if (ord == null || r.card.stOrd === ord) return;
    (byProject[r.project.code] = byProject[r.project.code] || []).push({ r, ord });
  });
  Object.entries(byProject).forEach(([code, list]) => {
    const ex = PX.pxGet(code) || {};
    const wos = (ex.workOrders || []).map(w => ({ ...w, cards: (w.cards || []).map(c => {
      const hit = list.find(x => x.r.wo.no === w.no && x.r.card.id === c.id);
      return hit ? { ...c, stOrd: hit.ord } : c;
    }) }));
    PX.pxSet(code, { workOrders: wos });
  });
  try { window.dispatchEvent(new Event("sss-projects-changed")); } catch (e) {}
}

// ── งานกำลังทำ (ฝั่งซ้าย จอช่าง): บล็อกรายชิ้น รูปใหญ่+รายละเอียดตามอัตลักษณ์ + ติ๊กเสร็จรายชิ้น ──
function STTechActive({ row, accent, refresh }) {
  const { project, wo, card } = row;
  const t = window.WOCards.type(card.type);
  const verb = stVerb(card.type);
  const specLabel = (t.extra && t.extra.label) || "สเปค/หมายเหตุ";
  const items = (card.items || []).filter(x => x.name || (x.photos || []).length);
  const doneItems = card.doneItems || [];
  const set = (patch) => { stSaveCard(project, wo.no, card.id, patch); refresh(); };
  const toggleItem = (k) => set({ doneItems: doneItems.includes(k) ? doneItems.filter(x => x !== k) : [...doneItems, k] });
  const allDone = items.length > 0 && items.every((_, k) => doneItems.includes(k));
  return (
    <div style={{ border: `2px solid ${accent}55`, borderRadius: 16, background: "var(--surface)", overflow: "hidden", marginBottom: 12 }}>
      <div style={{ padding: "11px 16px", background: `linear-gradient(90deg, ${accent}1e, transparent)`, display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
        <b style={{ fontSize: 19 }}>{t.emoji} {card.title || t.label}</b>
        <span className="mono" style={{ fontSize: 13, color: "var(--ink-3)" }}>{wo.no}</span>
        <span style={{ fontSize: 13.5, color: "var(--ink-2)", fontWeight: 600 }}>{project.name}</span>
        <span style={{ marginLeft: "auto", fontSize: 13.5, fontWeight: 700, color: "var(--warning)" }}>🏁 {stThai(card.due || wo.due) || "—"}</span>
      </div>
      <div style={{ padding: "10px 14px", display: "flex", flexDirection: "column", gap: 10 }}>
        {card.detail && <div style={{ fontSize: 14.5, color: "var(--ink-2)", whiteSpace: "pre-wrap", lineHeight: 1.5 }}>📝 {card.detail}</div>}
        {items.map((x, k) => {
          const dk = doneItems.includes(k);
          const phs = x.photos || [];
          return (
            <div key={k} style={{ display: "grid", gridTemplateColumns: "minmax(0, 1.5fr) minmax(0, 1fr)", gap: 10, opacity: dk ? 0.55 : 1 }}>
              <div style={{ border: "1.5px solid #86efac", background: "rgba(34,197,94,0.06)", borderRadius: 13, padding: 10, display: "flex", flexDirection: "column", gap: 6 }}>
                {phs.length
                  ? <>
                      <img src={phs[0]} onClick={() => window.openPhotoZoom && window.openPhotoZoom(phs, 0)}
                        style={{ width: "100%", maxHeight: 250, objectFit: "contain", borderRadius: 9, background: "#fff", cursor: "zoom-in" }}/>
                      {phs.length > 1 && (
                        <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
                          {phs.slice(1).map((u, i) => <img key={i} src={u} onClick={() => window.openPhotoZoom && window.openPhotoZoom(phs, i + 1)}
                            style={{ width: 72, height: 54, objectFit: "contain", borderRadius: 7, background: "#fff", border: "1px solid var(--line)", cursor: "zoom-in" }}/>)}
                        </div>
                      )}
                    </>
                  : <div style={{ height: 110, display: "grid", placeItems: "center", color: "var(--ink-3)", fontSize: 14, border: "1.5px dashed var(--line-strong)", borderRadius: 9 }}>ไม่มีแบบแนบ — ดูใบงาน/สอบถามผู้สั่งงาน</div>}
              </div>
              <div style={{ border: "1.5px solid #93c5fd", background: "rgba(59,130,246,0.06)", borderRadius: 13, padding: "10px 13px", display: "flex", flexDirection: "column", gap: 6 }}>
                <b style={{ fontSize: 17 }}>{k + 1}. {x.name || "(ดูแบบ)"}</b>
                <div style={{ fontSize: 26, fontWeight: 800 }}>{x.qty || 1} <span style={{ fontSize: 13, fontWeight: 400, color: "var(--ink-3)" }}>{x.unit || "ชุด"}</span></div>
                {x.spec && <div style={{ fontSize: 15.5, fontWeight: 800, color: accent }}>⚙️ {specLabel}: {x.spec}</div>}
                {x.material && <div style={{ fontSize: 14 }}>🧱 {x.material}</div>}
                <div style={{ marginTop: "auto" }}>
                  <STBtn color="#15803d" on={dk} onClick={() => toggleItem(k)}>{dk ? "↩️ ยังไม่เสร็จ" : `✔️ ชิ้นนี้${verb}แล้ว`}</STBtn>
                </div>
              </div>
            </div>
          );
        })}
        {items.length === 0 && <div style={{ padding: 20, textAlign: "center", color: "var(--ink-3)" }}>การ์ดนี้ไม่มีรายการชิ้นแนบ — ดูรายละเอียดจากใบงานกระดาษ</div>}
        <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap", borderTop: "1px dashed var(--line)", paddingTop: 10 }}>
          {card.ack && <span style={{ fontSize: 13, fontWeight: 700, color: "var(--success)" }}>🙋 รับเรื่อง · {card.ack.by || ""}</span>}
          {card.assigneeName && <span style={{ fontSize: 13, color: "var(--ink-3)" }}>👤 {card.assigneeName}</span>}
          {(card.helpers || []).length > 0 && <span style={{ fontSize: 12.5, color: "var(--ink-3)" }}>🤝 {(card.helpers || []).map(h => h.name).join(", ")}</span>}
          {allDone && <span style={{ fontSize: 13, fontWeight: 800, color: "var(--success)" }}>🎉 ครบทุกชิ้น — กดเสร็จแล้วได้เลย</span>}
          <span style={{ marginLeft: "auto", display: "flex", gap: 8, flexWrap: "wrap" }}>
            <STBtn color="#dc2626" on={false} onClick={() => set({ issue: { by: stActor(), at: Date.now() } })}>⚠️ ติดปัญหา</STBtn>
            <STBtn color="#57534e" on={false} onClick={() => set({ status: "รอทำ" })}>⏸ พัก · กลับเข้าคิว</STBtn>
            <STBtn color="#15803d" on={false} onClick={() => set({ status: "เสร็จแล้ว" })}>✅ {verb}เสร็จทั้งใบ</STBtn>
          </span>
        </div>
      </div>
    </div>
  );
}

// ── การ์ดคิวงานช่าง (ฝั่งขวา) — ลากเรียง / ลากไปเริ่มทำ / ลากเข้าติดปัญหา ──
function STTechQueueCard({ row, late, refresh, drag }) {
  const { project, wo, card } = row;
  const t = window.WOCards.type(card.type);
  const verb = stVerb(card.type);
  const n = (card.items || []).filter(x => x.name || (x.photos || []).length).length;
  const set = (patch) => { stSaveCard(project, wo.no, card.id, patch); refresh(); };
  const btn = (label, color, onClick) => (
    <button onClick={onClick} style={{ border: `1.5px solid ${color}55`, color, background: "var(--surface)", borderRadius: 8, padding: "4px 10px", fontSize: 12.5, fontWeight: 800, cursor: "pointer", fontFamily: "inherit" }}>{label}</button>
  );
  return (
    <div draggable onDragStart={() => drag.start(stKey(row))} onDragEnd={drag.end}
      onDragOver={e => e.preventDefault()} onDrop={e => { e.stopPropagation(); drag.dropBefore(stKey(row)); }}
      style={{ border: late ? "2px solid var(--danger)" : "1px solid var(--line)", borderRadius: 12, background: "var(--surface)", padding: "9px 12px", cursor: "grab", display: "flex", flexDirection: "column", gap: 5 }}>
      <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
        <span style={{ fontSize: 15, color: "var(--ink-4)", cursor: "grab" }} title="ลากเพื่อจัดลำดับ">⠿</span>
        <b style={{ fontSize: 14.5, flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{t.emoji} {card.title || t.label}</b>
        {card.ack && <span title={"รับเรื่องแล้ว · " + (card.ack.by || "")} style={{ fontSize: 13 }}>🙋</span>}
      </div>
      <div style={{ fontSize: 12, color: late ? "var(--danger)" : "var(--ink-3)", fontWeight: late ? 800 : 500, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
        {late ? "⚠️ เลยกำหนด · " : ""}{wo.no} · {project.name}{n ? ` · ${n} ชิ้น` : ""} · 🏁 {stThai(card.due || wo.due) || "—"}
      </div>
      <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
        {!card.ack && btn("🙋 รับเรื่อง", "#0d9488", () => set({ ack: { by: stActor(), at: Date.now() } }))}
        {btn(`▶️ เริ่ม${verb}`, "#1d4ed8", () => set({ status: "กำลังทำ", issue: null, ack: card.ack || { by: stActor(), at: Date.now() } }))}
        {btn("⚠️", "#dc2626", () => set({ issue: { by: stActor(), at: Date.now() } }))}
      </div>
    </div>
  );
}

// ── บอร์ดสถานีช่าง (พับ/เชื่อม/สี/ตกแต่ง/กำหนดเอง): ซ้ายงานกำลังทำ · ขวาคิวลากได้ · โซนติดปัญหา ──
function STTechBoard({ st, refresh }) {
  const today = stToday();
  const rows = stCards(st.id);
  const verb = stVerb(st.id === "bend" ? "bend" : st.id);
  const ordOf = r => (r.card.stOrd != null ? r.card.stOrd : Infinity);
  const dueKey = r => String(r.card.due || r.wo.due || "9999-99-99");
  const doing = rows.filter(r => r.card.status === "กำลังทำ" && !r.card.issue);
  const queue = rows.filter(r => r.card.status !== "เสร็จแล้ว" && r.card.status !== "กำลังทำ" && !r.card.issue)
    .sort((a, b) => (ordOf(a) - ordOf(b)) || dueKey(a).localeCompare(dueKey(b)));
  const issues = rows.filter(r => r.card.issue && r.card.status !== "เสร็จแล้ว");
  const doneRecent = rows.filter(r => r.card.status === "เสร็จแล้ว").slice(0, 5);
  const dragRef = React.useRef(null);
  const findRow = (k) => rows.find(r => stKey(r) === k);
  const dropBefore = (targetKey) => {
    const k = dragRef.current; dragRef.current = null;
    if (!k || k === targetKey) return;
    const r = findRow(k); if (!r) return;
    if (r.card.status === "กำลังทำ") stSaveCard(r.project, r.wo.no, r.card.id, { status: "รอทำ", issue: null });
    else if (r.card.issue) stSaveCard(r.project, r.wo.no, r.card.id, { issue: null });
    const keys = queue.filter(x => stKey(x) !== k).map(x => stKey(x));
    const at = targetKey ? keys.indexOf(targetKey) : keys.length;
    keys.splice(at < 0 ? keys.length : at, 0, k);
    const pos = {}; keys.forEach((x, i) => { pos[x] = (i + 1) * 10; });
    stSetCardOrds(rows, pos);
    refresh();
  };
  const drag = { start: (k) => { dragRef.current = k; }, end: () => {}, dropBefore };
  const dropTo = (patch) => {
    const k = dragRef.current; dragRef.current = null;
    const r = k && findRow(k);
    if (r) { stSaveCard(r.project, r.wo.no, r.card.id, typeof patch === "function" ? patch(r) : patch); refresh(); }
  };
  const panel = (extra) => ({ border: "1px solid var(--line)", borderRadius: 16, background: "var(--surface-2)", padding: "12px 12px", ...extra });
  return (
    <div style={{ display: "grid", gridTemplateColumns: "minmax(0, 1fr) 350px", gap: 14, alignItems: "start" }}>
      <div onDragOver={e => e.preventDefault()} onDrop={() => dropTo(r => ({ status: "กำลังทำ", issue: null, ack: r.card.ack || { by: stActor(), at: Date.now() } }))}
        style={panel({ minHeight: 340, background: "var(--surface)" })}>
        <div style={{ fontSize: 17, fontWeight: 800, marginBottom: 10 }}>🔥 งานกำลัง{verb} ({doing.length})</div>
        {doing.map(r => <STTechActive key={stKey(r)} row={r} accent={st.color} refresh={refresh}/>)}
        {doing.length === 0 && (
          <div style={{ border: "2px dashed var(--line-strong)", borderRadius: 14, padding: "60px 20px", textAlign: "center", color: "var(--ink-3)", fontSize: 15.5 }}>
            🖱️ ลากงานจากคิวมาวางตรงนี้ หรือกด <b>▶️ เริ่ม{verb}</b> ที่การ์ดในคิว
          </div>
        )}
        {doneRecent.length > 0 && (
          <div style={{ marginTop: 12, fontSize: 12.5, color: "var(--ink-3)" }}>
            ✅ เสร็จล่าสุด: {doneRecent.map(r => (r.card.title || r.wo.no)).join(" · ")}
          </div>
        )}
      </div>
      <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
        <div onDragOver={e => e.preventDefault()} onDrop={() => dropBefore(null)} style={panel({})}>
          <div style={{ fontSize: 16, fontWeight: 800, marginBottom: 9 }}>📋 คิวงาน ({queue.length}) <span style={{ fontSize: 11, fontWeight: 500, color: "var(--ink-3)" }}>ลาก ⠿ จัดลำดับได้</span></div>
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {queue.map(r => <STTechQueueCard key={stKey(r)} row={r} refresh={refresh} drag={drag}
              late={!!((r.card.due || r.wo.due) && String(r.card.due || r.wo.due) < today)}/>)}
            {queue.length === 0 && <div style={{ padding: 20, textAlign: "center", color: "var(--ink-3)", fontSize: 13.5 }}>🎉 ไม่มีงานรอคิว</div>}
          </div>
        </div>
        <div onDragOver={e => e.preventDefault()} onDrop={() => dropTo({ issue: { by: stActor(), at: Date.now() } })}
          style={panel({ background: "rgba(220,38,38,0.07)", border: "1.5px solid rgba(220,38,38,0.35)" })}>
          <div style={{ fontSize: 16, fontWeight: 800, color: "#dc2626", marginBottom: 9 }}>⚠️ ติดปัญหา ({issues.length})</div>
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {issues.map(r => (
              <div key={stKey(r)} draggable onDragStart={() => drag.start(stKey(r))}
                style={{ border: "1px solid rgba(220,38,38,0.4)", borderRadius: 12, background: "var(--surface)", padding: "9px 12px", cursor: "grab" }}>
                <b style={{ fontSize: 14 }}>{r.card.title || r.wo.no}</b>
                <div style={{ fontSize: 11.5, color: "var(--ink-3)", margin: "3px 0 6px" }}>{r.wo.no} · แจ้งโดย {(r.card.issue || {}).by || "—"}</div>
                <button onClick={() => { stSaveCard(r.project, r.wo.no, r.card.id, { issue: null }); refresh(); }}
                  style={{ border: "1.5px solid var(--line-strong)", background: "var(--surface)", borderRadius: 8, padding: "4px 10px", fontSize: 12.5, fontWeight: 800, cursor: "pointer", fontFamily: "inherit" }}>↩️ กลับเข้าคิว</button>
              </div>
            ))}
            {issues.length === 0 && <div style={{ fontSize: 12, color: "var(--ink-3)", textAlign: "center", padding: 8 }}>ลากงานที่มีปัญหา (รอแบบ/รอวัสดุ/รอชิ้นก่อนหน้า) มาพักตรงนี้</div>}
          </div>
        </div>
      </div>
    </div>
  );
}

// ── อัพเดทงานคิว + สะท้อนสถานะกลับการ์ดต้นทาง (หน้าโปรเจกต์/ใบสั่งงานเห็นตรงกัน) ──
function stSetJob(job, patch, refresh) {
  const all = stLS("sss-machine-queue", []) || [];
  stLSSet("sss-machine-queue", all.map(j => j.id === job.id ? { ...j, ...patch } : j));
  if (patch.status) {
    const src = stCardOfJob(job);
    if (src) {
      const cs = patch.status === "เสร็จ" ? "เสร็จแล้ว" : patch.status === "กำลังทำ" ? "กำลังทำ" : "รอทำ";
      stSaveCard(src.project, src.wo.no, src.card.id, { status: cs });
    }
  }
  if (refresh) refresh();
}

// ── งานกำลังตัด (ฝั่งซ้าย): บล็อกรายชิ้น รูปใหญ่+รายละเอียด + ติ๊กเสร็จรายชิ้น + ปุ่มครบ ──
function STCutActive({ job, machines, refresh }) {
  const src = stCardOfJob(job);
  const items = src ? (src.card.items || []).filter(x => x.name || (x.photos || []).length) : [];
  const mats = [...new Set(items.map(x => (x.material || "").trim()).filter(Boolean))];
  const mName = (machines.find(m => m.id === job.machineId) || {}).name || job.machineId || "—";
  const doneItems = job.doneItems || [];
  const [showMat, setShowMat] = useStateST(false);
  const setJob = (patch) => stSetJob(job, patch, refresh);
  const cancelMat = async () => {
    const md = job.matDone || {};
    const withStock = Array.isArray(md.items) && md.items.length;
    const ok = window.confirmDialog
      ? await window.confirmDialog({ title: "ยกเลิกการเบิกแผ่น?", message: withStock ? "จะคืนสต็อกเข้าคลัง และถอนต้นทุนออกจากโปรเจกต์ให้ด้วย" : "เอาเครื่องหมายเบิกแล้วออก", confirmText: "ยกเลิกเบิก", danger: true })
      : window.confirm("ยกเลิกการเบิกแผ่น?");
    if (!ok) return;
    if (withStock && window.InvOps) {
      const projectCode = src ? src.project : (job.project || "");
      md.items.forEach(it => {
        window.InvOps.adjust(it.sku, Number(it.qty) || 0, { reason: "ยกเลิกเบิก · คืนสต็อก" + (projectCode ? " · " + projectCode : ""), by: stActor() });
        window.InvOps.removeExpense(projectCode, `MATX-${job.id}-${it.sku}`);
      });
      window.toast && window.toast("↩️ คืนสต็อก + ถอนต้นทุนออกจากงานแล้ว");
    }
    setJob({ matDone: null });
  };
  const toggleItem = (k) => setJob({ doneItems: doneItems.includes(k) ? doneItems.filter(x => x !== k) : [...doneItems, k] });
  const allDone = items.length > 0 && items.every((_, k) => doneItems.includes(k));
  return (
    <div style={{ border: "2px solid rgba(185,28,28,0.35)", borderRadius: 16, background: "var(--surface)", overflow: "hidden", marginBottom: 12 }}>
      <div style={{ padding: "11px 16px", background: "linear-gradient(90deg, rgba(185,28,28,0.12), transparent)", display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap" }}>
        <b style={{ fontSize: 19 }}>{job.title || "งานตัด"}</b>
        <span style={{ marginLeft: "auto", fontSize: 14, fontWeight: 700, color: "var(--info)" }}>🏭 {mName} · {stThai(job.date)} {job.start || ""}{job.end ? "–" + job.end : ""}</span>
      </div>
      <div style={{ padding: "10px 14px", display: "flex", flexDirection: "column", gap: 10 }}>
        {items.map((x, k) => {
          const dk = doneItems.includes(k);
          const phs = x.photos || [];
          return (
            <div key={k} style={{ display: "grid", gridTemplateColumns: "minmax(0, 1.5fr) minmax(0, 1fr)", gap: 10, opacity: dk ? 0.55 : 1 }}>
              {/* รูปงาน/แบบงาน (เขียว) */}
              <div style={{ border: "1.5px solid #86efac", background: "rgba(34,197,94,0.06)", borderRadius: 13, padding: 10, display: "flex", flexDirection: "column", gap: 6 }}>
                {phs.length
                  ? <>
                      <img src={phs[0]} onClick={() => window.openPhotoZoom && window.openPhotoZoom(phs, 0)}
                        style={{ width: "100%", maxHeight: 250, objectFit: "contain", borderRadius: 9, background: "#fff", cursor: "zoom-in" }}/>
                      {phs.length > 1 && (
                        <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
                          {phs.slice(1).map((u, i) => <img key={i} src={u} onClick={() => window.openPhotoZoom && window.openPhotoZoom(phs, i + 1)}
                            style={{ width: 72, height: 54, objectFit: "contain", borderRadius: 7, background: "#fff", border: "1px solid var(--line)", cursor: "zoom-in" }}/>)}
                        </div>
                      )}
                    </>
                  : <div style={{ height: 120, display: "grid", placeItems: "center", color: "var(--ink-3)", fontSize: 14, border: "1.5px dashed var(--line-strong)", borderRadius: 9 }}>ไม่มีแบบแนบ — ดูใบงาน/สอบถามผู้สั่งงาน</div>}
              </div>
              {/* รายละเอียด (ฟ้า) */}
              <div style={{ border: "1.5px solid #93c5fd", background: "rgba(59,130,246,0.06)", borderRadius: 13, padding: "10px 13px", display: "flex", flexDirection: "column", gap: 6 }}>
                <b style={{ fontSize: 17 }}>{k + 1}. {x.name || "(ดูแบบ)"}</b>
                <div style={{ fontSize: 26, fontWeight: 800 }}>{x.qty || 1} <span style={{ fontSize: 13, fontWeight: 400, color: "var(--ink-3)" }}>{x.unit || "ชุด"}</span></div>
                {x.material && <div style={{ fontSize: 14 }}>🧱 {x.material}</div>}
                {x.path && <div className="mono" style={{ fontSize: 12, color: "var(--ink-3)", wordBreak: "break-all" }}>📁 {x.path}</div>}
                {x.spec && <div style={{ fontSize: 14, fontWeight: 700, color: "#b91c1c" }}>⚙️ {x.spec}</div>}
                <div style={{ marginTop: "auto" }}>
                  <STBtn color="#15803d" on={dk} onClick={() => toggleItem(k)}>{dk ? "↩️ ยังไม่เสร็จ" : "✔️ ชิ้นนี้ตัดแล้ว"}</STBtn>
                </div>
              </div>
            </div>
          );
        })}
        {items.length === 0 && <div style={{ padding: 20, textAlign: "center", color: "var(--ink-3)" }}>งานนี้ไม่มีรายการชิ้นแนบ — ดูรายละเอียดจากใบงานกระดาษ</div>}
        {/* แถบปุ่มล่าง */}
        <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap", borderTop: "1px dashed var(--line)", paddingTop: 10 }}>
          <STBtn color="#b45309" on={!!job.matDone} onClick={() => { if (job.matDone) cancelMat(); else setShowMat(true); }}>
            {job.matDone ? `📄 เบิกแผ่นแล้ว · ${job.matDone.by || ""}` : `📄 เบิกวัสดุ${mats.length ? " (" + mats.join(" · ") + ")" : ""}`}
          </STBtn>
          {!!(job.matDone && Array.isArray(job.matDone.items) && job.matDone.items.length) && (
            <span style={{ fontSize: 12, color: "var(--ink-3)", fontWeight: 600 }}>🧾 {job.matDone.items.map(it => `${it.name} x${it.qty}`).join(" · ")}</span>
          )}
          {allDone && <span style={{ fontSize: 13, fontWeight: 800, color: "var(--success)" }}>🎉 ครบทุกชิ้นแล้ว — กดตัดแล้วได้เลย</span>}
          <span style={{ marginLeft: "auto", display: "flex", gap: 8, flexWrap: "wrap" }}>
            <STBtn color="#dc2626" on={false} onClick={() => setJob({ issue: { by: stActor(), at: Date.now() } })}>⚠️ ติดปัญหา</STBtn>
            <STBtn color="#57534e" on={false} onClick={() => setJob({ status: "รอคิว" })}>⏸ พัก · กลับเข้าคิว</STBtn>
            <STBtn color="#15803d" on={false} onClick={() => setJob({ status: "เสร็จ" })}>✅ ตัดแล้วทั้งงาน</STBtn>
          </span>
        </div>
      </div>
      {showMat && <STMatModal job={job} src={src} mats={mats} onClose={() => setShowMat(false)}
        onDone={(md) => { setShowMat(false); setJob({ matDone: md }); }}/>}
    </div>
  );
}

// ── การ์ดงานในคิว (ฝั่งขวา) — ลากเรียงลำดับ / ลากไปฝั่งซ้ายเพื่อเริ่มตัด / ลากเข้าติดปัญหา ──
function STQueueCard({ job, late, refresh, drag }) {
  const src = stCardOfJob(job);
  const n = src ? (src.card.items || []).filter(x => x.name || (x.photos || []).length).length : 0;
  const btn = (label, color, onClick) => (
    <button onClick={onClick} style={{ border: `1.5px solid ${color}55`, color, background: "var(--surface)", borderRadius: 8, padding: "4px 10px", fontSize: 12.5, fontWeight: 800, cursor: "pointer", fontFamily: "inherit" }}>{label}</button>
  );
  return (
    <div draggable onDragStart={() => drag.start(job.id)} onDragEnd={drag.end}
      onDragOver={e => e.preventDefault()} onDrop={e => { e.stopPropagation(); drag.dropBefore(job.id); }}
      style={{ border: late ? "2px solid var(--danger)" : "1px solid var(--line)", borderRadius: 12, background: "var(--surface)", padding: "9px 12px", cursor: "grab", display: "flex", flexDirection: "column", gap: 5 }}>
      <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
        <span style={{ fontSize: 15, color: "var(--ink-4)", cursor: "grab" }} title="ลากเพื่อจัดลำดับ">⠿</span>
        <b style={{ fontSize: 14.5, flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{job.title || "งานตัด"}</b>
      </div>
      <div style={{ fontSize: 12, color: late ? "var(--danger)" : "var(--ink-3)", fontWeight: late ? 800 : 500 }}>
        {late ? "⚠️ เลยกำหนด · " : ""}{stThai(job.date)} {job.start || ""}{n ? ` · ${n} ชิ้น` : ""}{job.matDone ? " · 📄 เบิกแล้ว" : ""}
      </div>
      <div style={{ display: "flex", gap: 6 }}>
        {btn("▶️ เริ่มตัด", "#1d4ed8", () => stSetJob(job, { status: "กำลังทำ", issue: null }, refresh))}
        {btn("⚠️ ติดปัญหา", "#dc2626", () => stSetJob(job, { issue: { by: stActor(), at: Date.now() } }, refresh))}
      </div>
    </div>
  );
}

// ── บอร์ดเครื่องตัด: ซ้าย "งานกำลังตัด" · ขวา "คิวงาน" ลากเรียงได้ · โซนแดง "ติดปัญหา" ──
function STCutBoard({ machines, refresh }) {
  const today = stToday();
  const all = (stLS("sss-machine-queue", []) || []).slice();
  const ordOf = j => (j.ord != null ? j.ord : Infinity);
  const dtKey = j => String(j.date || "9999-99-99") + "T" + (j.start || "99:99");
  const doing = all.filter(j => j.status === "กำลังทำ" && !j.issue);
  const queue = all.filter(j => j.status !== "เสร็จ" && j.status !== "กำลังทำ" && !j.issue)
    .sort((a, b) => (ordOf(a) - ordOf(b)) || dtKey(a).localeCompare(dtKey(b)));
  const issues = all.filter(j => j.issue && j.status !== "เสร็จ");
  const doneRecent = all.filter(j => j.status === "เสร็จ").sort((a, b) => dtKey(b).localeCompare(dtKey(a))).slice(0, 5);
  const dragRef = React.useRef(null);
  const findJob = (id) => all.find(x => x.id === id);
  // จัดลำดับคิว: วาง "ก่อน" การ์ดเป้าหมาย (null = ต่อท้าย) แล้วบันทึกเลขลำดับใหม่ทั้งชุด
  const dropBefore = (targetId) => {
    const id = dragRef.current; dragRef.current = null;
    if (!id || id === targetId) return;
    const j = findJob(id); if (!j) return;
    if (j.status === "กำลังทำ") stSetJob(j, { status: "รอคิว", issue: null }, null);
    else if (j.issue) stSetJob(j, { issue: null }, null);
    const ids = queue.filter(x => x.id !== id).map(x => x.id);
    const at = targetId ? ids.indexOf(targetId) : ids.length;
    ids.splice(at < 0 ? ids.length : at, 0, id);
    const pos = {}; ids.forEach((x, i) => { pos[x] = (i + 1) * 10; });
    const fresh = stLS("sss-machine-queue", []) || [];
    stLSSet("sss-machine-queue", fresh.map(x => pos[x.id] != null ? { ...x, ord: pos[x.id] } : x));
    refresh();
  };
  const drag = { start: (id) => { dragRef.current = id; }, end: () => {}, dropBefore };
  const dropTo = (patch) => {
    const id = dragRef.current; dragRef.current = null;
    const j = id && findJob(id);
    if (j) stSetJob(j, patch, refresh);
  };
  const panel = (extra) => ({ border: "1px solid var(--line)", borderRadius: 16, background: "var(--surface-2)", padding: "12px 12px", ...extra });
  return (
    <div style={{ display: "grid", gridTemplateColumns: "minmax(0, 1fr) 350px", gap: 14, alignItems: "start" }}>
      {/* ซ้าย: งานกำลังตัด (ลากงานมาวาง = เริ่มตัด) */}
      <div onDragOver={e => e.preventDefault()} onDrop={() => dropTo({ status: "กำลังทำ", issue: null })} style={panel({ minHeight: 340, background: "var(--surface)" })}>
        <div style={{ fontSize: 17, fontWeight: 800, marginBottom: 10 }}>🔥 งานกำลังตัด ({doing.length})</div>
        {doing.map(j => <STCutActive key={j.id} job={j} machines={machines} refresh={refresh}/>)}
        {doing.length === 0 && (
          <div style={{ border: "2px dashed var(--line-strong)", borderRadius: 14, padding: "60px 20px", textAlign: "center", color: "var(--ink-3)", fontSize: 15.5 }}>
            🖱️ ลากงานจากคิวมาวางตรงนี้ หรือกด <b>▶️ เริ่มตัด</b> ที่การ์ดในคิว
          </div>
        )}
        {doneRecent.length > 0 && (
          <div style={{ marginTop: 12, fontSize: 12.5, color: "var(--ink-3)" }}>
            ✅ เสร็จล่าสุด: {doneRecent.map(j => j.title || "งานตัด").join(" · ")}
          </div>
        )}
      </div>
      {/* ขวา: คิวงาน (ลากเรียง) + ติดปัญหา */}
      <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
        <div onDragOver={e => e.preventDefault()} onDrop={() => dropBefore(null)} style={panel({})}>
          <div style={{ fontSize: 16, fontWeight: 800, marginBottom: 9 }}>📋 คิวงาน ({queue.length}) <span style={{ fontSize: 11, fontWeight: 500, color: "var(--ink-3)" }}>ลาก ⠿ จัดลำดับได้</span></div>
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {queue.map(j => <STQueueCard key={j.id} job={j} late={!!(j.date && j.date < today)} refresh={refresh} drag={drag}/>)}
            {queue.length === 0 && <div style={{ padding: 20, textAlign: "center", color: "var(--ink-3)", fontSize: 13.5 }}>🎉 ไม่มีงานรอคิว</div>}
          </div>
        </div>
        <div onDragOver={e => e.preventDefault()} onDrop={() => dropTo({ issue: { by: stActor(), at: Date.now() } })}
          style={panel({ background: "rgba(220,38,38,0.07)", border: "1.5px solid rgba(220,38,38,0.35)" })}>
          <div style={{ fontSize: 16, fontWeight: 800, color: "#dc2626", marginBottom: 9 }}>⚠️ ติดปัญหา ({issues.length})</div>
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {issues.map(j => (
              <div key={j.id} draggable onDragStart={() => drag.start(j.id)}
                style={{ border: "1px solid rgba(220,38,38,0.4)", borderRadius: 12, background: "var(--surface)", padding: "9px 12px", cursor: "grab" }}>
                <b style={{ fontSize: 14 }}>{j.title || "งานตัด"}</b>
                <div style={{ fontSize: 11.5, color: "var(--ink-3)", margin: "3px 0 6px" }}>แจ้งโดย {(j.issue || {}).by || "—"} · {stThai(j.date)}</div>
                <button onClick={() => stSetJob(j, { issue: null }, refresh)}
                  style={{ border: "1.5px solid var(--line-strong)", background: "var(--surface)", borderRadius: 8, padding: "4px 10px", fontSize: 12.5, fontWeight: 800, cursor: "pointer", fontFamily: "inherit" }}>↩️ กลับเข้าคิว</button>
              </div>
            ))}
            {issues.length === 0 && <div style={{ fontSize: 12, color: "var(--ink-3)", textAlign: "center", padding: 8 }}>ลากงานที่มีปัญหา (รอแบบ/รอวัสดุ/เครื่องเสีย) มาพักตรงนี้</div>}
          </div>
        </div>
      </div>
    </div>
  );
}

// ── โมดัลเบิกแผ่น: ผูกคลังสินค้า + โปรเจกต์ ──
// เลือกวัสดุจริงจากคลัง (ค้นหา/แนะนำจากวัสดุในการ์ด) → ตัดสต็อก + บันทึกเคลื่อนไหว + ลงต้นทุนงานทันที
function STMatModal({ job, src, mats, onClose, onDone }) {
  const { Btn, Drawer } = window.UI;
  const D = window.SSSData;
  const products = D.Products || [];
  const [q, setQ] = useStateST("");
  const [rows, setRows] = useStateST(() => {
    // แนะนำอัตโนมัติ: จับคู่วัสดุในการ์ด (เช่น "SUS304 2mm") กับสินค้าในคลัง
    const out = [];
    (mats || []).forEach(m => {
      const ml = m.toLowerCase();
      const hit = products.find(p => p.name && (p.name.toLowerCase().includes(ml) || ml.includes(p.name.toLowerCase())));
      if (hit && !out.some(r => r.sku === hit.sku)) out.push({ sku: hit.sku, name: hit.name, unit: hit.unit || "แผ่น", stock: hit.stock, qty: 1 });
    });
    return out;
  });
  const sq = q.trim().toLowerCase();
  const hits = sq ? products.filter(p => [p.name, p.sku, p.category].some(v => String(v || "").toLowerCase().includes(sq))).slice(0, 8) : [];
  const addRow = (p) => {
    setRows(rs => rs.some(r => r.sku === p.sku) ? rs : [...rs, { sku: p.sku, name: p.name, unit: p.unit || "แผ่น", stock: p.stock, qty: 1 }]);
    setQ("");
  };
  const confirm = () => {
    const valid = rows.filter(r => r.sku && Number(r.qty) > 0);
    if (!valid.length) { window.toast && window.toast("เลือกวัสดุอย่างน้อย 1 รายการ หรือกด \"เบิกโดยไม่ตัดสต็อก\""); return; }
    const projectCode = src ? src.project : (job.project || "");
    valid.forEach(r => {
      window.InvOps && window.InvOps.adjust(r.sku, -Number(r.qty), {
        projectCode, by: stActor(), reason: job.title || "เบิกแผ่นหน้าเครื่อง",
        expId: `MATX-${job.id}-${r.sku}`,
      });
    });
    onDone({ by: stActor(), at: Date.now(), items: valid.map(r => ({ sku: r.sku, name: r.name, qty: Number(r.qty), unit: r.unit })) });
    window.toast && window.toast(`📄 เบิกแล้ว ${valid.length} รายการ — ตัดสต็อก + ลงต้นทุนงาน ${projectCode || ""} ✓`);
  };
  return (
    <Drawer open title={`📄 เบิกแผ่น/วัสดุ — ${job.title || "งานตัด"}`} onClose={onClose} wide
      footer={<div style={{ display: "flex", gap: 8, justifyContent: "space-between", width: "100%", flexWrap: "wrap" }}>
        <Btn onClick={() => onDone({ by: stActor(), at: Date.now() })} title="กรณีวัสดุไม่อยู่ในระบบคลัง">📄 เบิกโดยไม่ตัดสต็อก</Btn>
        <span style={{ display: "flex", gap: 8 }}>
          <Btn onClick={onClose}>ยกเลิก</Btn>
          <Btn kind="primary" onClick={confirm}>✅ เบิก + ตัดสต็อก ({rows.filter(r => Number(r.qty) > 0).length})</Btn>
        </span>
      </div>}>
      {mats && mats.length > 0 && <div style={{ fontSize: 12.5, color: "var(--ink-3)", marginBottom: 8 }}>วัสดุตามใบงาน: <b>{mats.join(" · ")}</b></div>}
      <div style={{ position: "relative", marginBottom: 10 }}>
        <input className="input" placeholder="🔍 ค้นวัสดุ/แผ่นจากคลังสินค้า — ชื่อ / SKU / หมวด" value={q} onChange={e => setQ(e.target.value)} autoFocus/>
        {hits.length > 0 && (
          <div style={{ position: "absolute", top: "calc(100% + 3px)", left: 0, right: 0, zIndex: 60, background: "var(--surface)", border: "1px solid var(--line-strong)", borderRadius: 9, boxShadow: "0 12px 32px rgba(0,0,0,0.22)", maxHeight: 280, overflowY: "auto" }}>
            {hits.map(p => (
              <div key={p.sku} onMouseDown={e => { e.preventDefault(); addRow(p); }}
                style={{ display: "flex", justifyContent: "space-between", gap: 10, padding: "9px 12px", cursor: "pointer", borderBottom: "1px solid var(--line)", fontSize: 13.5 }}>
                <span style={{ fontWeight: 600 }}>{p.name} <span className="mono" style={{ fontSize: 10.5, color: "var(--ink-3)" }}>{p.sku}</span></span>
                <span style={{ color: (Number(p.stock) || 0) > 0 ? "var(--success)" : "var(--danger)", fontWeight: 700 }}>คงเหลือ {p.stock || 0} {p.unit || ""}</span>
              </div>
            ))}
          </div>
        )}
      </div>
      {rows.length === 0 && <div style={{ padding: 18, textAlign: "center", color: "var(--ink-3)", fontSize: 12.5 }}>ยังไม่ได้เลือกวัสดุ — ค้นจากช่องด้านบน หรือถ้าวัสดุไม่อยู่ในคลัง กด "เบิกโดยไม่ตัดสต็อก"</div>}
      <div style={{ display: "flex", flexDirection: "column", gap: 7 }}>
        {rows.map((r, i) => (
          <div key={r.sku} style={{ display: "grid", gridTemplateColumns: "1fr 96px 84px 34px", gap: 8, alignItems: "center", border: "1px solid var(--line)", borderRadius: 10, padding: "8px 12px", background: "var(--surface-2)" }}>
            <div>
              <div style={{ fontWeight: 700, fontSize: 13.5 }}>{r.name}</div>
              <div style={{ fontSize: 11, color: (Number(r.stock) || 0) >= Number(r.qty) ? "var(--ink-3)" : "var(--danger)", fontWeight: 600 }}>คงเหลือ {r.stock || 0} {r.unit}{(Number(r.stock) || 0) < Number(r.qty) ? " — ⚠️ ไม่พอ (ตัดได้ต่ำสุด 0)" : ""}</div>
            </div>
            <input className="input mono" type="number" min="0" step="any" value={r.qty} onChange={e => setRows(rs => rs.map((x, j) => j === i ? { ...x, qty: e.target.value } : x))} style={{ textAlign: "right", fontWeight: 700 }}/>
            <span style={{ fontSize: 12.5, color: "var(--ink-3)" }}>{r.unit}</span>
            <button className="icon-btn" title="เอาออก" onClick={() => setRows(rs => rs.filter((_, j) => j !== i))}>✕</button>
          </div>
        ))}
      </div>
    </Drawer>
  );
}

function StationPage({ navigate }) {
  const { PageHead, Btn, Card } = window.UI;
  const routeSt = (window.location.hash.replace("#/", "").split("/")[1] || "").trim();
  const [stId, setStId] = useStateST(() => routeSt || (() => { try { return localStorage.getItem(ST_KEY) || ""; } catch { return ""; } })());
  const [, force] = useStateST(0);
  const refresh = () => force(n => n + 1);
  useEffectST(() => {
    const h = () => refresh();
    const evts = ["sss-localstore-polled", "sss-data-synced", "sss-projects-changed", "sss-db-loaded"];
    evts.forEach(e => window.addEventListener(e, h));
    const clock = setInterval(refresh, 30000);
    return () => { evts.forEach(e => window.removeEventListener(e, h)); clearInterval(clock); };
  }, []);
  const pick = (id) => {
    setStId(id);
    try { localStorage.setItem(ST_KEY, id); } catch (e) {}
    try { window.location.hash = "#/station/" + id; } catch (e) {}
  };
  const st = stStation(stId);

  // ── หน้าเลือกสถานี (ครั้งแรกของจอนั้น) ──
  if (!st) {
    return (
      <>
        <PageHead title="จอสถานีงาน · Station Display" sub="เลือกว่าจอเครื่องนี้คือสถานีอะไร — จอจะจำไว้ เปิดมาก็เข้าสถานีเดิมทันที (เปลี่ยนได้ตลอด)"/>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(280px, 1fr))", gap: 14 }}>
          {ST_LIST.map(s => (
            <button key={s.id} onClick={() => pick(s.id)}
              style={{ border: `2px solid ${s.color}`, borderRadius: 16, padding: "26px 20px", background: "var(--surface)", cursor: "pointer", textAlign: "left", fontFamily: "inherit" }}>
              <div style={{ fontSize: 40 }}>{s.emoji}</div>
              <div style={{ fontSize: 18, fontWeight: 800, color: s.color, marginTop: 8 }}>{s.label}</div>
              <div style={{ fontSize: 13, color: "var(--ink-3)", marginTop: 4 }}>{s.desc}</div>
            </button>
          ))}
        </div>
      </>
    );
  }

  const today = stToday();
  let body = null;
  if (st.id === "machine") {
    const machines = stLS("sss-machines", []) || [];
    body = <STCutBoard machines={machines} refresh={refresh}/>;
  } else {
    body = <STTechBoard st={st} refresh={refresh}/>;
  }

  const now = new Date();
  return (
    <>
      <div style={{ borderRadius: 14, padding: "14px 18px", marginBottom: 14, color: "#fff", display: "flex", alignItems: "center", gap: 14,
        background: `linear-gradient(120deg, ${st.color}, ${st.color}cc)` }}>
        <span style={{ fontSize: 34 }}>{st.emoji}</span>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 19, fontWeight: 800, textShadow: "0 1px 3px rgba(0,0,0,0.3)" }}>สถานี: {st.label}</div>
          <div style={{ fontSize: 12.5, opacity: 0.9 }}>อัพเดทสดทุก ~5 วิ · กดปุ่มบนงานได้เลย ทุกเครื่องเห็นตาม</div>
        </div>
        <div style={{ textAlign: "right", flexShrink: 0 }}>
          <div style={{ fontSize: 22, fontWeight: 800, fontVariantNumeric: "tabular-nums" }}>{String(now.getHours()).padStart(2, "0")}:{String(now.getMinutes()).padStart(2, "0")}</div>
          <button onClick={() => { try { localStorage.removeItem(ST_KEY); } catch (e) {} setStId(""); window.location.hash = "#/station"; }}
            style={{ marginTop: 3, border: "1px solid rgba(255,255,255,0.5)", background: "rgba(255,255,255,0.15)", color: "#fff", borderRadius: 8, padding: "3px 12px", fontSize: 12, cursor: "pointer", fontFamily: "inherit" }}>⚙ เปลี่ยนสถานี</button>
        </div>
      </div>
      {body}
    </>
  );
}

window.StationPage = StationPage;
