// ─────────────────────────────────────────────────────────────────────────────
// Operator Tablet — QC module (Module 3) app shell. Renders the scaled 1280×800
// stage, the tablet top app bar (QC Inspector persona), optional offline banner,
// the current page, an optional bottom tab bar, and the Tweaks panel.
// Per-screen HTML sets window.OPT_START. Pages register on
// window.OptPages[route] = { chrome, title, sub, tab, render }. Loads LAST.
// Reuses hooks + primitives from op-ui.jsx and shared data from op-data.js.
// ─────────────────────────────────────────────────────────────────────────────

const QSIc = window.Icons;
const QDD = window.QD;
const ODD = window.OD;

// route → [code, label, href, group]
const QC_NAV = [
  ["queue",     "OPT-QC-01", "QC queue dashboard",       "OPT-QC-01.html", "Queue"],
  ["entry",     "OPT-QC-02", "QC entry — start",         "OPT-QC-02.html", "Inspection"],
  ["sampling",  "OPT-QC-03", "Sampling — capture",       "OPT-QC-03.html", "Inspection"],
  ["dmParam",   "OPT-QC-04", "Enter DM parameter",       "OPT-QC-04.html", "Inspection"],
  ["ffaParam",  "OPT-QC-05", "Enter FFA parameter",      "OPT-QC-05.html", "Inspection"],
  ["extReport", "OPT-QC-06", "Upload external report",   "OPT-QC-06.html", "Inspection"],
  ["breach",    "OPT-QC-07", "Threshold breach warning", "OPT-QC-07.html", "Inspection"],
  ["remarks",   "OPT-QC-08", "Add remarks & photos",     "OPT-QC-08.html", "Inspection"],
  ["decision",  "OPT-QC-09", "Approve / reject decision","OPT-QC-09.html", "Inspection"],
  ["pass",      "OPT-QC-10", "QC pass — confirmation",   "OPT-QC-10.html", "Inspection"],
  ["reject",    "OPT-QC-11", "QC reject — confirmation", "OPT-QC-11.html", "Inspection"],
  ["matrix",    "OPT-QC-12", "QC matrix configuration",  "OPT-QC-12.html", "Configure"],
  ["history",   "OPT-QC-13", "QC history per batch",     "OPT-QC-13.html", "Records"],
  ["analytics", "OPT-QC-14", "QC pass/fail analytics",   "OPT-QC-14.html", "Records"],
  ["empty",     "OPT-QC-15", "Empty — no QC pending",    "OPT-QC-15.html", "Queue"],
  ["grn",       "OPT-QC-16", "Goods Received Note (GRN)", "OPT-QC-16.html", "Receiving"],
  ["batch",     "OPT-QC-17", "Batch created — warehouse", "OPT-QC-17.html", "Receiving"],
];
const QHREF = Object.fromEntries(QC_NAV.map(([r, , , h]) => [r, h]));

// Bottom tabs
const QTABS = [
  { key: "Queue",     route: "queue",     icon: QSIc.ClipboardList, badge: 5 },
  { key: "History",   route: "history",   icon: QSIc.Clock },
  { key: "Matrix",    route: "matrix",    icon: QSIc.Layers },
  { key: "Analytics", route: "analytics", icon: QSIc.Reports },
];

