// ============================================================
// Rack Detail View — Electric power flow + scan highlight
// ============================================================
const { useState: useStateR, useRef: useRefR, useEffect: useEffectR } = React;

function PortsGrid({ ports, M }) {
  const rows = [ports.slice(0, M), ports.slice(M)];
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
      {rows.map((row, ri) => (
        <div key={ri} style={{ display: 'grid', gridTemplateColumns: `repeat(${M}, 8px)`, gap: 2 }}>
          {row.map((p, i) => (
            <div key={i} className={`port ${p}`} title={`P${ri * M + i + 1} · ${p}`} />
          ))}
        </div>
      ))}
    </div>
  );
}

/* Bolt icon — small lightning glyph */
function Bolt({ size = 10, color = 'currentColor', glow = false }) {
  return (
    <svg width={size} height={size * 1.4} viewBox="0 0 10 14" style={{ overflow: 'visible' }}>
      <path d="M6 0 L0 8 L4 8 L3 14 L10 5 L6 5 Z"
            fill={color}
            style={glow ? { filter: `drop-shadow(0 0 3px ${color})` } : undefined} />
    </svg>
  );
}

function PowerSwitch({ on, onClick }) {
  return (
    <button className={`psw ${on ? 'on' : 'off'}`} onClick={onClick} title={`Power ${on ? 'ON' : 'OFF'}`}>
      {on ? <Bolt size={9} color="var(--electric)" glow={true} /> : <span className="psw-dot" />}
      <span className="psw-lbl">{on ? 'ON' : 'OFF'}</span>
    </button>
  );
}

/* One "wire" from rack top-edge down into the slot's power switch */
function SlotFeedWire({ on }) {
  return (
    <span className={`slot-feed ${on ? 'on' : ''}`} aria-hidden="true">
      {on && (
        <>
          <span className="slot-feed-arc" />
          <span className="slot-feed-arc" style={{ animationDelay: '0.4s' }} />
        </>
      )}
    </span>
  );
}

function Slot({ slot, M, unit, onToggle, tt }) {
  const typeLabel = { server: 'SRV', switch: 'SW', storage: 'STO', empty: '—' }[slot.kind];
  if (slot.kind === 'empty') {
    return (
      <div className="slot empty">
        <div className="slot-u">U{String(unit).padStart(2, '0')}</div>
        <div className="slot-body">
          <div className="slot-type">empty</div>
        </div>
        <div />
      </div>
    );
  }
  const stats = {
    connected: slot.ports.filter(p => p === 'connected').length,
    suspicious: slot.ports.filter(p => p === 'suspicious').length,
    unplugged: slot.ports.filter(p => p === 'unplugged').length,
  };
  const hasPorts = slot.kind !== 'storage';
  const on = slot.power === 'on';
  return (
    <div className={`slot ${on ? 'powered' : ''}`}
      onMouseEnter={(e) => tt.show({
        title: `${slot.name} · ${slot.kind.toUpperCase()}`,
        rows: hasPorts ? [
          ['Power', slot.power.toUpperCase(), on ? 'var(--electric)' : 'var(--fg-2)'],
          ['Ports', `${2*M} total`],
          ['Connected', stats.connected, 'var(--ok)'],
          ['Suspicious', stats.suspicious, stats.suspicious ? 'var(--warn)' : 'var(--fg-2)'],
          ['Unplugged', stats.unplugged, 'var(--fg-2)'],
        ] : [
          ['Power', slot.power.toUpperCase(), on ? 'var(--electric)' : 'var(--fg-2)'],
          ['Type', 'Storage'],
        ]
      }, e)}
      onMouseMove={tt.move}
      onMouseLeave={tt.hide}>
      <div className="slot-u">U{String(unit).padStart(2, '0')}</div>
      <div className="slot-body">
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span className={`slot-type ${slot.kind}`}>{typeLabel}</span>
          <span className="slot-name">{slot.name}</span>
        </div>
        {hasPorts
          ? <div style={{ marginTop: 2 }}><PortsGrid ports={slot.ports} M={M} /></div>
          : <div style={{ marginTop: 2, display: 'flex', gap: 4 }}>
              {Array.from({ length: 3 }).map((_, i) => (
                <div key={i} style={{
                  width: 18, height: 6,
                  background: on ? 'var(--ok)' : 'var(--bg-3)',
                  opacity: on ? 0.6 - i * 0.15 : 0.5,
                  borderRadius: 1,
                }} />
              ))}
            </div>}
      </div>
      <div style={{ position: 'relative', display: 'flex', justifyContent: 'flex-end' }}>
        <SlotFeedWire on={on} />
        <PowerSwitch on={on} onClick={() => onToggle(slot.id)} />
      </div>
    </div>
  );
}

