// Facility Map — hybrid floorplan + stylized cells.
// Floorplan view: each zone is a building footprint with units rendered as cells inside.
// Grid view: dense unit grid by zone (less spatial, more data).

const { ZONES: M_ZONES, UNITS: M_UNITS } = window.VAULT_DATA;

const STATE_LABEL = {
  vacant: "Vacant",
  occupied: "Occupied",
  reserved: "Reserved",
  delinq: "Delinquent",
  locked: "Smart Locked",
  alarm: "Alarm",
  open: "Door Open",
};

// Simple stat counter
const useUnitFilter = () => {
  const [filter, setFilter] = useState({ states: new Set(), zones: new Set(), climate: null, query: "" });
  const filtered = useMemo(() => M_UNITS.filter(u => {
    if (filter.states.size > 0 && !filter.states.has(u.state)) return false;
    if (filter.zones.size > 0 && !filter.zones.has(u.zone)) return false;
    if (filter.climate === true && !u.climate) return false;
    if (filter.climate === false && u.climate) return false;
    if (filter.query && !u.id.toLowerCase().includes(filter.query.toLowerCase()) &&
        !(u.tenant || "").toLowerCase().includes(filter.query.toLowerCase())) return false;
    return true;
  }), [filter]);
  return { filter, setFilter, filtered };
};

const FilterBar = ({ filter, setFilter, total }) => {
  const states = ["occupied","vacant","reserved","delinq","locked","alarm","open"];
  const toggle = (set, key, val) => {
    const s = new Set(set);
    s.has(val) ? s.delete(val) : s.add(val);
    setFilter(f => ({ ...f, [key]: s }));
  };
  return (
    <div style={{
      display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap",
      padding: "8px 10px",
      background: "var(--bg-1)", border: "1px solid var(--line-1)", borderRadius: 8,
    }}>
      <div className="search" style={{ flex: "0 0 220px", height: 26 }}>
        <Icon name="search" size={12} />
        <input
          placeholder="Unit or tenant…"
          value={filter.query}
          onChange={e => setFilter(f => ({ ...f, query: e.target.value }))}
        />
      </div>
      <div style={{ width: 1, height: 18, background: "var(--line-1)" }} />
      <span style={{ fontSize: 11, color: "var(--tx-3)", textTransform: "uppercase", letterSpacing: "0.08em" }}>State</span>
      {states.map(s => (
        <button
          key={s}
          onClick={() => toggle(filter.states, "states", s)}
          className={`chip ${filter.states.has(s) ? `u-${s === "delinq" ? "delinq" : s}` : ""}`}
          style={{
            cursor: "pointer",
            opacity: filter.states.size === 0 || filter.states.has(s) ? 1 : 0.4,
          }}
        >
          <span className={`u-${s}`} style={{ width: 8, height: 8, border: "1px solid", borderRadius: 2, display: "inline-block", padding: 0 }}></span>
          {STATE_LABEL[s]}
        </button>
      ))}
      <div style={{ width: 1, height: 18, background: "var(--line-1)" }} />
      <span style={{ fontSize: 11, color: "var(--tx-3)", textTransform: "uppercase", letterSpacing: "0.08em" }}>Zone</span>
      {M_ZONES.map(z => (
        <button
          key={z.id}
          onClick={() => toggle(filter.zones, "zones", z.id)}
          className="chip"
          style={{
            cursor: "pointer",
            background: filter.zones.has(z.id) ? "var(--bg-4)" : "var(--bg-3)",
            opacity: filter.zones.size === 0 || filter.zones.has(z.id) ? 1 : 0.5,
          }}
        >{z.id}</button>
      ))}
      <div style={{ flex: 1 }} />
      <span style={{ fontSize: 11.5, color: "var(--tx-3)" }} className="tnum">{total} units</span>
    </div>
  );
};

const Tooltip = ({ unit, x, y }) => {
  if (!unit) return null;
  return (
    <div className="tip" style={{ left: x + 14, top: y + 14 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 6, marginBottom: 6 }}>
        <span className="mono" style={{ fontSize: 12, fontWeight: 600 }}>{unit.id}</span>
        <span className={`chip ${unit.state === "delinq" ? "bad" : unit.state === "alarm" || unit.state === "open" ? "bad" : unit.state === "reserved" ? "warn" : unit.state === "locked" ? "cyan" : unit.state === "vacant" ? "" : "info"}`}>
          {STATE_LABEL[unit.state]}
        </span>
      </div>
      <div style={{ fontSize: 11.5, color: "var(--tx-2)", lineHeight: 1.6 }}>
        <div>{unit.widthM} × {unit.lengthM} m · {unit.sqm} m²</div>
        <div>{unit.type}{unit.climate ? " · Climate" : ""}</div>
        <div className="tnum">${unit.price} <span style={{ color: "var(--tx-3)" }}>/ mo</span></div>
        {unit.tenant && <div style={{ marginTop: 4, color: "var(--tx-1)" }}>{unit.tenant}</div>}
      </div>
    </div>
  );
};