// Per-screen state tweaks (rendered for the active route only)
const QC_STATE_TWEAKS = {
  queue:     { label: "Queue (QC-01)", opts: [["default","Default — active day"],["longWait","Long-wait alert"],["empty","Empty queue"],["loading","Loading"],["offline","Offline"]] },
  entry:     { label: "Entry (QC-02)", opts: [["default","Default"],["noMatrix","No matrix for variety"],["mismatch","Variety mismatch"],["loading","Loading context"]] },
  sampling:  { label: "Sampling (QC-03)", opts: [["ruleMet","Rule met (3 samples)"],["empty","Empty (0 samples)"],["partial","Partial (< minimum)"],["over","Over-sampled"]] },
  dmParam:   { label: "DM (QC-04)", opts: [["inRange","All in range"],["someOut","Some out of range"],["allOut","All out of range"],["calibration","Calibration overdue"]] },
  ffaParam:  { label: "FFA (QC-05)", opts: [["inRange","All premium"],["tiered","Standard grade"],["someBreach","Some breach"],["allBreach","All breach"]] },
  extReport: { label: "External (QC-06)", opts: [["noUpload","No upload"],["uploaded","Uploaded — manual entry"],["override","Override active"],["tooOld","Report too old"]] },
  breach:    { label: "Breach (QC-07)", opts: [["single","Single breach"],["multiSame","Multiple, same direction"],["mixed","Mixed direction"],["across","DM + FFA breach"]] },
  remarks:   { label: "Remarks (QC-08)", opts: [["noBreach","No breaches"],["breach","Breaches present"],["photoLimit","Photo limit reached"]] },
  decision:  { label: "Decision (QC-09)", opts: [["approve","Recommend approve"],["reject","Recommend reject"],["call","Inspector's call"]] },
  pass:      { label: "Pass (QC-10)", opts: [["default","Default success"],["breach","Approved with breach"],["pending","GRN pending (offline)"]] },
  reject:    { label: "Reject (QC-11)", opts: [["default","Default"],["offline","Offline (queued)"]] },
  matrix:    { label: "Matrix (QC-12)", opts: [["default","Default with matrices"],["editor","Editor open"],["empty","Empty"],["errors","Validation errors"]] },
  history:   { label: "History (QC-13)", opts: [["default","With events"],["noResults","Filtered — no results"],["loading","Loading"],["empty","Empty"]] },
  analytics: { label: "Analytics (QC-14)", opts: [["default","With data"],["sparse","Sparse data"],["loading","Loading"]] },
  empty:     { label: "Empty (QC-15)", opts: [["quiet","Normal quiet"],["fresh","Fresh shift"],["long","Long quiet (>4h)"]] },
};

const QC_TWEAKS_DEFAULTS = /*EDITMODE-BEGIN*/{
  "dark": false,
  "offline": false,
  "queue": "default",
  "entry": "default",
  "sampling": "ruleMet",
  "dmParam": "inRange",
  "ffaParam": "inRange",
  "extReport": "uploaded",
  "breach": "multiSame",
  "remarks": "breach",
  "decision": "approve",
  "pass": "default",
  "reject": "default",
  "matrix": "default",
  "history": "default",
  "analytics": "default",
  "empty": "quiet"
}/*EDITMODE-END*/;

// ── Top app bar ──
const QAppBar = ({ page, offline, onToggleDark, dark, go }) => {
  const flow = page.chrome === "flow";
  return (
    <header className="op-appbar">
      {flow ? (
        <>
          <button className="op-ab-back" aria-label="Back" onClick={() => (page.back ? go(page.back) : history.back())}><QSIc.ChevronLeft size={24}/></button>
          <div style={{ minWidth: 0 }}>
            <div className="op-ab-title">{page.title}</div>
            {page.sub && <div className="op-ab-sub">{page.sub}</div>}
          </div>
        </>
      ) : (
        <div className="op-ab-brand">
          <span className="op-ab-mark"><QSIc.Leaf size={19}/></span>
          <div style={{ minWidth: 0 }}>
            <div className="op-ab-facility">{ODD.FACILITY.name}</div>
            <div className="op-ab-gate"><QSIc.MapPin size={11}/> {ODD.FACILITY.plant} · QC Station 1</div>
          </div>
        </div>
      )}
      <div className="op-ab-spacer"/>
      <div className="op-ab-right">
        <span className={`op-sync ${offline ? "offline" : ""}`} title="Network & sync">
          <span className="op-sync-dot"/>
          {offline ? <><QSIc.WifiOff size={14}/> Offline</> : <><QSIc.Wifi size={14}/> Synced</>}
        </span>
        <span className="op-ab-clock">09:16</span>
        <button className="op-iconbtn ghost" aria-label="Toggle theme" onClick={onToggleDark}>{dark ? <QSIc.Sun size={18}/> : <QSIc.Moon size={18}/>}</button>
        <button className="op-iconbtn ghost" aria-label="Notifications"><QSIc.Bell size={18}/><span className="op-dot"/></button>
        <div className="op-ab-user">
          <span className="avatar avatar-avocado">{QDD.INSPECTOR.initials}</span>
          <div>
            <div className="op-au-name">{QDD.INSPECTOR.name}</div>
            <div className="op-au-role">{QDD.INSPECTOR.role}</div>
          </div>
        </div>
      </div>
    </header>
  );
};

