/* =============================================================
   CoreIQ Office — Floor & Shelf Planner: rail panels + scan modal
   Exposes window.PlannerRail and window.PlannerScanModal
   ============================================================= */
const { useState: prUseState, useMemo: prUseMemo, useEffect: prUseEffect, useRef: prUseRef } = React;

// ---------------------------------------------------------------
// Summary stat
// ---------------------------------------------------------------
function PlSum({ label, value, sub }) {
  return (
    <div className="pl-sum">
      <div className="pl-sum-l">{label}</div>
      <div className="pl-sum-v">{value}</div>
      {sub && <div className="pl-sum-sub">{sub}</div>}
    </div>
  );
}

// ---------------------------------------------------------------
// Category tree (draggable) — Plan mode
// ---------------------------------------------------------------
function CategoryTree({ plan, storeId, basis, selBay, assignBay, setDragCat, dragCat }) {
  const placed = new Set(window.plannerPlanCats(plan));
  const [open, setOpen] = prUseState(() => {
    const o = {}; window.OFFICE_DATA.CATEGORIES.forEach(d => { o[d.id] = true; }); return o;
  });

  function onChipClick(catId) {
    if (selBay) assignBay(selBay.fixtureId, selBay.bayId, catId);
  }

  return (
    <div>
      {window.OFFICE_DATA.CATEGORIES.map(dept => {
        const color = window.plannerDeptColor(dept.id, 1);
        return (
          <div key={dept.id} className="pl-tree-dept">
            <div className="pl-tree-dept-head" onClick={() => setOpen(o => ({ ...o, [dept.id]: !o[dept.id] }))}>
              <span className="pl-tree-dept-dot" style={{ background: color }}/>
              {dept.name}
              <window.OIcon name="chevron-right" width={13} height={13} className={"pl-tree-dept-chev" + (open[dept.id] ? " pl-tree-dept-chev--open" : "")}/>
            </div>
            {open[dept.id] && (
              <div className="pl-tree-cats">
                {dept.cats.map(cat => {
                  const sku = window.plannerCatSkuCount(cat.id, storeId);
                  const isPlaced = placed.has(cat.id);
                  return (
                    <div
                      key={cat.id}
                      className={"pl-chip" + (isPlaced ? " pl-chip--placed" : "") + (dragCat === cat.id ? " pl-chip--dragging" : "")}
                      draggable
                      onDragStart={(e) => { e.dataTransfer.effectAllowed = "copy"; e.dataTransfer.setData("text/plain", cat.id); setDragCat(cat.id); }}
                      onDragEnd={() => setDragCat(null)}
                      onClick={() => onChipClick(cat.id)}
                      title={selBay ? "Click to assign to selected bay" : "Drag onto a bay"}
                    >
                      <span className="pl-chip-grip"><window.OIcon name="list"/></span>
                      <span className="pl-chip-dot" style={{ background: window.plannerDeptColor(dept.id, 0.9) }}/>
                      {cat.name}
                      <span className="pl-chip-meta">{sku} SKU{isPlaced ? " · placed" : ""}</span>
                    </div>
                  );
                })}
              </div>
            )}
          </div>
        );
      })}
    </div>
  );
}