// Floorplan rendering: zone buildings drawn at scale, units packed inside.
const Floorplan = ({ filter, filtered, onPick, hover, setHover }) => {
  const filteredIds = useMemo(() => new Set(filtered.map(u => u.id)), [filtered]);
  const W = 1080, H = 420;

  return (
    <div style={{ position: "relative", width: "100%", overflow: "auto", border: "1px solid var(--line-1)", borderRadius: 12, background: "var(--bg-1)" }}>
      <svg
        viewBox={`0 0 ${W} ${H}`}
        style={{ width: "100%", display: "block", minWidth: 800 }}
      >
        {/* grid bg */}
        <defs>
          <pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse">
            <path d="M 20 0 L 0 0 0 20" fill="none" stroke="var(--line-1)" strokeWidth="0.5"/>
          </pattern>
        </defs>
        <rect width={W} height={H} fill="url(#grid)" />

        {/* drive aisles between zones */}
        <rect x={20} y={245} width={1040} height={30} fill="var(--bg-2)" stroke="var(--line-1)" strokeDasharray="4 4" />
        <text x={540} y={262} textAnchor="middle" fontSize="10" fill="var(--tx-3)" letterSpacing="2">DRIVE LANE</text>

        {/* gates */}
        <g>
          <rect x={4} y={175} width={16} height={30} fill="var(--accent-700)" stroke="var(--accent-400)" />
          <text x={12} y={222} textAnchor="middle" fontSize="9" fill="var(--accent-300)">G1</text>
          <rect x={1060} y={175} width={16} height={30} fill="var(--accent-700)" stroke="var(--accent-400)" />
          <text x={1068} y={222} textAnchor="middle" fontSize="9" fill="var(--accent-300)">G2</text>
        </g>

        {M_ZONES.map(zone => {
          const { pos } = zone;
          // unit cells in zone
          const zoneUnits = M_UNITS.filter(u => u.zone === zone.id);
          const cellW = (pos.w - 12) / zone.cols;
          const cellH = (pos.h - 24) / zone.rows;

          return (
            <g key={zone.id}>
              {/* zone outline */}
              <rect
                x={pos.x} y={pos.y} width={pos.w} height={pos.h}
                fill="var(--bg-2)"
                stroke="var(--line-2)"
                strokeWidth={1}
                rx={6}
              />
              <text x={pos.x + 8} y={pos.y + 14} fontSize="11" fill="var(--tx-2)" fontWeight="500">
                {zone.label}
              </text>
              <text x={pos.x + pos.w - 8} y={pos.y + 14} fontSize="10" fill="var(--tx-3)" textAnchor="end">
                {zone.type}{zone.climate ? " · Climate" : ""} · {zoneUnits.length}
              </text>

              {/* hallway */}
              {zone.rows > 1 && (
                <rect
                  x={pos.x + 6} y={pos.y + 18 + cellH * (zone.rows / 2) - 2}
                  width={pos.w - 12} height={4}
                  fill="var(--bg-0)" opacity="0.6"
                />
              )}

              {zoneUnits.map((u) => {
                const cx = pos.x + 6 + u.col * cellW;
                const cy = pos.y + 18 + u.row * cellH;
                const isFiltered = filteredIds.has(u.id);
                const dim = filtered.length !== M_UNITS.length && !isFiltered;
                const colors = {
                  vacant:   { fill: "#1a1f2c", stroke: "#2c3344" },
                  occupied: { fill: "#2a3a5e", stroke: "#4d7cdb" },
                  reserved: { fill: "#3a2c0f", stroke: "#f59e0b" },
                  delinq:   { fill: "#3a1418", stroke: "#ef4444" },
                  locked:   { fill: "#0e2c33", stroke: "#22d3ee" },
                  alarm:    { fill: "#5a1218", stroke: "#ef4444" },
                  open:     { fill: "#1d2456", stroke: "#6b73ff" },
                };
                const c = colors[u.state];
                return (
                  <g key={u.id}
                     onMouseEnter={(e) => setHover({ unit: u, x: e.clientX, y: e.clientY })}
                     onMouseMove={(e) => setHover({ unit: u, x: e.clientX, y: e.clientY })}
                     onMouseLeave={() => setHover(null)}
                     onClick={() => onPick(u)}
                     style={{ cursor: "pointer", opacity: dim ? 0.18 : 1, transition: "opacity 200ms" }}
                  >
                    <rect
                      x={cx + 0.5} y={cy + 0.5}
                      width={cellW - 1.5} height={cellH - 1.5}
                      fill={c.fill} stroke={c.stroke}
                      strokeWidth={u.state === "alarm" ? 1.5 : 0.8}
                      rx={2}
                    />
                    {u.state === "alarm" && (
                      <rect x={cx + 0.5} y={cy + 0.5} width={cellW - 1.5} height={cellH - 1.5}
                            fill="none" stroke="#ef4444" strokeWidth="1" rx={2}>
                        <animate attributeName="opacity" values="0.3;1;0.3" dur="1.4s" repeatCount="indefinite"/>
                      </rect>
                    )}
                    {u.state === "open" && (
                      <rect x={cx + 0.5} y={cy + 0.5} width={cellW - 1.5} height={cellH - 1.5}
                            fill="none" stroke="#8d96ff" strokeWidth="1" rx={2}>
                        <animate attributeName="opacity" values="0.4;1;0.4" dur="2s" repeatCount="indefinite"/>
                      </rect>
                    )}
                    {cellW > 22 && (
                      <text x={cx + cellW/2} y={cy + cellH/2 + 3} fontSize={cellW > 30 ? "8" : "7"}
                            textAnchor="middle" fill={c.stroke} opacity="0.85"
                            fontFamily="var(--font-mono)">
                        {u.id.split("-")[1]}
                      </text>
                    )}
                  </g>
                );
              })}
            </g>
          );
        })}

        {/* compass / scale */}
        <g transform={`translate(${W - 80}, ${H - 36})`}>
          <line x1={0} y1={10} x2={60} y2={10} stroke="var(--tx-3)" strokeWidth="1"/>
          <line x1={0} y1={6} x2={0} y2={14} stroke="var(--tx-3)" strokeWidth="1"/>
          <line x1={60} y1={6} x2={60} y2={14} stroke="var(--tx-3)" strokeWidth="1"/>
          <text x={30} y={26} textAnchor="middle" fontSize="9" fill="var(--tx-3)">10 m</text>
        </g>
      </svg>

      <Tooltip unit={hover?.unit} x={hover?.x ?? 0} y={hover?.y ?? 0} />
    </div>
  );
};