function AbsentRackPlaceholder({ rack, K }) {
  return (
    <div className="rack absent" data-rack-id={rack.id} data-absent="1"
         title={`${rack.label} · 빈 자리`}>
      <div className="rack-head" style={{ opacity: 0.45 }}>
        <span className="id" style={{ color: 'var(--fg-3)' }}>— {rack.label}</span>
        <span className="tag">empty</span>
      </div>
      <div className="absent-body">
        <svg width="100%" height="100%" preserveAspectRatio="none" style={{ position: 'absolute', inset: 0 }}>
          <defs>
            <pattern id={`abs-stripe-${rack.id}`} width="8" height="8" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
              <line x1="0" y1="0" x2="0" y2="8" stroke="var(--line-faint)" strokeWidth="1"/>
            </pattern>
          </defs>
          <rect x="0" y="0" width="100%" height="100%" fill={`url(#abs-stripe-${rack.id})`} opacity="0.5"/>
        </svg>
        <div className="absent-label mono">
          <div style={{ fontSize: 10, letterSpacing: '0.15em', color: 'var(--fg-3)' }}>NO RACK</div>
          <div style={{ fontSize: 9, color: 'var(--fg-3)', opacity: 0.7, marginTop: 2 }}>빈 자리</div>
        </div>
      </div>
    </div>
  );
}

function RackColumn({ rack, M, K, onToggle, tt, scanning }) {
  if (rack.absent) return <AbsentRackPlaceholder rack={rack} K={K} />;
  const anyOn = rack.slots.some(s => s.power === 'on');
  return (
    <div className={`rack ${scanning ? 'scanning' : ''}`} data-rack-id={rack.id}>
      <div className={`rack-feed ${anyOn ? 'on' : ''}`}>
        {anyOn && (
          <>
            <div className="bolt-pulse" />
            <div className="bolt-pulse" />
            <div className="bolt-pulse" />
            <div className="bolt-spark" />
          </>
        )}
      </div>
      <div className="rack-head">
        <span className="id">
          {anyOn && <Bolt size={8} color="var(--electric)" glow={true} />}
          {rack.label}
        </span>
        <span className="tag">{K}U</span>
      </div>
      {/* vertical DC rail on the left of the rack, internal distribution */}
      <div className={`rack-rail ${anyOn ? 'on' : ''}`} aria-hidden="true">
        {anyOn && <div className="rack-rail-flow" />}
      </div>
      {rack.slots.map((s, i) => (
        <Slot key={s.id} slot={s} M={M} unit={K - i} onToggle={onToggle} tt={tt} />
      ))}
    </div>
  );
}