// ---------------------------------------------------------------
// Bay inspector — Plan mode
// ---------------------------------------------------------------
function BayInspector({ plan, storeId, basis, selBay, clearBay, money }) {
  const fixture = selBay && plan.fixtures.find(f => f.id === selBay.fixtureId);
  const bay = fixture && (fixture.bays || []).find(b => b.id === selBay.bayId);
  if (!bay) {
    return (
      <div className="pl-empty-rail">
        <div className="pl-empty-rail-ic"><window.OIcon name="tag" width={20} height={20}/></div>
        <div className="pl-empty-rail-title">No bay selected</div>
        <div className="pl-empty-rail-meta">Click a bay on the floor plan, then drag or click a category to assign it.</div>
      </div>
    );
  }
  const catId = bay.cat;
  const dept = catId ? window.plannerCatDept(catId) : null;
  const s2s = catId ? window.plannerSpaceToSales(plan, catId, "week") : null;
  const value = catId ? window.plannerCatInventoryValue(catId, storeId, basis) : 0;
  const sku = catId ? window.plannerCatSkuCount(catId, storeId) : 0;
  const sales = catId ? window.plannerCatSales(catId, storeId, "week") : 0;

  return (
    <div>
      <div className="pl-insp-head">
        <div className="pl-insp-sw" style={{ background: catId ? window.plannerDeptColor(dept, 0.92) : "var(--bg-muted)" }}/>
        <div style={{ minWidth: 0 }}>
          <div className="pl-insp-name">{catId ? window.plannerCatName(catId) : "Empty bay"}</div>
          <div className="pl-insp-sub">{fixture.label} · bay {(fixture.bays.indexOf(bay) + 1)}</div>
        </div>
      </div>

      <div className="pl-insp-rows">
        <div className="pl-insp-row"><span className="pl-insp-row-k">Linear space</span><span className="pl-insp-row-v">{bay.m.toFixed(2)} m</span></div>
        {catId && <div className="pl-insp-row"><span className="pl-insp-row-k">Share of floor</span><span className="pl-insp-row-v">{(s2s.shareSpace * 100).toFixed(1)}%</span></div>}
        {catId && <div className="pl-insp-row"><span className="pl-insp-row-k">Inventory ({basis})</span><span className="pl-insp-row-v">{money(value)}</span></div>}
        {catId && <div className="pl-insp-row"><span className="pl-insp-row-k">SKUs stocked</span><span className="pl-insp-row-v">{sku}</span></div>}
        {catId && <div className="pl-insp-row"><span className="pl-insp-row-k">Sales · week</span><span className="pl-insp-row-v">{money(sales)}</span></div>}
        {catId && <div className="pl-insp-row"><span className="pl-insp-row-k">Space-to-sales</span><span className="pl-insp-row-v">{s2s.index.toFixed(2)}×</span></div>}
      </div>

      {catId
        ? <button className="btn btn--ghost btn--block" style={{ color: "var(--void)", marginTop: 12 }} onClick={() => clearBay(selBay.fixtureId, selBay.bayId)}><window.OIcon name="trash"/> Clear bay</button>
        : <div style={{ marginTop: 12, fontSize: 12.5, color: "var(--text-subtle)", lineHeight: 1.5 }}>This bay is empty. Drag a category from the list, or click one while this bay is selected.</div>}
    </div>
  );
}

