/* global React, I, UI, SSSData */
// ═══ คิวงานเครื่องจักร — บอร์ดรายสัปดาห์ ลากการ์ดจัดคิว + พิมพ์แจ้งคนคุมงาน ═══
// แถว = เครื่องจักร (ผู้ใช้เพิ่มเอง ใส่รูปได้) · คอลัมน์ = วันจันทร์-อาทิตย์
// ลากการ์ดงานจากถาด "รอจัดคิว" ลงช่องวัน/เครื่อง หรือย้ายระหว่างช่องได้
const { useState: useStateMQ, useEffect: useEffectMQ } = React;

const MQ_MACHINES = "sss-machines";
const MQ_QUEUE = "sss-machine-queue";
const MQ_PHOTOS = "sss-machine-photos";

function mqGet(key, def) {
  const v = window.lsSyncGet ? window.lsSyncGet(key) : null;
  if (v != null) return v;
  try { return JSON.parse(localStorage.getItem(key) || "null") || def; } catch { return def; }
}
function mqSet(key, val) {
  if (window.lsSyncSet) window.lsSyncSet(key, val);
  else { try { localStorage.setItem(key, JSON.stringify(val)); } catch {} }
}

// รายการโปรเจกต์จริงทั้งหมด — รวมที่ผู้ใช้สร้าง (sss-projects-user ผ่าน ProjX) + ของระบบ (D.Projects)
// พร้อม % ความคืบหน้าล่าสุดจาก project-extras (เหมือนหน้าโปรเจกต์)
function mqProjects() {
  const D = window.SSSData;
  const 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].map(p => {
    const x = (PX && PX.pxGet) ? PX.pxGet(p.code) : {};
    return { ...p, progress: x.progress !== undefined ? x.progress : p.progress, status: x.status || p.status };
  });
}

const MQ_DAYS = ["จันทร์", "อังคาร", "พุธ", "พฤหัส", "ศุกร์", "เสาร์", "อาทิตย์"];
const MQ_MONTHS = ["ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.", "ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค."];
const MQ_STATUS = {
  "รอคิว": { color: "#78716c", bg: "#f5f5f4" },
  "กำลังทำ": { color: "#1d4ed8", bg: "#dbeafe" },
  "เสร็จแล้ว": { color: "#15803d", bg: "#dcfce7" },
  "เลื่อน": { color: "#b45309", bg: "#fef3c7" },
};

function mqISO(d) { const x = new Date(d); x.setHours(12, 0, 0, 0); return x.toISOString().slice(0, 10); }
function mqMonday(d) {
  const x = new Date(d); x.setHours(12, 0, 0, 0);
  const dow = (x.getDay() + 6) % 7;   // จันทร์ = 0
  x.setDate(x.getDate() - dow);
  return x;
}
function mqThai(iso) { const [y, m, d] = iso.split("-").map(Number); return `${d} ${MQ_MONTHS[m - 1]}`; }
function mqThaiFull(iso) { const [y, m, d] = iso.split("-").map(Number); return `${d} ${MQ_MONTHS[m - 1]} ${y + 543}`; }
function mqDayName(iso) { return MQ_DAYS[(new Date(iso + "T12:00:00").getDay() + 6) % 7]; }

// เวลา "HH:MM" ⇄ นาที
function mqMin(t) { const m = /^(\d{1,2}):(\d{2})$/.exec(String(t || "").trim()); return m ? (+m[1]) * 60 + (+m[2]) : null; }
function mqHM(min) { return `${String(Math.floor(min / 60)).padStart(2, "0")}:${String(min % 60).padStart(2, "0")}`; }
function mqDurOf(j) { const s = mqMin(j.start), e = mqMin(j.end); return (s != null && e != null && e > s) ? e - s : 60; }
function mqTimeLabel(j) { return (mqMin(j.start) != null) ? `${j.start}${mqMin(j.end) != null ? "–" + j.end : ""}` : ""; }