// Grid view: dense per-zone grid
const GridView = ({ filter, filtered, onPick, hover, setHover }) => {
  const byZone = useMemo(() => {
    const m = {};
    M_ZONES.forEach(z => m[z.id] = []);
    filtered.forEach(u => m[u.zone].push(u));
    return m;
  }, [filtered]);

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      {M_ZONES.map(z => {
        const units = byZone[z.id];
        return (
          <div key={z.id} className="card" style={{ padding: 14 }}>
            <div className="card-h">
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                <div className="card-t" style={{ marginBottom: 0 }}>{z.label}</div>
                <span className="chip">{z.type}{z.climate ? " · Climate" : ""}</span>
                <span style={{ fontSize: 11, color: "var(--tx-3)" }} className="tnum">{units.length} units</span>
              </div>
            </div>
            <div style={{
              display: "grid",
              gridTemplateColumns: `repeat(${z.cols}, minmax(0, 1fr))`,
              gap: 4,
            }}>
              {units.map(u => (
                <div
                  key={u.id}
                  className={`u-${u.state} ${u.state === "alarm" ? "alarm-pulse" : ""}${u.state === "open" ? " door-open-glow" : ""}`}
                  style={{
                    border: "1px solid", borderRadius: 4,
                    padding: "6px 4px",
                    fontSize: 10, fontFamily: "var(--font-mono)", textAlign: "center",
                    cursor: "pointer",
                    transition: "transform 120ms",
                  }}
                  onMouseEnter={(e) => setHover({ unit: u, x: e.clientX, y: e.clientY })}
                  onMouseMove={(e) => setHover({ unit: u, x: e.clientX, y: e.clientY })}
                  onMouseLeave={() => setHover(null)}
                  onClick={() => onPick(u)}
                  onMouseOver={(e) => e.currentTarget.style.transform = "scale(1.06)"}
                  onMouseOut={(e) => e.currentTarget.style.transform = "scale(1)"}
                >
                  {u.id.split("-")[1]}
                </div>
              ))}
            </div>
          </div>
        );
      })}
      <Tooltip unit={hover?.unit} x={hover?.x ?? 0} y={hover?.y ?? 0} />
    </div>
  );
};