// ---------------------------------------------------------------
// Performance breakdown — Performance mode
// ---------------------------------------------------------------
function PerfPanel({ plan, storeId, period, metric, basis, setBasis, money }) {
  const cats = window.plannerPlanCats(plan);
  const PERIOD_LABEL = window.PLANNER_DATA.PERIOD_LABEL[period];

  const rows = prUseMemo(() => cats.map(c => {
    const s2s = window.plannerSpaceToSales(plan, c, period);
    return {
      cat: c,
      sales: window.plannerCatSales(c, storeId, period),
      value: window.plannerCatInventoryValue(c, storeId, basis),
      units: window.plannerCatUnits(c, storeId, period),
      gp: window.plannerCatGP(c, storeId, period),
      delta: window.plannerCatDelta(c, storeId, period),
      idx: s2s.index, shareSales: s2s.shareSales, shareSpace: s2s.shareSpace,
    };
  }).sort((a, b) => a.idx - b.idx), [plan, storeId, period, metric, basis]);

  const totals = prUseMemo(() => ({
    sales: rows.reduce((s, r) => s + r.sales, 0),
    gp: rows.reduce((s, r) => s + r.gp, 0),
    value: rows.reduce((s, r) => s + r.value, 0),
  }), [rows]);

  const maxShare = Math.max(...rows.map(r => Math.max(r.shareSales, r.shareSpace)), 0.01);

  function idxClass(idx) { return idx >= 1.15 ? "pl-idx--under" : idx <= 0.85 ? "pl-idx--over" : "pl-idx--ok"; }
  function idxLabel(idx) { return idx >= 1.15 ? "grow" : idx <= 0.85 ? "trim" : "ok"; }

  // movement — top 4 movers + decliners by delta
  const movers = prUseMemo(() => [...rows].sort((a, b) => b.delta - a.delta), [rows]);

  return (
    <>
      <div className="pl-rail-sec">
        <div className="pl-rail-title">Totals · {PERIOD_LABEL}</div>
        <div className="pl-sumrow">
          <PlSum label="Sales" value={money(totals.sales)} sub={`${window.findOfficeStore(storeId).name}`}/>
          <PlSum label="Gross profit" value={money(totals.gp)} sub={`${Math.round(totals.gp / totals.sales * 100)}% margin`}/>
        </div>
        <div style={{ height: 10 }}/>
        <div className="pl-sumrow">
          <PlSum label={`Inventory (${basis})`} value={money(totals.value)} sub={`${cats.length} categories`}/>
          <div className="pl-sum">
            <div className="pl-sum-l">Value basis</div>
            <div style={{ marginTop: 6 }}>
              <div className="pl-seg" style={{ width: "100%" }}>
                {["cost", "retail"].map(b => (
                  <button key={b} className={"pl-seg-btn" + (basis === b ? " pl-seg-btn--active" : "")} style={{ flex: 1, justifyContent: "center", padding: "4px 6px" }} onClick={() => setBasis(b)}>{b === "cost" ? "Cost" : "Retail"}</button>
                ))}
              </div>
            </div>
          </div>
        </div>
      </div>

      {/* legend */}
      <div className="pl-rail-sec">
        <div className="pl-rail-title">Heatmap · {window.PLANNER_DATA.METRICS.find(m => m.key === metric).label}</div>
        {metric === "s2s" ? (
          <div className="pl-legend" style={{ "--pl-heat-lo": "hsl(350,68%,55%)", "--pl-heat-mid": "hsl(205,20%,72%)", "--pl-heat-hi": "hsl(152,55%,42%)" }}>
            <div className="pl-legend-bar"/>
            <div className="pl-legend-scale"><span>Over-spaced</span><span>Balanced</span><span>Under-spaced</span></div>
            <div className="pl-legend-note"><b>Space-to-sales</b> = share of sales ÷ share of floor. <span style={{ color: "var(--paid-text)" }}>Green</span> earns more than its footprint (give it room); <span style={{ color: "var(--void)" }}>red</span> takes more room than it earns (trim).</div>
          </div>
        ) : (
          <div className="pl-legend" style={{ "--pl-heat-lo": "hsl(210,34%,86%)", "--pl-heat-mid": "hsl(198,55%,62%)", "--pl-heat-hi": "hsl(186,68%,40%)" }}>
            <div className="pl-legend-bar"/>
            <div className="pl-legend-scale"><span>Low</span><span>High</span></div>
            <div className="pl-legend-note">Each bay shaded by its {window.PLANNER_DATA.METRICS.find(m => m.key === metric).label.toLowerCase()} {PERIOD_LABEL}.</div>
          </div>
        )}
      </div>

      {/* breakdown table */}
      <div className="pl-rail-sec">
        <div className="pl-rail-title">By category<span className="pl-rail-title-count">{rows.length}</span></div>
        <div className="pl-cat-row pl-cat-row--header">
          <span>Category · space vs sales</span>
          <span style={{ textAlign: "right" }}>Sales</span>
          <span style={{ textAlign: "center" }}>S2S</span>
        </div>
        {rows.map(r => (
          <div key={r.cat} className="pl-cat-row">
            <div style={{ minWidth: 0 }}>
              <div className="pl-cat-name">
                <span className="pl-cat-name-dot" style={{ background: window.plannerDeptColor(window.plannerCatDept(r.cat), 0.9) }}/>
                <span>{window.plannerCatName(r.cat)}</span>
              </div>
              <div className="pl-svs" style={{ marginTop: 5 }}>
                <div className="pl-svs-track pl-svs-space"><i style={{ width: (r.shareSpace / maxShare * 100) + "%" }}/></div>
                <div className="pl-svs-track pl-svs-sales"><i style={{ width: (r.shareSales / maxShare * 100) + "%" }}/></div>
              </div>
            </div>
            <span className="pl-cat-val">{money(r.sales)}</span>
            <span style={{ textAlign: "center" }}><span className={"pl-idx " + idxClass(r.idx)}>{r.idx.toFixed(2)}×</span></span>
          </div>
        ))}
        <div style={{ display: "flex", gap: 14, marginTop: 8, fontSize: 11, color: "var(--text-subtle)" }}>
          <span style={{ display: "inline-flex", alignItems: "center", gap: 5 }}><span style={{ width: 16, height: 4, borderRadius: 9, background: "var(--text-subtle)" }}/> Space</span>
          <span style={{ display: "inline-flex", alignItems: "center", gap: 5 }}><span style={{ width: 16, height: 4, borderRadius: 9, background: "var(--brand)" }}/> Sales</span>
        </div>
      </div>

      {/* movement */}
      <div className="pl-rail-sec">
        <div className="pl-rail-title">Movement · {PERIOD_LABEL} vs prior</div>
        {movers.slice(0, 5).map(r => {
          const up = r.delta >= 0;
          const trend = window.plannerCatTrend(r.cat, storeId, period);
          const tmax = Math.max(...trend, 1);
          return (
            <div key={r.cat} className="pl-move-row">
              <div style={{ minWidth: 0, flex: 1 }}>
                <div className="pl-cat-name"><span className="pl-cat-name-dot" style={{ background: window.plannerDeptColor(window.plannerCatDept(r.cat), 0.9) }}/><span>{window.plannerCatName(r.cat)}</span></div>
              </div>
              <div className="pl-spark" style={{ width: 70 }}>
                {trend.map((v, i) => <div key={i} className={"pl-spark-bar" + (i === trend.length - 1 ? " pl-spark-bar--last" : "")} style={{ height: (v / tmax * 100) + "%" }}/>)}
              </div>
              <span className={"pl-delta " + (up ? "pl-delta--up" : "pl-delta--down")}>
                <window.OIcon name={up ? "arrow-up" : "arrow-down"}/>{Math.abs(r.delta * 100).toFixed(0)}%
              </span>
            </div>
          );
        })}
      </div>
    </>
  );
}