// ── พิมพ์คิวสัปดาห์ (แจ้งคนคุมงาน) ──
function mqPrint(machines, photos, jobs, days) {
  const C = window.SSSData.Company;
  const jobsOf = (mid, day) => jobs.filter(j => j.machineId === mid && j.date === day);
  const stChip = (s) => { const c = MQ_STATUS[s] || MQ_STATUS["รอคิว"]; return `<span style="font-size:9px;font-weight:700;color:${c.color};background:${c.bg};border-radius:99px;padding:1px 7px;white-space:nowrap">${s}</span>`; };
  const sections = machines.map(m => `
    <div style="page-break-inside:avoid;break-inside:avoid;margin-bottom:14px">
      <div style="display:flex;align-items:center;gap:10px;background:#0c0a09;color:white;border-radius:8px 8px 0 0;padding:7px 12px">
        ${photos[m.id] ? `<img src="${photos[m.id]}" style="width:30px;height:30px;border-radius:6px;object-fit:cover"/>` : ""}
        <b style="font-size:13px">${m.name}</b>
        ${m.code ? `<span style="font-family:monospace;font-size:10.5px;opacity:0.75">${m.code}</span>` : ""}
      </div>
      <table style="width:100%;border-collapse:collapse;font-size:11px">
        ${days.map((day, i) => {
          const list = jobsOf(m.id, day);
          return `<tr>
            <td style="border:1px solid #d6d3d1;padding:5px 9px;width:92px;background:#f7f6f4;vertical-align:top">
              <b>${MQ_DAYS[i]}</b><div style="color:#78716c;font-size:10px">${mqThai(day)}</div>
            </td>
            <td style="border:1px solid #d6d3d1;padding:5px 9px;vertical-align:top">
              ${list.length === 0 ? `<span style="color:#d6d3d1">—</span>` : list.slice().sort((a, b) => ((mqMin(a.start) ?? 9999) - (mqMin(b.start) ?? 9999))).map(j => `
                <div style="display:flex;gap:7px;align-items:baseline;padding:2px 0">
                  ${mqTimeLabel(j) ? `<span style="font-family:monospace;font-size:10px;font-weight:700;color:#1d4ed8;white-space:nowrap">${mqTimeLabel(j)}</span>` : ""}
                  <b style="font-size:11.5px">${(j.title || "").replace(/</g, "&lt;")}</b>
                  ${j.project ? `<span style="font-family:monospace;font-size:9.5px;color:#57534e">${j.project}</span>` : ""}
                  ${j.assignee ? `<span style="font-size:10px;color:#57534e">👤 ${j.assignee}</span>` : ""}
                  ${stChip(j.status || "รอคิว")}
                  ${j.detail ? `<span style="font-size:10px;color:#78716c">· ${(j.detail || "").replace(/</g, "&lt;")}</span>` : ""}
                </div>`).join("")}
            </td>
          </tr>`;
        }).join("")}
      </table>
    </div>`).join("");

  const html = `
    <div style="background:white;color:#0c0a09;padding:10mm 12mm;box-sizing:border-box">
      <div style="display:flex;justify-content:space-between;align-items:flex-start;border-bottom:2.5px solid #0c0a09;padding-bottom:9px;margin-bottom:12px">
        <div style="display:flex;gap:10px;align-items:center">
          <div style="width:40px;height:40px;background:#0c0a09;color:white;display:grid;place-items:center;font-weight:700;font-size:13px;border-radius:6px">SSS</div>
          <div>
            <div style="font-weight:700;font-size:14px">คิวงานเครื่องจักร ประจำสัปดาห์</div>
            <div style="font-size:11px;color:#57534e">${mqThaiFull(days[0])} — ${mqThaiFull(days[6])} · ${C.name}</div>
          </div>
        </div>
        <div style="font-size:10px;color:#78716c;text-align:right">พิมพ์ ${new Date().toLocaleString("th-TH", { day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" })}<br/>ออกโดยระบบ SSS</div>
      </div>
      ${sections || '<div style="color:#78716c">ยังไม่มีเครื่องจักร</div>'}
      <div style="margin-top:10px;font-size:10px;color:#78716c"><b>หมายเหตุ:</b> พบปัญหาเครื่อง/งานไม่ทันคิว แจ้งหัวหน้างานทันที · อัปเดตสถานะในระบบทุกครั้งที่จบงาน</div>
    </div>`;

  document.getElementById("__print_modal")?.remove();
  document.body.classList.remove("printing-modal");
  const modal = document.createElement("div");
  modal.id = "__print_modal"; modal.className = "print-modal";
  modal.innerHTML = `
    <div class="print-modal-bar no-print">
      <div style="font-weight:600;font-size:14px;flex:1">คิวเครื่องจักร ${mqThai(days[0])} — ${mqThai(days[6])}</div>
      <button id="__print_close" class="pm-btn pm-btn-ghost">ปิด (Esc)</button>
      <button id="__print_btn" class="pm-btn pm-btn-primary">🖨 พิมพ์ / บันทึก PDF</button>
    </div>
    <div class="print-modal-paper">${html}</div>`;
  document.body.appendChild(modal);
  document.body.classList.add("printing-modal");
  const cleanup = () => { modal.remove(); document.body.classList.remove("printing-modal"); document.removeEventListener("keydown", onKey); };
  const onKey = (e) => { if (e.key === "Escape") cleanup(); };
  document.addEventListener("keydown", onKey);
  modal.addEventListener("click", e => { if (e.target === modal) cleanup(); });
  modal.querySelector("#__print_btn").addEventListener("click", () => window.print());
  modal.querySelector("#__print_close").addEventListener("click", cleanup);
}

// ── การ์ดงาน (ลากได้) ──
function MQCard({ job, onOpen }) {
  const st = MQ_STATUS[job.status] || MQ_STATUS["รอคิว"];
  return (
    <div draggable onDragStart={(e) => { e.dataTransfer.setData("text/plain", "mqjob:" + job.id); e.dataTransfer.effectAllowed = "move"; }}
      onClick={() => onOpen(job)}
      style={{background: "var(--surface)", border: `1px solid var(--line-strong)`, borderLeft: `4px solid ${st.color}`, borderRadius: 7, padding: "6px 8px", cursor: "grab", fontSize: 11.5, boxShadow: "0 1px 2px rgba(0,0,0,0.06)"}}>
      <div style={{fontWeight: 700, lineHeight: 1.3}}>{job.title}</div>
      <div style={{display: "flex", gap: 5, flexWrap: "wrap", marginTop: 3, alignItems: "center"}}>
        {mqTimeLabel(job) && <span style={{fontSize: 9.5, fontWeight: 700, color: "var(--info)"}}>🕐 {mqTimeLabel(job)}</span>}
        {job.project && <span className="mono" style={{fontSize: 9.5, color: "var(--ink-3)"}}>{job.project}</span>}
        {job.assignee && <span style={{fontSize: 10, color: "var(--ink-3)"}}>👤 {job.assignee}</span>}
        <span style={{fontSize: 9, fontWeight: 700, color: st.color, background: st.bg, borderRadius: 99, padding: "1px 6px"}}>{job.status || "รอคิว"}</span>
      </div>
    </div>
  );
}