/*
  Power bus — horizontal rail above the racks.
  Receives rack positions (refs-measured) so feed drops align exactly.
*/
function PowerBus({ racks, stageRef, anyOnMap }) {
  const [positions, setPositions] = useStateR([]);
  useEffectR(() => {
    const measure = () => {
      if (!stageRef.current) return;
      const stageRect = stageRef.current.getBoundingClientRect();
      const pts = racks.filter(r => !r.absent).map(r => {
        const el = stageRef.current.querySelector(`[data-rack-id="${r.id}"]`);
        if (!el) return null;
        const rect = el.getBoundingClientRect();
        return {
          id: r.id,
          cx: rect.left - stageRect.left + rect.width / 2,
        };
      }).filter(Boolean);
      setPositions(pts);
    };
    measure();
    const ro = new ResizeObserver(measure);
    if (stageRef.current) ro.observe(stageRef.current);
    window.addEventListener('resize', measure);
    return () => { ro.disconnect(); window.removeEventListener('resize', measure); };
  }, [racks.length]);

  return (
    <svg className="power-bus" preserveAspectRatio="none">
      {/* Main bus bar — two parallel rails */}
      <defs>
        <linearGradient id="bus-grad" x1="0" x2="1" y1="0" y2="0">
          <stop offset="0%" stopColor="var(--electric-hot)" stopOpacity="0.5"/>
          <stop offset="50%" stopColor="var(--electric)" stopOpacity="1"/>
          <stop offset="100%" stopColor="var(--electric-hot)" stopOpacity="0.5"/>
        </linearGradient>
        <filter id="bus-glow" x="-20%" y="-50%" width="140%" height="200%">
          <feGaussianBlur stdDeviation="2" result="b"/>
          <feMerge>
            <feMergeNode in="b"/><feMergeNode in="SourceGraphic"/>
          </feMerge>
        </filter>
      </defs>

      {/* Bus enclosure markings */}
      <rect x="0" y="4" width="100%" height="18" fill="none"
            stroke="var(--line-faint)" strokeWidth="1" strokeDasharray="2 4"/>

      {/* Dark rail */}
      <line x1="0" y1="13" x2="100%" y2="13"
            stroke="var(--line-soft)" strokeWidth="2"/>

      {/* Live rail — yellow */}
      <line x1="0" y1="13" x2="100%" y2="13"
            stroke="url(#bus-grad)" strokeWidth="2.5"
            filter="url(#bus-glow)" opacity="0.95"/>

      {/* Flow particles — rightward */}
      <circle r="3" fill="var(--electric-hot)" filter="url(#bus-glow)">
        <animate attributeName="cx" from="0" to="10000" dur="3s" repeatCount="indefinite"/>
        <animate attributeName="cy" values="13" dur="3s" repeatCount="indefinite"/>
      </circle>
      <circle r="2.5" fill="var(--electric)" filter="url(#bus-glow)">
        <animate attributeName="cx" from="-400" to="10000" dur="3s" repeatCount="indefinite"/>
        <animate attributeName="cy" values="13" dur="3s" repeatCount="indefinite"/>
      </circle>

      {/* Feed tap marks at each rack x */}
      {positions.map(p => {
        const on = anyOnMap[p.id];
        return (
          <g key={p.id}>
            {/* Connector dot on the bus */}
            <circle cx={p.cx} cy="13" r="4"
                    fill="var(--bg-0)"
                    stroke={on ? 'var(--electric)' : 'var(--line-soft)'}
                    strokeWidth="1.2"
                    filter={on ? 'url(#bus-glow)' : undefined}/>
            <circle cx={p.cx} cy="13" r="1.8"
                    fill={on ? 'var(--electric-hot)' : 'var(--fg-3)'}
                    filter={on ? 'url(#bus-glow)' : undefined}/>
            {/* Drop-down stub to the rack top */}
            <line x1={p.cx} y1="17" x2={p.cx} y2="30"
                  stroke={on ? 'var(--electric)' : 'var(--line-soft)'}
                  strokeWidth="1.5"/>
          </g>
        );
      })}

      {/* Label */}
      <text x="6" y="36" fill="var(--fg-3)" fontFamily="var(--font-mono)"
            fontSize="8" letterSpacing="1.5">PDU-01 · 208V / 30A · BUSBAR</text>
    </svg>
  );
}