// ---------------------------------------------------------------
// RAIL
// ---------------------------------------------------------------
function PlannerRail(props) {
  const { plan, storeId, mode, period, metric, basis, setBasis, showLabels, setShowLabels,
          selBay, assignBay, clearBay, dragCat, setDragCat, money } = props;

  if (mode === "perf") {
    return (
      <aside className="pl-rail">
        <PerfPanel plan={plan} storeId={storeId} period={period} metric={metric} basis={basis} setBasis={setBasis} money={money}/>
      </aside>
    );
  }

  // PLAN mode
  const totalM = window.plannerTotalLinearM(plan);
  const allBays = window.plannerAllBays(plan);
  const empties = allBays.filter(b => !b.cat).length;
  const cats = window.plannerPlanCats(plan);
  const allocValue = cats.reduce((s, c) => s + window.plannerCatInventoryValue(c, storeId, basis), 0);
  const assignedBays = allBays.filter(b => b.cat).length;

  return (
    <aside className="pl-rail">
      <div className="pl-rail-sec">
        <div className="pl-rail-title">Plan summary</div>
        <div className="pl-sumrow">
          <PlSum label="Linear space" value={totalM.toFixed(1) + " m"} sub={`${assignedBays} bays placed`}/>
          <PlSum label={`Stock on floor`} value={money(allocValue)} sub={`at ${basis}`}/>
        </div>
        {empties > 0 && (
          <div className="stock-alert" style={{ marginTop: 10, background: "var(--hold-bg)", color: "var(--hold-text)", borderColor: "var(--hold-border)" }}>
            <window.OIcon name="alert"/><span><b>{empties}</b> empty bay{empties > 1 ? "s" : ""} — assign a category.</span>
          </div>
        )}
      </div>

      <div className="pl-rail-sec" style={{ flex: 1 }}>
        <div className="pl-rail-title">
          Categories
          <span className="pl-rail-title-count">{selBay ? "click to place" : "drag onto a bay"}</span>
        </div>
        <CategoryTree plan={plan} storeId={storeId} basis={basis} selBay={selBay} assignBay={assignBay} setDragCat={setDragCat} dragCat={dragCat}/>
      </div>

      <div className="pl-rail-sec">
        <div className="pl-rail-title">Selected bay</div>
        <BayInspector plan={plan} storeId={storeId} basis={basis} selBay={selBay} clearBay={clearBay} money={money}/>
      </div>
    </aside>
  );
}