function MachineQueuePage() {
  const D = window.SSSData;
  const { Btn, Badge, Card, PageHead, Drawer } = window.UI;
  const [machines, setMachines] = useStateMQ(() => mqGet(MQ_MACHINES, []));
  const [photos, setPhotos] = useStateMQ(() => mqGet(MQ_PHOTOS, {}) || {});
  const [jobs, setJobs] = useStateMQ(() => mqGet(MQ_QUEUE, []));
  const [weekStart, setWeekStart] = useStateMQ(() => mqISO(mqMonday(new Date())));
  const [showMachines, setShowMachines] = useStateMQ(false);
  const [editJob, setEditJob] = useStateMQ(null);       // null | {} (ใหม่) | job
  const [dragOver, setDragOver] = useStateMQ("");       // "mid|day" ช่องที่ลากอยู่เหนือ
  const [view, setView] = useStateMQ("week");           // "week" = ทั้งสัปดาห์ | "day" = ไทม์ไลน์รายชั่วโมง
  const [selDay, setSelDay] = useStateMQ(() => mqISO(new Date()));
  const [showProjTray, setShowProjTray] = useStateMQ(true);

  // รับข้อมูลจากเครื่องอื่นแบบสด
  useEffectMQ(() => {
    const h = () => { setMachines(mqGet(MQ_MACHINES, [])); setPhotos(mqGet(MQ_PHOTOS, {}) || {}); setJobs(mqGet(MQ_QUEUE, [])); };
    const evts = ["sss-localstore-polled", "sss-db-loaded", "sss-data-synced"];
    evts.forEach(e => window.addEventListener(e, h));
    h();
    return () => evts.forEach(e => window.removeEventListener(e, h));
  }, []);

  const days = Array.from({ length: 7 }, (_, i) => { const d = new Date(weekStart + "T12:00:00"); d.setDate(d.getDate() + i); return mqISO(d); });
  const todayISO = mqISO(new Date());
  const shiftWeek = (n) => { const d = new Date(weekStart + "T12:00:00"); d.setDate(d.getDate() + n * 7); setWeekStart(mqISO(mqMonday(d))); };

  // เขียนกับข้อมูลสดเสมอ (กันทับงานที่เครื่องอื่นเพิ่งเพิ่ม)
  const saveJobs = (mut) => { const next = mut(mqGet(MQ_QUEUE, [])); setJobs(next); mqSet(MQ_QUEUE, next); };
  const upsertJob = (job) => saveJobs(cur => cur.some(j => j.id === job.id) ? cur.map(j => j.id === job.id ? job : j) : [...cur, job]);
  const removeJob = (id) => saveJobs(cur => cur.filter(j => j.id !== id));
  const newJobId = () => "J-" + Date.now().toString(36) + Math.random().toString(36).slice(2, 5);

  // รับได้ทั้ง "การ์ดงาน" และ "การ์ดโปรเจกต์" — startMin (ถ้ามี) = เวลาที่วางในไทม์ไลน์รายวัน
  const onDropCell = (e, machineId, date, startMin) => {
    e.preventDefault(); e.stopPropagation(); setDragOver("");
    const raw = e.dataTransfer.getData("text/plain") || "";
    const jid = raw.indexOf("mqjob:") === 0 ? raw.slice(6) : e.dataTransfer.getData("text/mq-job");
    const pcode = raw.indexOf("mqproj:") === 0 ? raw.slice(7) : e.dataTransfer.getData("text/mq-proj");
    if (jid) {
      saveJobs(cur => cur.map(j => {
        if (j.id !== jid) return j;
        const next = { ...j, machineId, date };
        if (startMin != null) { const dur = mqDurOf(j); next.start = mqHM(startMin); next.end = mqHM(Math.min(24 * 60 - 1, startMin + dur)); }
        return next;
      }));
    } else if (pcode) {
      const p = mqProjects().find(x => x.code === pcode);
      upsertJob({
        id: newJobId(), title: p ? p.name : pcode, project: pcode, machineId, date, status: "รอคิว",
        assignee: "", detail: "",
        start: startMin != null ? mqHM(startMin) : "", end: startMin != null ? mqHM(Math.min(24 * 60 - 1, startMin + 60)) : "",
      });
      window.toast && window.toast("เพิ่มงานจากโปรเจกต์ " + pcode + " แล้ว — คลิกการ์ดเพื่อใส่รายละเอียด");
    }
  };
  const allowDrop = (e, key) => { e.preventDefault(); e.dataTransfer.dropEffect = "move"; if (dragOver !== key) setDragOver(key); };

  const tray = jobs.filter(j => !j.date || !j.machineId);
  const cellJobs = (mid, day) => jobs.filter(j => j.machineId === mid && j.date === day);
  const weekJobs = jobs.filter(j => j.machineId && days.includes(j.date));

  return (
    <>
      <PageHead title="คิวงานเครื่องจักร" sub={`${machines.length} เครื่อง · สัปดาห์นี้ ${weekJobs.length} งาน · รอจัดคิว ${tray.length}`}
        right={<div style={{display: "flex", gap: 6}}>
          <Btn size="sm" icon={I.cog} onClick={() => setShowMachines(true)}>จัดการเครื่องจักร</Btn>
          <Btn size="sm" icon={I.doc} kind="ghost" onClick={() => view === "day" ? mqPrintDay(machines, photos, jobs, selDay) : mqPrint(machines, photos, jobs, days)}>
            🖨 พิมพ์{view === "day" ? "คิววันนี้" : "แจ้งคนคุมงาน"}</Btn>
          <Btn size="sm" kind="primary" icon={I.check} onClick={() => setEditJob({})}>+ เพิ่มงาน</Btn>
        </div>}/>

      {/* สลับมุมมอง + เลือกช่วง */}
      <div style={{display: "flex", alignItems: "center", gap: 8, marginBottom: 12, flexWrap: "wrap"}}>
        <div style={{display: "flex", border: "1px solid var(--line-strong)", borderRadius: 8, overflow: "hidden"}}>
          {[["week", "📅 สัปดาห์"], ["day", "🕐 รายวัน (ชั่วโมง)"]].map(([v, label]) => (
            <button key={v} onClick={() => setView(v)}
              style={{border: 0, padding: "6px 14px", fontSize: 12.5, fontWeight: 600, cursor: "pointer", background: view === v ? "var(--ink-1)" : "var(--surface)", color: view === v ? "var(--surface)" : "var(--ink-2)"}}>{label}</button>
          ))}
        </div>
        {view === "week" ? (
          <>
            <Btn size="sm" kind="ghost" onClick={() => shiftWeek(-1)}>← สัปดาห์ก่อน</Btn>
            <div style={{fontWeight: 700, fontSize: 14}}>{mqThaiFull(days[0])} — {mqThaiFull(days[6])}</div>
            <Btn size="sm" kind="ghost" onClick={() => shiftWeek(1)}>สัปดาห์ถัดไป →</Btn>
            <Btn size="sm" kind="ghost" onClick={() => setWeekStart(mqISO(mqMonday(new Date())))}>วันนี้</Btn>
          </>
        ) : (
          <>
            <Btn size="sm" kind="ghost" onClick={() => { const d = new Date(selDay + "T12:00:00"); d.setDate(d.getDate() - 1); setSelDay(mqISO(d)); }}>← วันก่อน</Btn>
            <div style={{fontWeight: 700, fontSize: 14}}>{mqDayName(selDay)} {mqThaiFull(selDay)}{selDay === todayISO ? " · วันนี้" : ""}</div>
            <Btn size="sm" kind="ghost" onClick={() => { const d = new Date(selDay + "T12:00:00"); d.setDate(d.getDate() + 1); setSelDay(mqISO(d)); }}>วันถัดไป →</Btn>
            <Btn size="sm" kind="ghost" onClick={() => setSelDay(mqISO(new Date()))}>วันนี้</Btn>
            <input type="date" className="input" style={{height: 30, width: 150, fontSize: 12}} value={selDay} onChange={e => e.target.value && setSelDay(e.target.value)}/>
          </>
        )}
      </div>

      {/* ถาดโปรเจกต์ — ลากลงบอร์ดเพื่อสร้างงานผูกโปรเจกต์ทันที */}
      <Card title="โปรเจกต์ · ลากลงบอร์ดเพื่อสร้างงาน" sub="การ์ดโปรเจกต์ → วางในช่องวัน/เครื่อง (หรือวางบนไทม์ไลน์ = ระบุเวลาทันที)" className="mb-lg"
        right={<Btn size="sm" kind="ghost" onClick={() => setShowProjTray(s => !s)}>{showProjTray ? "ซ่อน" : "แสดง"}</Btn>}>
        {showProjTray && (
          <div style={{display: "flex", gap: 8, flexWrap: "wrap"}}>
            {mqProjects().filter(p => (Number(p.progress) || 0) < 100).map(p => (
              <div key={p.code} draggable
                onDragStart={(e) => { e.dataTransfer.setData("text/plain", "mqproj:" + p.code); e.dataTransfer.effectAllowed = "copyMove"; }}
                title="ลากลงบอร์ดเพื่อสร้างงานของโปรเจกต์นี้"
                style={{cursor: "grab", border: "1px solid var(--line-strong)", borderLeft: "4px solid var(--info)", borderRadius: 7, padding: "5px 10px", background: "var(--surface)", fontSize: 11.5, maxWidth: 230}}>
                <span className="mono" style={{fontSize: 9.5, color: "var(--ink-3)"}}>{p.code}</span>
                <div style={{fontWeight: 700, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap"}}>{p.name}</div>
              </div>
            ))}
            {mqProjects().filter(p => (Number(p.progress) || 0) < 100).length === 0 &&
              <span style={{fontSize: 12, color: "var(--ink-4)"}}>ไม่มีโปรเจกต์ที่ยังไม่จบ</span>}
          </div>
        )}
      </Card>

      {/* ถาดงานรอจัดคิว — ลากลงบอร์ด */}
      <Card title="งานรอจัดคิว" sub="ลากการ์ดลงช่องวัน/เครื่องด้านล่าง หรือคลิกเพื่อแก้ไข" className="mb-lg">
        <div onDragOver={(e) => allowDrop(e, "tray")} onDrop={(e) => onDropCell(e, "", "")} onDragLeave={() => setDragOver("")}
          style={{display: "flex", gap: 8, flexWrap: "wrap", minHeight: 46, padding: 8, borderRadius: 8, border: `1.5px dashed ${dragOver === "tray" ? "var(--info)" : "var(--line-strong)"}`, background: dragOver === "tray" ? "var(--surface-2)" : "transparent"}}>
          {tray.length === 0 && <span style={{fontSize: 12, color: "var(--ink-4)", alignSelf: "center"}}>ไม่มีงานค้าง — กด "+ เพิ่มงาน" ลากโปรเจกต์มาวาง หรือลากงานจากบอร์ดกลับมาพักที่นี่</span>}
          {tray.map(j => <div key={j.id} style={{width: 210}}><MQCard job={j} onOpen={setEditJob}/></div>)}
        </div>
      </Card>

      {/* บอร์ด: สัปดาห์ (แถวเครื่อง × วัน) หรือ ไทม์ไลน์รายชั่วโมงของวันเดียว */}
      {machines.length === 0 ? (
        <Card>
          <div style={{padding: 24, textAlign: "center", color: "var(--ink-3)", fontSize: 13}}>
            ยังไม่มีเครื่องจักร — กด <b>"จัดการเครื่องจักร"</b> เพื่อเพิ่มเครื่อง (ใส่รูปได้)
          </div>
        </Card>
      ) : view === "day" ? (
        <MQDayTimeline machines={machines} photos={photos} jobs={jobs} day={selDay}
          onDrop={onDropCell} onOpen={setEditJob}
          onQuickAdd={(mid, startMin) => setEditJob({ machineId: mid, date: selDay, start: mqHM(startMin), end: mqHM(startMin + 60) })}/>
      ) : (
        <div style={{overflowX: "auto", border: "1px solid var(--line)", borderRadius: 10, background: "var(--surface)"}}>
          <table style={{borderCollapse: "collapse", width: "100%", minWidth: 1000}}>
            <thead>
              <tr>
                <th style={{position: "sticky", left: 0, background: "var(--surface-2)", zIndex: 2, padding: "8px 10px", borderBottom: "2px solid var(--line-strong)", borderRight: "1px solid var(--line)", textAlign: "left", fontSize: 11.5, minWidth: 150}}>เครื่องจักร</th>
                {days.map((day, i) => (
                  <th key={day} onClick={() => { setSelDay(day); setView("day"); }} title="คลิกเพื่อดูไทม์ไลน์รายชั่วโมงของวันนี้"
                    style={{padding: "8px 6px", borderBottom: "2px solid var(--line-strong)", borderRight: "1px solid var(--line)", fontSize: 11.5, minWidth: 128, background: day === todayISO ? "var(--surface-2)" : "transparent", cursor: "pointer"}}>
                    <div style={{fontWeight: 700, color: i >= 5 ? "var(--danger)" : "var(--ink-1)"}}>{MQ_DAYS[i]} <span style={{fontSize: 9, color: "var(--ink-4)"}}>🕐</span></div>
                    <div style={{fontSize: 10, color: day === todayISO ? "var(--info)" : "var(--ink-4)", fontWeight: day === todayISO ? 700 : 400}}>{mqThai(day)}{day === todayISO ? " · วันนี้" : ""}</div>
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {machines.map(m => (
                <tr key={m.id}>
                  <td style={{position: "sticky", left: 0, background: "var(--surface)", zIndex: 1, padding: "8px 10px", borderBottom: "1px solid var(--line)", borderRight: "1px solid var(--line)", verticalAlign: "top"}}>
                    <div style={{display: "flex", gap: 8, alignItems: "center"}}>
                      {photos[m.id]
                        ? <img src={photos[m.id]} alt={m.name} style={{width: 38, height: 38, borderRadius: 7, objectFit: "cover", border: "1px solid var(--line)"}}/>
                        : <div style={{width: 38, height: 38, borderRadius: 7, background: "var(--surface-2)", display: "grid", placeItems: "center", fontSize: 16}}>⚙️</div>}
                      <div>
                        <div style={{fontWeight: 700, fontSize: 12.5}}>{m.name}</div>
                        {m.code && <div className="mono" style={{fontSize: 10, color: "var(--ink-4)"}}>{m.code}</div>}
                      </div>
                    </div>
                  </td>
                  {days.map(day => {
                    const key = m.id + "|" + day;
                    const list = cellJobs(m.id, day);
                    return (
                      <td key={key} onDragOver={(e) => allowDrop(e, key)} onDrop={(e) => onDropCell(e, m.id, day)} onDragLeave={() => setDragOver("")}
                        style={{padding: 5, borderBottom: "1px solid var(--line)", borderRight: "1px solid var(--line)", verticalAlign: "top", background: dragOver === key ? "var(--surface-2)" : (day === todayISO ? "color-mix(in srgb, var(--info) 4%, transparent)" : "transparent"), minHeight: 60}}>
                        <div style={{display: "flex", flexDirection: "column", gap: 5, minHeight: 52}}>
                          {list.map(j => <MQCard key={j.id} job={j} onOpen={setEditJob}/>)}
                          <button onClick={() => setEditJob({ machineId: m.id, date: day })}
                            style={{border: "1px dashed var(--line-strong)", background: "transparent", color: "var(--ink-4)", borderRadius: 6, fontSize: 10.5, padding: "2px 0", cursor: "pointer"}}>+ งาน</button>
                        </div>
                      </td>
                    );
                  })}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {showMachines && <MachineManageDrawer machines={machines} photos={photos}
        onChange={(next, nextPhotos) => {
          setMachines(next); mqSet(MQ_MACHINES, next);
          if (nextPhotos) { setPhotos(nextPhotos); mqSet(MQ_PHOTOS, nextPhotos); }
        }}
        onClose={() => setShowMachines(false)}/>}

      {editJob !== null && <JobEditDrawer job={editJob} machines={machines}
        onSave={(j) => { upsertJob(j); setEditJob(null); }}
        onDelete={(id) => { removeJob(id); setEditJob(null); }}
        onClose={() => setEditJob(null)}/>}
    </>
  );
}

// ── ไทม์ไลน์รายชั่วโมงของวันเดียว — เห็นละเอียดว่าเครื่องไหนทำอะไรกี่โมงถึงกี่โมง ──
const MQ_HOUR_W = 96;   // px ต่อชั่วโมง
function MQDayTimeline({ machines, photos, jobs, day, onDrop, onOpen, onQuickAdd }) {
  const dayJobs = jobs.filter(j => j.date === day);
  // ช่วงชั่วโมงที่แสดง: 7:00–19:00 ขยายอัตโนมัติถ้ามีงานนอกช่วง
  let h0 = 7, h1 = 19;
  dayJobs.forEach(j => {
    const s = mqMin(j.start), e = mqMin(j.end);
    if (s != null) h0 = Math.min(h0, Math.floor(s / 60));
    if (e != null) h1 = Math.max(h1, Math.ceil(e / 60));
    else if (s != null) h1 = Math.max(h1, Math.ceil(s / 60) + 1);
  });
  const hours = Array.from({ length: h1 - h0 }, (_, i) => h0 + i);
  const width = hours.length * MQ_HOUR_W;
  const xOf = (min) => ((min - h0 * 60) / 60) * MQ_HOUR_W;

  // จัดเลน — งานเวลาทับกันวางซ้อนเป็นชั้น ไม่บังกัน
  const lanesOf = (list) => {
    const sorted = [...list].sort((a, b) => (mqMin(a.start) ?? 0) - (mqMin(b.start) ?? 0));
    const laneEnd = [];
    return sorted.map(j => {
      const s = mqMin(j.start) ?? h0 * 60, e = s + mqDurOf(j);
      let lane = laneEnd.findIndex(le => le <= s);
      if (lane < 0) { lane = laneEnd.length; laneEnd.push(e); } else laneEnd[lane] = e;
      return { job: j, lane, s, e };
    });
  };

  const nowMin = (() => { const n = new Date(); return mqISO(n) === day ? n.getHours() * 60 + n.getMinutes() : null; })();
  const snap = (e, rowEl) => {
    const rect = rowEl.getBoundingClientRect();
    const x = Math.max(0, e.clientX - rect.left + rowEl.scrollLeft);
    return Math.max(0, h0 * 60 + Math.round((x / MQ_HOUR_W) * 60 / 15) * 15);   // snap 15 นาที
  };

  return (
    <div style={{border: "1px solid var(--line)", borderRadius: 10, background: "var(--surface)", overflowX: "auto"}}>
      <div style={{minWidth: 150 + width}}>
        {/* หัวชั่วโมง */}
        <div style={{display: "flex", borderBottom: "2px solid var(--line-strong)", position: "sticky", top: 0, background: "var(--surface-2)", zIndex: 2}}>
          <div style={{width: 150, flexShrink: 0, padding: "7px 10px", fontSize: 11.5, fontWeight: 700, borderRight: "1px solid var(--line)"}}>เครื่องจักร</div>
          <div style={{position: "relative", width, height: 30}}>
            {hours.map(h => (
              <div key={h} style={{position: "absolute", left: (h - h0) * MQ_HOUR_W, top: 0, bottom: 0, borderLeft: "1px solid var(--line)", paddingLeft: 5, fontSize: 10.5, color: "var(--ink-3)", display: "flex", alignItems: "center", fontWeight: 600}}>
                {String(h).padStart(2, "0")}:00
              </div>
            ))}
            {nowMin != null && nowMin >= h0 * 60 && nowMin <= h1 * 60 &&
              <div style={{position: "absolute", left: xOf(nowMin), top: 0, bottom: 0, width: 2, background: "var(--danger)", zIndex: 3}}/>}
          </div>
        </div>

        {machines.map(m => {
          const list = dayJobs.filter(j => j.machineId === m.id);
          const timed = lanesOf(list.filter(j => mqMin(j.start) != null));
          const untimed = list.filter(j => mqMin(j.start) == null);
          const laneCount = Math.max(1, timed.reduce((mx, t) => Math.max(mx, t.lane + 1), 0));
          const rowH = laneCount * 42 + (untimed.length ? 34 : 0) + 10;
          return (
            <div key={m.id} style={{display: "flex", borderBottom: "1px solid var(--line)"}}>
              <div style={{width: 150, flexShrink: 0, padding: "8px 10px", borderRight: "1px solid var(--line)", display: "flex", gap: 8, alignItems: "center"}}>
                {photos[m.id]
                  ? <img src={photos[m.id]} alt={m.name} style={{width: 34, height: 34, borderRadius: 6, objectFit: "cover", border: "1px solid var(--line)"}}/>
                  : <div style={{width: 34, height: 34, borderRadius: 6, background: "var(--surface-2)", display: "grid", placeItems: "center", fontSize: 14}}>⚙️</div>}
                <div style={{minWidth: 0}}>
                  <div style={{fontWeight: 700, fontSize: 12, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap"}}>{m.name}</div>
                  {m.code && <div className="mono" style={{fontSize: 9.5, color: "var(--ink-4)"}}>{m.code}</div>}
                </div>
              </div>
              <div style={{position: "relative", width, minHeight: rowH, cursor: "copy"}}
                onDragOver={(e) => { e.preventDefault(); e.dataTransfer.dropEffect = "move"; }}
                onDrop={(e) => onDrop(e, m.id, day, snap(e, e.currentTarget))}
                onDoubleClick={(e) => onQuickAdd(m.id, snap(e, e.currentTarget))}
                title="ลากงาน/โปรเจกต์มาวางตามเวลา · ดับเบิลคลิกเพื่อเพิ่มงานที่เวลานั้น">
                {hours.map(h => <div key={h} style={{position: "absolute", left: (h - h0) * MQ_HOUR_W, top: 0, bottom: 0, borderLeft: "1px solid var(--line)", opacity: 0.55}}/>)}
                {nowMin != null && nowMin >= h0 * 60 && nowMin <= h1 * 60 &&
                  <div style={{position: "absolute", left: xOf(nowMin), top: 0, bottom: 0, width: 2, background: "var(--danger)", opacity: 0.6}}/>}
                {timed.map(({ job, lane, s }) => {
                  const st = MQ_STATUS[job.status] || MQ_STATUS["รอคิว"];
                  const w = Math.max(46, (mqDurOf(job) / 60) * MQ_HOUR_W - 4);
                  return (
                    <div key={job.id} draggable
                      onDragStart={(e) => { e.dataTransfer.setData("text/plain", "mqjob:" + job.id); e.dataTransfer.effectAllowed = "move"; }}
                      onClick={(e) => { e.stopPropagation(); onOpen(job); }}
                      title={`${job.title} · ${mqTimeLabel(job)}`}
                      style={{position: "absolute", left: xOf(s) + 2, top: 5 + lane * 42, width: w, height: 36, background: st.bg, border: `1.5px solid ${st.color}`, borderRadius: 7, padding: "3px 7px", fontSize: 10.5, cursor: "grab", overflow: "hidden", zIndex: 1}}>
                      <div style={{fontWeight: 800, color: st.color, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis"}}>{job.title}</div>
                      <div style={{fontSize: 9.5, color: "var(--ink-3)", whiteSpace: "nowrap"}}>{mqTimeLabel(job)}{job.assignee ? ` · ${job.assignee}` : ""}</div>
                    </div>
                  );
                })}
                {untimed.length > 0 && (
                  <div style={{position: "absolute", left: 4, right: 4, top: laneCount * 42 + 8, display: "flex", gap: 6, alignItems: "center", flexWrap: "wrap"}}>
                    <span style={{fontSize: 9.5, color: "var(--ink-4)", fontWeight: 700}}>ทั้งวัน:</span>
                    {untimed.map(j => {
                      const st = MQ_STATUS[j.status] || MQ_STATUS["รอคิว"];
                      return <span key={j.id} draggable
                        onDragStart={(e) => { e.dataTransfer.setData("text/plain", "mqjob:" + j.id); e.dataTransfer.effectAllowed = "move"; }}
                        onClick={(e) => { e.stopPropagation(); onOpen(j); }}
                        style={{fontSize: 10, fontWeight: 700, color: st.color, background: st.bg, border: `1px solid ${st.color}`, borderRadius: 99, padding: "2px 9px", cursor: "grab"}}>{j.title}</span>;
                    })}
                  </div>
                )}
              </div>
            </div>
          );
        })}
      </div>
      <div style={{padding: "7px 12px", fontSize: 10.5, color: "var(--ink-4)", borderTop: "1px solid var(--line)"}}>
        💡 ลากงาน/โปรเจกต์วางบนแถบเวลา = ตั้งเวลาเริ่มทันที (ขยับทีละ 15 นาที) · ดับเบิลคลิกพื้นที่ว่าง = เพิ่มงานที่เวลานั้น · เส้นแดง = เวลาปัจจุบัน
      </div>
    </div>
  );
}

// ── พิมพ์คิวรายวัน (ละเอียดรายชั่วโมง) ──
function mqPrintDay(machines, photos, jobs, day) {
  const C = window.SSSData.Company;
  const dayJobs = jobs.filter(j => j.date === day);
  const stChip = (s) => { const c = MQ_STATUS[s] || MQ_STATUS["รอคิว"]; return `<span style="font-size:9px;font-weight:700;color:${c.color};background:${c.bg};border-radius:99px;padding:1px 7px;white-space:nowrap">${s}</span>`; };
  const sections = machines.map(m => {
    const list = dayJobs.filter(j => j.machineId === m.id)
      .sort((a, b) => (mqMin(a.start) ?? 9999) - (mqMin(b.start) ?? 9999));
    return `
    <div style="page-break-inside:avoid;break-inside:avoid;margin-bottom:12px">
      <div style="display:flex;align-items:center;gap:10px;background:#0c0a09;color:white;border-radius:8px 8px 0 0;padding:7px 12px">
        ${photos[m.id] ? `<img src="${photos[m.id]}" style="width:30px;height:30px;border-radius:6px;object-fit:cover"/>` : ""}
        <b style="font-size:13px">${m.name}</b>
        ${m.code ? `<span style="font-family:monospace;font-size:10.5px;opacity:0.75">${m.code}</span>` : ""}
        <span style="margin-left:auto;font-size:10.5px">${list.length} งาน</span>
      </div>
      <table style="width:100%;border-collapse:collapse;font-size:11px">
        <tr style="background:#f7f6f4">
          <th style="border:1px solid #d6d3d1;padding:4px 8px;width:92px;text-align:left">เวลา</th>
          <th style="border:1px solid #d6d3d1;padding:4px 8px;text-align:left">งาน</th>
          <th style="border:1px solid #d6d3d1;padding:4px 8px;width:90px;text-align:left">โปรเจกต์</th>
          <th style="border:1px solid #d6d3d1;padding:4px 8px;width:110px;text-align:left">ผู้คุม/ช่าง</th>
          <th style="border:1px solid #d6d3d1;padding:4px 8px;width:70px;text-align:left">สถานะ</th>
          <th style="border:1px solid #d6d3d1;padding:4px 8px;width:70px;text-align:left">เสร็จจริง</th>
        </tr>
        ${list.length === 0 ? `<tr><td colspan="6" style="border:1px solid #d6d3d1;padding:6px 8px;color:#a8a29e">— ว่าง —</td></tr>` : list.map(j => `
          <tr>
            <td style="border:1px solid #d6d3d1;padding:4px 8px;font-family:monospace;font-weight:700">${mqTimeLabel(j) || "ทั้งวัน"}</td>
            <td style="border:1px solid #d6d3d1;padding:4px 8px"><b>${(j.title || "").replace(/</g, "&lt;")}</b>${j.detail ? `<div style="font-size:10px;color:#78716c">${(j.detail || "").replace(/</g, "&lt;")}</div>` : ""}</td>
            <td style="border:1px solid #d6d3d1;padding:4px 8px;font-family:monospace;font-size:10px">${j.project || "—"}</td>
            <td style="border:1px solid #d6d3d1;padding:4px 8px">${j.assignee || "—"}</td>
            <td style="border:1px solid #d6d3d1;padding:4px 8px">${stChip(j.status || "รอคิว")}</td>
            <td style="border:1px solid #d6d3d1;padding:4px 8px;color:#a8a29e">.......…</td>
          </tr>`).join("")}
      </table>
    </div>`;
  }).join("");

  const html = `
    <div style="background:white;color:#0c0a09;padding:10mm 12mm;box-sizing:border-box">
      <div style="display:flex;justify-content:space-between;align-items:flex-start;border-bottom:2.5px solid #0c0a09;padding-bottom:9px;margin-bottom:12px">
        <div style="display:flex;gap:10px;align-items:center">
          <div style="width:40px;height:40px;background:#0c0a09;color:white;display:grid;place-items:center;font-weight:700;font-size:13px;border-radius:6px">SSS</div>
          <div>
            <div style="font-weight:700;font-size:14px">คิวงานเครื่องจักร — ${mqDayName(day)} ${mqThaiFull(day)}</div>
            <div style="font-size:11px;color:#57534e">${C.name}</div>
          </div>
        </div>
        <div style="font-size:10px;color:#78716c;text-align:right">พิมพ์ ${new Date().toLocaleString("th-TH", { day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" })}<br/>ออกโดยระบบ SSS</div>
      </div>
      ${sections || '<div style="color:#78716c">ยังไม่มีเครื่องจักร</div>'}
      <div style="margin-top:10px;font-size:10px;color:#78716c"><b>หมายเหตุ:</b> ช่างลงเวลา "เสร็จจริง" ทุกงาน · พบปัญหาแจ้งหัวหน้างานทันที</div>
    </div>`;

  document.getElementById("__print_modal")?.remove();
  document.body.classList.remove("printing-modal");
  const modal = document.createElement("div");
  modal.id = "__print_modal"; modal.className = "print-modal";
  modal.innerHTML = `
    <div class="print-modal-bar no-print">
      <div style="font-weight:600;font-size:14px;flex:1">คิวเครื่องจักร ${mqThaiFull(day)}</div>
      <button id="__print_close" class="pm-btn pm-btn-ghost">ปิด (Esc)</button>
      <button id="__print_btn" class="pm-btn pm-btn-primary">🖨 พิมพ์ / บันทึก PDF</button>
    </div>
    <div class="print-modal-paper">${html}</div>`;
  document.body.appendChild(modal);
  document.body.classList.add("printing-modal");
  const cleanup = () => { modal.remove(); document.body.classList.remove("printing-modal"); document.removeEventListener("keydown", onKey); };
  const onKey = (e) => { if (e.key === "Escape") cleanup(); };
  document.addEventListener("keydown", onKey);
  modal.addEventListener("click", e => { if (e.target === modal) cleanup(); });
  modal.querySelector("#__print_btn").addEventListener("click", () => window.print());
  modal.querySelector("#__print_close").addEventListener("click", cleanup);
}

// ── จัดการเครื่องจักร (เพิ่ม/รูป/ลบ) ──
function MachineManageDrawer({ machines, photos, onChange, onClose }) {
  const { Btn, Drawer } = window.UI;
  const [name, setName] = useStateMQ("");
  const [code, setCode] = useStateMQ("");

  const resize = (f) => window.DeliveryStore && window.DeliveryStore.resizeImage
    ? window.DeliveryStore.resizeImage(f, 500)
    : new Promise(res => { const r = new FileReader(); r.onload = () => res(r.result); r.readAsDataURL(f); });

  const add = () => {
    if (!name.trim()) { window.toast && window.toast("ใส่ชื่อเครื่องจักรก่อน"); return; }
    const m = { id: "M-" + Date.now().toString(36), name: name.trim(), code: code.trim() };
    onChange([...(mqGet(MQ_MACHINES, [])), m]);
    setName(""); setCode("");
  };
  const remove = async (m) => {
    const ok = await (window.confirmDelete ? window.confirmDelete("เครื่องจักร " + m.name, m.code || "") : Promise.resolve(confirm("ลบ?")));
    if (!ok) return;
    onChange(mqGet(MQ_MACHINES, []).filter(x => x.id !== m.id));
    // งานของเครื่องนี้กลับไปถาดรอจัดคิว
    const q = mqGet(MQ_QUEUE, []).map(j => j.machineId === m.id ? { ...j, machineId: "", date: "" } : j);
    mqSet(MQ_QUEUE, q);
    window.dispatchEvent(new Event("sss-localstore-polled"));
  };
  const pickPhoto = async (m, e) => {
    const f = e.target.files[0]; e.target.value = "";
    if (!f) return;
    const url = await resize(f);
    if (!url) return;
    const next = { ...(mqGet(MQ_PHOTOS, {}) || {}) };
    next[m.id] = url;
    onChange(mqGet(MQ_MACHINES, []), next);
    window.toast && window.toast("ใส่รูป " + m.name + " แล้ว");
  };

  return (
    <Drawer open={true} onClose={onClose} title="จัดการเครื่องจักร">
      <div style={{display: "flex", gap: 8, marginBottom: 14}}>
        <input className="input" placeholder="ชื่อเครื่องจักร เช่น เครื่องพับ 1" value={name} onChange={e => setName(e.target.value)} style={{flex: 2}}/>
        <input className="input" placeholder="รหัส (ไม่บังคับ)" value={code} onChange={e => setCode(e.target.value)} style={{flex: 1}}/>
        <Btn kind="primary" onClick={add}>เพิ่ม</Btn>
      </div>
      {machines.length === 0 && <div style={{padding: 16, textAlign: "center", color: "var(--ink-3)", fontSize: 12.5}}>ยังไม่มีเครื่องจักร</div>}
      <div style={{display: "flex", flexDirection: "column", gap: 8}}>
        {machines.map(m => (
          <div key={m.id} style={{display: "flex", gap: 10, alignItems: "center", border: "1px solid var(--line)", borderRadius: 8, padding: "8px 10px"}}>
            {photos[m.id]
              ? <img src={photos[m.id]} alt={m.name} style={{width: 46, height: 46, borderRadius: 8, objectFit: "cover", border: "1px solid var(--line)"}}/>
              : <div style={{width: 46, height: 46, borderRadius: 8, background: "var(--surface-2)", display: "grid", placeItems: "center", fontSize: 18}}>⚙️</div>}
            <div style={{flex: 1}}>
              <div style={{fontWeight: 700, fontSize: 13}}>{m.name}</div>
              {m.code && <div className="mono" style={{fontSize: 10.5, color: "var(--ink-4)"}}>{m.code}</div>}
            </div>
            <label className="btn sm" style={{cursor: "pointer"}}>
              <input type="file" accept="image/*" style={{display: "none"}} onChange={(e) => pickPhoto(m, e)}></input>
              📷 รูป
            </label>
            <button className="icon-btn" title="ลบ" onClick={() => remove(m)}><I.trash size={13}/></button>
          </div>
        ))}
      </div>
    </Drawer>
  );
}

// ── เพิ่ม/แก้งานในคิว ──
function JobEditDrawer({ job, machines, onSave, onDelete, onClose }) {
  const D = window.SSSData;
  const { Btn, Drawer } = window.UI;
  const isNew = !job.id;
  const [f, setF] = useStateMQ({
    title: job.title || "", machineId: job.machineId || "", date: job.date || "",
    project: job.project || "", assignee: job.assignee || "", detail: job.detail || "",
    status: job.status || "รอคิว", start: job.start || "", end: job.end || "",
  });
  const set = (k, v) => setF(p => ({ ...p, [k]: v }));
  const save = () => {
    if (!f.title.trim()) { window.toast && window.toast("ใส่ชื่องานก่อน"); return; }
    onSave({ ...job, id: job.id || ("J-" + Date.now().toString(36) + Math.random().toString(36).slice(2, 5)), ...f, title: f.title.trim() });
    window.toast && window.toast(isNew ? "เพิ่มงานแล้ว" : "บันทึกแล้ว");
  };
  const del = async () => {
    const ok = await (window.confirmDelete ? window.confirmDelete("งาน " + (job.title || ""), "") : Promise.resolve(confirm("ลบ?")));
    if (ok) onDelete(job.id);
  };

  return (
    <Drawer open={true} onClose={onClose} title={isNew ? "เพิ่มงานเข้าคิว" : "แก้ไขงาน"}
      footer={<>
        {!isNew && <Btn kind="ghost" icon={I.trash} onClick={del}>ลบงาน</Btn>}
        <Btn kind="primary" onClick={save}>{isNew ? "เพิ่มงาน" : "บันทึก"}</Btn>
      </>}>
      <div style={{display: "flex", flexDirection: "column", gap: 12}}>
        <div className="field"><label>ชื่องาน *</label><input className="input" value={f.title} onChange={e => set("title", e.target.value)} placeholder="เช่น พับกล่องสแตนเลส 40 ชุด"/></div>
        <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10}}>
          <div className="field"><label>เครื่องจักร</label>
            <select className="input" value={f.machineId} onChange={e => set("machineId", e.target.value)}>
              <option value="">— รอจัดคิว —</option>
              {machines.map(m => <option key={m.id} value={m.id}>{m.name}</option>)}
            </select>
          </div>
          <div className="field"><label>วันที่ทำ</label><input type="date" className="input" value={f.date} onChange={e => set("date", e.target.value)}/></div>
        </div>
        {/* ช่วงเวลา — ไม่ระบุ = งานทั้งวัน · ระบุ = แสดงบนไทม์ไลน์รายชั่วโมง */}
        <div className="field"><label>ช่วงเวลา (ไม่ระบุ = ทั้งวัน)</label>
          <div style={{display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap"}}>
            <span style={{fontSize: 12, color: "var(--ink-3)"}}>เริ่ม</span>
            {window.UI.TimeField ? <window.UI.TimeField value={f.start} onChange={v => set("start", v)} minuteStep={15}/> : <input type="time" className="input" style={{width: 110}} value={f.start} onChange={e => set("start", e.target.value)}/>}
            <span style={{fontSize: 12, color: "var(--ink-3)"}}>ถึง</span>
            {window.UI.TimeField ? <window.UI.TimeField value={f.end} onChange={v => set("end", v)} minuteStep={15}/> : <input type="time" className="input" style={{width: 110}} value={f.end} onChange={e => set("end", e.target.value)}/>}
            {(f.start || f.end) && <Btn size="sm" kind="ghost" onClick={() => setF(p => ({ ...p, start: "", end: "" }))}>ล้างเวลา (ทั้งวัน)</Btn>}
          </div>
        </div>
        <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10}}>
          <div className="field"><label>โปรเจกต์ (ไม่บังคับ)</label>
            <select className="input" value={f.project} onChange={e => set("project", e.target.value)}>
              <option value="">—</option>
              {mqProjects().map(p => <option key={p.code} value={p.code}>{p.code} · {p.name}</option>)}
            </select>
          </div>
          <div className="field"><label>ผู้คุมงาน/ช่าง</label>
            <select className="input" value={f.assignee} onChange={e => set("assignee", e.target.value)}>
              <option value="">—</option>
              {(D.Employees || []).map(emp => <option key={emp.id} value={emp.name}>{emp.name}</option>)}
            </select>
          </div>
        </div>
        <div className="field"><label>สถานะ</label>
          <div style={{display: "flex", gap: 6, flexWrap: "wrap"}}>
            {Object.keys(MQ_STATUS).map(s => {
              const st = MQ_STATUS[s]; const on = f.status === s;
              return <button key={s} onClick={() => set("status", s)}
                style={{cursor: "pointer", fontSize: 12, fontWeight: 600, padding: "5px 12px", borderRadius: 99, border: `1.5px solid ${on ? st.color : "var(--line-strong)"}`, background: on ? st.bg : "transparent", color: on ? st.color : "var(--ink-3)"}}>{s}</button>;
            })}
          </div>
        </div>
        <div className="field"><label>รายละเอียด</label><textarea className="input" rows={3} value={f.detail} onChange={e => set("detail", e.target.value)} placeholder="สเปก/ขนาด/จำนวน/ข้อควรระวัง"/></div>
      </div>
    </Drawer>
  );
}

window.MachineQueuePage = MachineQueuePage;