function RackDetail({ cfg, groupId, onBack, setCfg, scanState }) {
  const group = cfg.groups.find(g => g.id === groupId) || cfg.groups[0];
  const tt = useTooltip();
  const { M, K } = cfg.params;
  const stageRef = useRefR(null);

  const toggle = (slotId) => {
    setCfg(c => ({
      ...c,
      groups: c.groups.map(g => g.id !== group.id ? g : {
        ...g,
        racks: g.racks.map(r => ({
          ...r,
          slots: r.slots.map(s => s.id === slotId ? { ...s, power: s.power === 'on' ? 'off' : 'on' } : s),
        })),
      }),
    }));
  };

  const health = groupHealth(group);
  const col = health.level === 'ok' ? 'var(--ok)' : health.level === 'warn' ? 'var(--warn)' : 'var(--bad)';

  const anyOnMap = {};
  group.racks.forEach(r => { anyOnMap[r.id] = r.slots.some(s => s.power === 'on'); });

  // Which rack is being scanned? scanState: { groupId, rackId } | null
  const scanningRackId = scanState && scanState.groupId === group.id ? scanState.rackId : null;

  return (
    <div className="rack-wrap view-enter" onMouseMove={tt.move}>
      <div className="rack-stage">
        <div className="bp-grid" style={{ opacity: 0.35 }} />
        <Corners />
        <div className="bp-vignette" />

        <div className="rack-stage-inner" ref={stageRef}>
          <PowerBus racks={group.racks} stageRef={stageRef} anyOnMap={anyOnMap}/>
          {group.racks.map(r => (
            <RackColumn key={r.id} rack={r} M={M} K={K}
                        onToggle={toggle} tt={tt}
                        scanning={scanningRackId === r.id} />
          ))}
        </div>
        <Tooltip tip={tt.tip} />
      </div>

      <aside className="rack-side">
        <button className="rack-back-btn" onClick={onBack}>
          <Icon kind="back" size={14} /> 평면도 · Floor Plan
        </button>
        <div className="panel">
          <div className="panel-title"><span>{group.tag}</span><span className="spacer"/><span style={{ color: col }}>{health.level.toUpperCase()}</span></div>
          <div className="stat-row"><span className="k">Racks</span><span className="v">{group.racks.length}</span></div>
          <div className="stat-row"><span className="k">Devices</span><span className="v">{health.total}</span></div>
          <div className="stat-row ok"><span className="k">Powered</span><span className="v">{health.on}/{health.total}</span></div>
          <div className="stat-row"><span className="k">Total Ports</span><span className="v">{health.ports}</span></div>
          <div className="stat-row warn"><span className="k">Suspicious</span><span className="v">{health.susp}</span></div>
        </div>

        {scanningRackId && (
          <div className="panel" style={{ borderColor: 'var(--warn)',
               boxShadow: '0 0 16px rgba(245,180,84,0.22)' }}>
            <div className="panel-title">
              <span style={{ color: 'var(--warn)' }}>Inspection · 점검중</span>
              <span className="spacer"/>
              <span className="mono" style={{ color: 'var(--warn)', animation: 'port-blink 1.2s infinite' }}>●</span>
            </div>
            <div className="mono" style={{ fontSize: 11, color: 'var(--fg-1)', lineHeight: 1.7 }}>
              Target · <span style={{ color: 'var(--warn)' }}>
                {group.racks.find(r => r.id === scanningRackId)?.label}
              </span>
            </div>
            <div className="mono" style={{ fontSize: 9, color: 'var(--fg-3)', marginTop: 4 }}>
              로봇이 해당 랙을 스캔하는 중입니다.
            </div>
          </div>
        )}

        <div className="panel">
          <div className="panel-title"><span>Port Legend</span><span className="spacer"/></div>
          <div className="legend-row" style={{ color: 'var(--fg-2)' }}>
            <div style={{ width: 10, height: 10, border: '1px solid currentColor', borderRadius: 1 }} />
            <span className="nm">Unplugged</span>
            <span className="ct">꼽혀있지 않음</span>
          </div>
          <div className="legend-row ok">
            <div style={{ width: 10, height: 10, background: 'currentColor', borderRadius: 1, boxShadow: '0 0 4px currentColor' }} />
            <span className="nm">Connected</span>
            <span className="ct">꼽혀있음</span>
          </div>
          <div className="legend-row warn">
            <div style={{ width: 10, height: 10, background: 'currentColor', borderRadius: 1, animation: 'port-blink calc(1.2s / var(--anim-speed)) ease-in-out infinite' }} />
            <span className="nm">Suspicious</span>
            <span className="ct">의심스러움</span>
          </div>
        </div>
        <div className="panel">
          <div className="panel-title"><span>Power Flow</span><span className="spacer"/></div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '6px 0' }}>
            <Bolt size={10} color="var(--electric)" glow={true} />
            <div className="mono" style={{ fontSize: 10, color: 'var(--fg-1)', lineHeight: 1.6 }}>
              PDU-01 → BUSBAR<br/>
              → Rack Feed (208V)<br/>
              → Device Switch (ON)
            </div>
          </div>
          <div className="mono" style={{ fontSize: 9, color: 'var(--fg-3)', marginTop: 4 }}>
            ⚡ 노란색 스파크가 활성 장비로 흐릅니다.
          </div>
        </div>
      </aside>
    </div>
  );
}

Object.assign(window, { RackDetail, RackColumn });