// ---------------------------------------------------------------
// ROOMPLAN SCAN MODAL — staged "scan arriving from iPhone"
// ---------------------------------------------------------------
function PlannerScanModal({ store, plan, onClose, onApply }) {
  const [stage, setStage] = prUseState(0); // 0 connect · 1 scan · 2 walls · 3 fixtures · 4 done
  const [pct, setPct] = prUseState(0);
  const [shownFix, setShownFix] = prUseState(0);

  // fit plan geometry into the preview stage
  const SW = 460, SH = 240, pad = 16;
  const k = Math.min((SW - pad * 2) / plan.room.w, (SH - pad * 2) / plan.room.h);
  const offX = (SW - plan.room.w * k) / 2, offY = (SH - plan.room.h * k) / 2;

  prUseEffect(() => {
    const timers = [];
    timers.push(setTimeout(() => setStage(1), 700));
    // progress during scan
    let p = 0;
    const prog = setInterval(() => { p = Math.min(100, p + 4); setPct(p); }, 70);
    timers.push(setTimeout(() => { clearInterval(prog); setPct(100); setStage(2); }, 2600));
    timers.push(setTimeout(() => setStage(3), 4000));
    return () => { timers.forEach(clearTimeout); clearInterval(prog); };
  }, []);

  // reveal fixtures one-by-one during stage 3
  prUseEffect(() => {
    if (stage !== 3) return;
    let i = 0;
    const id = setInterval(() => {
      i++; setShownFix(i);
      if (i >= plan.fixtures.length) { clearInterval(id); setTimeout(() => setStage(4), 400); }
    }, 110);
    return () => clearInterval(id);
  }, [stage]);

  const statusText = {
    0: "Connecting to iPhone…",
    1: `Capturing room geometry — ${pct}%`,
    2: "Reconstructing walls & openings…",
    3: `Detecting fixtures — ${shownFix}/${plan.fixtures.length}`,
    4: "Plan ready",
  }[stage];

  return (
    <div className="pl-scan-overlay" onClick={onClose}>
      <div className="pl-scan-card" onClick={e => e.stopPropagation()}>
        <div className="pl-scan-head">
          <div className="pl-scan-head-ic"><window.OIcon name="phone"/></div>
          <div style={{ flex: 1 }}>
            <div className="pl-scan-title">Import scan · Apple RoomPlan</div>
            <div className="pl-scan-sub">{store.name} · {store.address.split(",")[0]}</div>
          </div>
          <button className="off-topbar-btn" onClick={onClose}><window.OIcon name="x"/></button>
        </div>

        <div className="pl-scan-stage">
          {stage <= 1 && <><div className="pl-scan-grid"/><div className="pl-scan-sweep"/></>}

          {stage >= 2 && (
            <div className="pl-scan-outline">
              <svg width={SW} height={SH} viewBox={`0 0 ${SW} ${SH}`}>
                <rect className={"pl-scan-room pl-scan-room--draw"} x={offX} y={offY} width={plan.room.w * k} height={plan.room.h * k} rx="3"/>
                {stage >= 3 && plan.fixtures.slice(0, shownFix).map(f => (
                  <rect key={f.id} className="pl-scan-fix pl-scan-fix--show"
                    x={offX + f.x * k} y={offY + f.y * k} width={f.w * k} height={f.h * k} rx="1.5"/>
                ))}
              </svg>
            </div>
          )}

          <div className="pl-scan-status">
            {stage < 4 ? <span className="spinner"/> : <window.OIcon name="check-circle" style={{ color: "#7ee0d0" }}/>}
            {statusText}
          </div>
        </div>

        <div className="pl-scan-foot">
          <div className="pl-scan-metrics">
            <div><div className="pl-scan-metric-l">Area</div><div className="pl-scan-metric-v">{plan.meta.area} m²</div></div>
            <div><div className="pl-scan-metric-l">Fixtures</div><div className="pl-scan-metric-v">{stage >= 3 ? shownFix : 0}</div></div>
            <div><div className="pl-scan-metric-l">Bays</div><div className="pl-scan-metric-v">{stage >= 4 ? plan.fixtures.reduce((s, f) => s + (f.bays || []).length, 0) : 0}</div></div>
          </div>
          <div style={{ flex: 1 }}/>
          <button className="btn btn--secondary" onClick={onClose}>Cancel</button>
          <button className="btn btn--primary" disabled={stage < 4} onClick={onApply}>
            <window.OIcon name="check"/> Apply plan
          </button>
        </div>
      </div>
    </div>
  );
}

window.PlannerRail = PlannerRail;
window.PlannerScanModal = PlannerScanModal;