// ── Root ──
const QcApp = () => {
  const route = window.OPT_START || "queue";
  const [scale, setScale] = useState(1);
  const [t, setTweak] = window.useTweaks ? window.useTweaks(QC_TWEAKS_DEFAULTS) : [QC_TWEAKS_DEFAULTS, () => {}];

  const offline = !!t.offline || t[route] === "offline";

  useEffect(() => { document.documentElement.classList.toggle("dark", !!t.dark); }, [t.dark]);

  useEffect(() => {
    const fit = () => {
      const pad = 24;
      setScale(Math.min((window.innerWidth - pad) / 1332, (window.innerHeight - pad) / 852, 1));
    };
    fit();
    window.addEventListener("resize", fit);
    return () => window.removeEventListener("resize", fit);
  }, []);

  const go = useCallback((r) => { if (QHREF[r]) window.location.href = QHREF[r]; }, []);
  const page = window.OptPages?.[route];
  const chrome = page?.chrome || "tabs";
  const showTabs = chrome === "tabs";
  const showAppbar = chrome !== "bare";

  const ctx = { t, setTweak, go, offline, route };
  const st = QC_STATE_TWEAKS[route];

  return (
    <div className="op-stage">
      <div className="op-scaler" style={{ transform: `scale(${scale})` }}>
        <div className="op-device">
          <span className="op-cam"/>
          <div className="op-screen">
          <div className="op-osbar">
            <span className="op-os-time">09:16</span>
            <span className="op-os-right">
              <QSIc.Signal size={15}/>
              {offline ? <QSIc.WifiOff size={15}/> : <QSIc.Wifi size={15}/>}
              <span className="op-os-batt">100%</span>
              <QSIc.Battery size={20}/>
            </span>
          </div>
          {showAppbar && <QAppBar page={page} offline={offline} dark={!!t.dark} onToggleDark={() => setTweak("dark", !t.dark)} go={go}/>}
          {showAppbar && offline && (
            <div className="op-offline-bar">
              <QSIc.WifiOff size={15}/>
              <span>Offline — the cached matrix is in use. Decisions, photos and GRN creation queue and sync when the connection returns.</span>
              <QSIc.ChevronRight size={15} className="op-ob-chev"/>
            </div>
          )}
          {page
            ? page.render(ctx)
            : <div className="op-empty"><div className="op-empty-title">Screen not found</div></div>}
          {showTabs && (
            <div className="op-tabbar-wrap">
              <nav className="op-tabbar">
                {QTABS.map(tab => {
                  const on = tab.key === (page.tab || "Queue");
                  return (
                    <button key={tab.key} className={`op-tab ${on ? "on" : ""}`} onClick={() => go(tab.route)}>
                      {tab.badge != null && <span className="op-tab-badge">{tab.badge}</span>}
                      <tab.icon size={22}/>
                      <span className="op-tab-label">{tab.key}</span>
                    </button>
                  );
                })}
              </nav>
            </div>
          )}
        </div>
        </div>
      </div>

      {window.TweaksPanel && (
        <window.TweaksPanel title="Tweaks">
          <window.TweakSection label="Appearance">
            <window.TweakToggle label="Dark mode" value={t.dark} onChange={(v) => setTweak("dark", v)}/>
            <window.TweakToggle label="Offline mode" value={t.offline} onChange={(v) => setTweak("offline", v)}/>
          </window.TweakSection>
          <window.TweakSection label="Go to screen">
            <window.TweakSelect label="Screen" value={route}
              onChange={(v) => go(v)}
              options={QC_NAV.map(([r, code, label]) => ({ value: r, label: `${code} · ${label}` }))}/>
          </window.TweakSection>
          {st && (
            <window.TweakSection label={st.label}>
              <window.TweakSelect label="Screen state" value={t[route]} onChange={(v) => setTweak(route, v)}
                options={st.opts.map(([value, label]) => ({ value, label }))}/>
            </window.TweakSection>
          )}
        </window.TweaksPanel>
      )}
    </div>
  );
};

const qcRoot = ReactDOM.createRoot(document.getElementById("root"));
qcRoot.render(<QcApp/>);