// Heatmap: occupancy intensity per zone
const HeatmapView = ({ filtered }) => {
  return (
    <div className="card" style={{ padding: 18 }}>
      <div className="card-h"><div className="card-t">Occupancy heatmap</div></div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 10 }}>
        {M_ZONES.map(z => {
          const units = M_UNITS.filter(u => u.zone === z.id);
          const occ = units.filter(u => u.state !== "vacant").length;
          const pct = Math.round((occ / units.length) * 100);
          const intensity = pct / 100;
          return (
            <div key={z.id} style={{
              padding: 14, borderRadius: 8,
              background: `color-mix(in oklab, var(--accent-500) ${intensity * 60}%, var(--bg-2))`,
              border: "1px solid var(--line-2)"
            }}>
              <div style={{ fontSize: 11.5, color: "var(--tx-2)" }}>{z.label}</div>
              <div style={{ fontSize: 22, fontWeight: 600, marginTop: 4 }} className="tnum">{pct}%</div>
              <div style={{ fontSize: 11, color: "var(--tx-3)" }}>{occ} of {units.length} occupied</div>
              <div className="bar" style={{ marginTop: 10 }}>
                <span style={{ width: `${pct}%` }} />
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
};

const FacilityMap = ({ initialMode = "floorplan", onPickUnit }) => {
  const [mode, setMode] = useState(initialMode);
  const [hover, setHover] = useState(null);
  const { filter, setFilter, filtered } = useUnitFilter();

  const counts = useMemo(() => {
    const c = {};
    M_UNITS.forEach(u => c[u.state] = (c[u.state] || 0) + 1);
    return c;
  }, []);

  return (
    <div data-screen-label="Facility Map" style={{ display: "flex", flexDirection: "column", gap: 14 }}>
      <div className="page-head">
        <div>
          <h1 className="page-title">Facility Map</h1>
          <div className="page-sub">Auckland Central · 5 zones · {M_UNITS.length} units · last sync 12s ago</div>
        </div>
        <div className="head-actions">
          <div style={{
            display: "inline-flex", background: "var(--bg-1)",
            border: "1px solid var(--line-1)", borderRadius: 7, padding: 2,
          }}>
            {[
              { id: "floorplan", icon: "map",   label: "Floorplan" },
              { id: "grid",      icon: "grid3", label: "Grid" },
              { id: "heatmap",   icon: "layers",label: "Heatmap" },
            ].map(t => (
              <button
                key={t.id}
                className="btn ghost sm"
                onClick={() => setMode(t.id)}
                style={{
                  background: mode === t.id ? "var(--bg-3)" : "transparent",
                  color: mode === t.id ? "var(--tx-1)" : "var(--tx-2)",
                  border: 0, height: 26,
                }}
              >
                <Icon name={t.icon} size={12} /> {t.label}
              </button>
            ))}
          </div>
          <button className="btn ghost"><Icon name="external" size={14} /> Export</button>
          <button className="btn primary"><Icon name="plus" size={14} /> Reserve unit</button>
        </div>
      </div>

      <FilterBar filter={filter} setFilter={setFilter} total={filtered.length} />

      <div className="legend" style={{ padding: "0 4px" }}>
        {[
          ["occupied","Occupied"],["vacant","Vacant"],["reserved","Reserved"],
          ["delinq","Delinquent"],["locked","Smart Locked"],["open","Door Open"],
          ["alarm","Alarm"],
        ].map(([k, lbl]) => (
          <span key={k} className="legend-i">
            <span className={`sw u-${k}`} />{lbl} <span className="dim tnum">· {counts[k] || 0}</span>
          </span>
        ))}
      </div>

      {mode === "floorplan" && (
        <Floorplan filter={filter} filtered={filtered} onPick={onPickUnit} hover={hover} setHover={setHover} />
      )}
      {mode === "grid" && (
        <GridView filter={filter} filtered={filtered} onPick={onPickUnit} hover={hover} setHover={setHover} />
      )}
      {mode === "heatmap" && <HeatmapView filtered={filtered} />}
    </div>
  );
};

window.FacilityMap = FacilityMap;
