// LanDocs landing hero — a stripped-down version of the promo scene.
// No intro/outro, no camera moves, no big text callouts. Just the app
// quietly building a network: drag-drop devices, click ports to wire them.
// Loops cleanly.

const HERO_DUR = 16.5;
const HW = 1920;
const HH = 1080;

// ── Layout: where devices land on the canvas (stage-absolute coords) ──
const H_LAYOUT = {
  router: { x: 850,  y: 220, w: 220, h: 130 },
  switch: { x: 800,  y: 450, w: 320, h: 150 },
  server: { x: 520,  y: 730, w: 200, h: 110 },
  pc1:    { x: 820,  y: 730, w: 200, h: 110 },
  pc2:    { x: 1120, y: 730, w: 200, h: 110 },
};
const H_INFO = {
  router: { type: 'router', name: 'Edge Router', ports: 6  },
  switch: { type: 'switch', name: 'Core Switch', ports: 24 },
  server: { type: 'server', name: 'NAS',         ports: 2  },
  pc1:    { type: 'pc',     name: 'Workstation', ports: 1  },
  pc2:    { type: 'pc',     name: 'Media PC',    ports: 1  },
};
const H_APPEAR = {
  router: 2.55,
  switch: 4.05,
  server: 5.15,
  pc1:    6.30,
  pc2:    7.40,
};
const H_CABLES = [
  { id: 'h1', from: 'router', to: 'switch', drawStart: 8.65,  drawEnd: 9.20                  },
  { id: 'h2', from: 'switch', to: 'server', drawStart: 10.20, drawEnd: 10.75, fromOffset: -60 },
  { id: 'h3', from: 'switch', to: 'pc1',    drawStart: 11.75, drawEnd: 12.30, fromOffset:  0 },
  { id: 'h4', from: 'switch', to: 'pc2',    drawStart: 13.30, drawEnd: 13.85, fromOffset: 60 },
];

// Targets: cursor lands here. Canvas ports + drop centers are stage-absolute.
const H_CANVAS_TARGETS = {
  'router-bottom':   { x: 960,  y: 350 },
  'switch-top':      { x: 960,  y: 450 },
  'switch-bottom-l': { x: 900,  y: 600 },
  'switch-bottom-c': { x: 960,  y: 600 },
  'switch-bottom-r': { x: 1020, y: 600 },
  'server-top':      { x: 620,  y: 730 },
  'pc1-top':         { x: 920,  y: 730 },
  'pc2-top':         { x: 1220, y: 730 },
  'drop-router':     { x: 960,  y: 285 },
  'drop-switch':     { x: 960,  y: 525 },
  'drop-server':     { x: 620,  y: 785 },
  'drop-pc1':        { x: 920,  y: 785 },
  'drop-pc2':        { x: 1220, y: 785 },
};

const H_CURSOR_KFS = [
  { t: 0.00, x: 1520, y: 820 },
  { t: 0.50, x: 1520, y: 820 },

  // Drag router from toolbox → canvas
  { t: 1.30, target: 'card-router' },
  { t: 1.55, target: 'card-router' },   // click @ 1.55
  { t: 2.50, target: 'drop-router' },
  { t: 2.75, target: 'drop-router' },

  // Quick-add switch
  { t: 3.40, target: 'card-switch' },
  { t: 3.60, target: 'card-switch' },   // click @ 3.60
  { t: 4.10, target: 'drop-switch' },

  // Quick-add server
  { t: 4.75, target: 'card-server' },
  { t: 4.90, target: 'card-server' },   // click @ 4.90
  { t: 5.40, target: 'drop-server' },

  // Quick-add pc1
  { t: 6.00, target: 'card-pc' },
  { t: 6.15, target: 'card-pc' },       // click @ 6.15
  { t: 6.65, target: 'drop-pc1' },

  // Quick-add pc2
  { t: 7.10, target: 'card-pc' },
  { t: 7.25, target: 'card-pc' },       // click @ 7.25
  { t: 7.75, target: 'drop-pc2' },

  // Wire cable 1: router → switch
  { t: 8.10, target: 'router-bottom' },
  { t: 8.30, target: 'router-bottom' }, // click @ 8.30
  { t: 8.85, target: 'switch-top' },
  { t: 9.05, target: 'switch-top' },    // click @ 9.05 — c1 draws 8.65-9.20

  // Wire cable 2: switch → server
  { t: 9.70, target: 'switch-bottom-l' },
  { t: 9.90, target: 'switch-bottom-l' },// click @ 9.90
  { t: 10.40, target: 'server-top' },
  { t: 10.60, target: 'server-top' },   // click @ 10.60 — c2 draws 10.20-10.75

  // Wire cable 3: switch → pc1
  { t: 11.20, target: 'switch-bottom-c' },
  { t: 11.40, target: 'switch-bottom-c' },// click @ 11.40
  { t: 11.90, target: 'pc1-top' },
  { t: 12.10, target: 'pc1-top' },       // click @ 12.10 — c3 draws 11.75-12.30

  // Wire cable 4: switch → pc2
  { t: 12.75, target: 'switch-bottom-r' },
  { t: 12.95, target: 'switch-bottom-r' },// click @ 12.95
  { t: 13.45, target: 'pc2-top' },
  { t: 13.65, target: 'pc2-top' },       // click @ 13.65 — c4 draws 13.30-13.85

  // Settle, then return cursor to corner
  { t: 14.50, target: 'pc2-top' },
  { t: 15.50, x: 1520, y: 820 },
  { t: 16.50, x: 1520, y: 820 },
];

const H_CLICK_EVENTS = [
  { t: 1.55,  dur: 0.22 },
  { t: 3.60,  dur: 0.14 },
  { t: 4.90,  dur: 0.14 },
  { t: 6.15,  dur: 0.14 },
  { t: 7.25,  dur: 0.14 },
  { t: 8.30,  dur: 0.20 },
  { t: 9.05,  dur: 0.20 },
  { t: 9.90,  dur: 0.20 },
  { t: 10.60, dur: 0.20 },
  { t: 11.40, dur: 0.20 },
  { t: 12.10, dur: 0.20 },
  { t: 12.95, dur: 0.20 },
  { t: 13.65, dur: 0.20 },
];

const H_DRAG_WINDOWS = [
  { t0: 1.55, t1: 2.75, type: 'router' },
  { t0: 3.60, t1: 4.10, type: 'switch' },
  { t0: 4.90, t1: 5.40, type: 'server' },
  { t0: 6.15, t1: 6.65, type: 'pc'     },
  { t0: 7.25, t1: 7.75, type: 'pc'     },
];

// Hot/pressed state for toolbox cards
const H_CARD_HOTS = {
  router: [[1.10, 1.55]],
  switch: [[3.20, 3.60]],
  server: [[4.60, 4.90]],
  pc:     [[5.85, 6.15], [6.95, 7.25]],
};
const H_CARD_PRESS = {
  router: [[1.55, 1.72]],
  switch: [[3.60, 3.74]],
  server: [[4.90, 5.04]],
  pc:     [[6.15, 6.29], [7.25, 7.39]],
};

function _hInRanges(ranges, t) {
  if (!ranges) return false;
  for (const [a, b] of ranges) if (t >= a && t <= b) return true;
  return false;
}
function _hDragInfo(time) {
  for (const d of H_DRAG_WINDOWS) if (time >= d.t0 && time <= d.t1) return d.type;
  return null;
}
function _hClickAt(time) {
  for (const e of H_CLICK_EVENTS) if (time >= e.t && time <= e.t + e.dur) return true;
  return false;
}
function _hRipple(time) {
  for (const e of H_CLICK_EVENTS) {
    const dt = time - e.t;
    if (dt >= 0 && dt < 0.55) return 8 + dt * 70;
  }
  return null;
}

// ─── Components (self-contained — don't depend on PromoScene) ───────────

function HeroToolboxCard({ type, time }) {
  const meta = DEVICE_META[type];
  const hot = _hInRanges(H_CARD_HOTS[type], time);
  const pressed = _hInRanges(H_CARD_PRESS[type], time);
  const Icon = meta.Icon;
  return (
    <div className={`ld-device-card ${hot ? 'hot' : ''} ${pressed ? 'pressed' : ''}`}
         data-target={`card-${type}`}>
      <div className="ld-device-icon" style={{ background: meta.bg, border: `1px solid ${meta.color}` }}>
        <Icon size={22}/>
      </div>
      <div>
        <div className="ld-device-label">{meta.label}</div>
        <div className="ld-device-sub">{meta.sub}</div>
      </div>
    </div>
  );
}

function HeroToolbox({ time }) {
  return (
    <aside className="ld-toolbox">
      <div className="ld-toolbox-title">Devices</div>
      <HeroToolboxCard type="switch" time={time}/>
      <HeroToolboxCard type="router" time={time}/>
      <HeroToolboxCard type="server" time={time}/>
      <HeroToolboxCard type="pc"     time={time}/>
      <HeroToolboxCard type="custom" time={time}/>

      <div className="ld-toolbox-shortcuts">
        <div className="ld-shortcuts-title">Shortcuts</div>
        {[
          ['Drag card', 'Place device'],
          ['Click port', 'Connect ports'],
          ['Right-click', 'Edit / remove'],
          ['Shift click', 'Multi-select'],
          ['Del', 'Delete selected'],
          ['Ctrl D', 'Duplicate'],
          ['Ctrl Z', 'Undo'],
          ['F', 'Fit to screen'],
        ].map(([k, v]) => (
          <div key={k} className="ld-shortcut-row">
            <kbd className="ld-kbd">{k}</kbd>
            <span>{v}</span>
          </div>
        ))}
      </div>
    </aside>
  );
}

function HeroTopBar() {
  // Static — no buttons get highlighted in the hero loop.
  return (
    <div className="ld-topbar">
      <span className="ld-app-title">LanDocs</span>
      <div className="ld-sep"/>
      <button className="ld-btn">−</button>
      <span className="ld-zoom-display">100%</span>
      <button className="ld-btn">+</button>
      <button className="ld-btn">1:1</button>
      <button className="ld-btn">Fit</button>
      <div className="ld-sep"/>
      <button className="ld-btn">Snap: On</button>
      <button className="ld-btn">Add Group</button>
      <button className="ld-btn">Find</button>
      <div className="ld-sep"/>
      <button className="ld-btn">Save</button>
      <button className="ld-btn">Load</button>
      <div className="ld-sep"/>
      <button className="ld-btn">PNG</button>
      <button className="ld-btn">TXT</button>
      <div className="ld-sep"/>
      <button className="ld-btn ld-btn-ai">AI Prompt</button>
    </div>
  );
}

function HeroCanvasDevice({ id, time }) {
  const layout = H_LAYOUT[id];
  const info = H_INFO[id];
  const meta = DEVICE_META[info.type];
  const appear = H_APPEAR[id];
  if (time < appear) return null;
  const dt = Math.max(0, time - appear);
  const p = Math.min(1, dt / 0.40);
  const e = easeOut(p);
  const opacity = e;
  const scale = 0.94 + 0.06 * e;
  const dx = layout.x + layout.w / 2;
  const dy = layout.y + layout.h / 2;

  const isSwitch = info.type === 'switch';
  const portCount = isSwitch ? 11 : Math.min(info.ports || 0, 6);
  const portW = isSwitch ? 10 : 11;
  const gap = isSwitch ? 10 : 3;
  const labelY = layout.h < 130 ? 30 : 40;
  const subY = layout.h < 130 ? 48 : 64;

  return (
    <g style={{ opacity }}
       transform={`translate(${dx} ${dy}) scale(${scale}) translate(${-layout.w/2} ${-layout.h/2})`}>
      <rect width={layout.w} height={layout.h} rx="4"
            fill={meta.bg}
            stroke={meta.color}
            strokeWidth="1.8"/>
      <text x={layout.w/2} y={labelY} textAnchor="middle"
            fontFamily="system-ui,sans-serif" fontSize="22" fontWeight="600" fill="#111">
        {info.name}
      </text>
      <text x={layout.w/2} y={subY} textAnchor="middle"
            fontFamily="system-ui,sans-serif" fontSize="13" fontWeight="600"
            fill={meta.color} letterSpacing="0.08em">
        {info.type.toUpperCase()} · {info.ports}P
      </text>
      {portCount > 0 && (() => {
        const total = portCount * portW + (portCount - 1) * gap;
        const startX = (layout.w - total) / 2;
        return Array.from({length: portCount}).map((_, i) => (
          <rect key={i}
                x={startX + i * (portW + gap)}
                y={layout.h - 20}
                width={portW} height={10} rx="1"
                fill="#999"/>
        ));
      })()}
    </g>
  );
}

function _heroCablePath(cable) {
  const a = H_LAYOUT[cable.from];
  const b = H_LAYOUT[cable.to];
  if (!a || !b) return '';
  const ax = a.x + a.w/2 + (cable.fromOffset || 0);
  const ay = a.y + a.h;
  const bx = b.x + b.w/2 + (cable.toOffset || 0);
  const by = b.y;
  const gap = Math.max(50, (by - ay) * 0.45);
  return `M ${ax} ${ay} C ${ax} ${ay + gap}, ${bx} ${by - gap}, ${bx} ${by}`;
}

function HeroCanvas({ time }) {
  return (
    <div className="ld-canvas-panel">
      <svg className="ld-canvas-svg" viewBox="0 0 1242 1016" preserveAspectRatio="xMidYMid meet">
        <defs>
          <pattern id="hero-grid" width="20" height="20" patternUnits="userSpaceOnUse">
            <path d="M 20 0 L 0 0 0 20" fill="none" stroke="#f1f1f1" strokeWidth="1"/>
          </pattern>
        </defs>
        <rect width="1242" height="1016" fill="url(#hero-grid)"/>

        {/* Canvas panel sits at (280,64) in stage coords; offset back so we
            can author device positions in stage-absolute. */}
        <g transform="translate(-280, -64)">
          {H_CABLES.map((c) => {
            if (time < c.drawStart) return null;
            const p = Math.min(1, (time - c.drawStart) / Math.max(0.001, c.drawEnd - c.drawStart));
            const e = easeInOut(p);
            return (
              <path key={c.id}
                    d={_heroCablePath(c)}
                    fill="none"
                    stroke="#555"
                    strokeWidth="2.8"
                    strokeLinecap="round"
                    pathLength="100"
                    strokeDasharray="100"
                    strokeDashoffset={100 * (1 - e)}/>
            );
          })}
          {Object.keys(H_LAYOUT).map((id) => (
            <HeroCanvasDevice key={id} id={id} time={time}/>
          ))}
        </g>
      </svg>
      <div className="ld-zoom-overlay">
        {Object.keys(H_LAYOUT).filter((id) => time >= H_APPEAR[id]).length} devices
        {' · '}
        {H_CABLES.filter((c) => time >= c.drawEnd).length} links
      </div>
    </div>
  );
}

function HeroPropertiesPanel() {
  // Static empty state — properties editing is shown in the feature below.
  return (
    <aside className="ld-config-panel">
      <div className="ld-config-header"><h3>Properties</h3></div>
      <div className="ld-config-content">
        <p className="ld-panel-empty">Click a device or connection to configure it.</p>
      </div>
    </aside>
  );
}

// ─── Top-level Hero Scene ───────────────────────────────────────────────
function LandingHeroScene() {
  const time = useTime();
  const appRef = React.useRef(null);
  const [domTargets, setDomTargets] = React.useState({});

  React.useLayoutEffect(() => {
    if (!appRef.current) return;
    const measure = () => {
      const app = appRef.current;
      if (!app) return;
      const appR = app.getBoundingClientRect();
      if (appR.width === 0) return;
      const factor = HW / appR.width;
      const map = {};
      app.querySelectorAll('[data-target]').forEach((el) => {
        const r = el.getBoundingClientRect();
        const name = el.getAttribute('data-target');
        map[name] = {
          x: (r.left + r.width / 2 - appR.left) * factor,
          y: (r.top + r.height / 2 - appR.top) * factor,
        };
      });
      setDomTargets((prev) => ({ ...prev, ...map }));
    };
    measure();
    const ro = new ResizeObserver(measure);
    ro.observe(appRef.current);
    return () => ro.disconnect();
  }, []);

  const targets = { ...H_CANVAS_TARGETS, ...domTargets };
  const cur = interpKeyframes(H_CURSOR_KFS, time, targets);
  const clicking = _hClickAt(time);
  const ripple = _hRipple(time);
  const dragType = _hDragInfo(time);

  return (
    <div style={{ width: HW, height: HH, position: 'relative', overflow: 'hidden', background: '#fff' }}>
      <div ref={appRef} className="ld-app" style={{ position: 'absolute', left: 0, top: 0 }}>
        <HeroTopBar/>
        <div className="ld-workspace">
          <HeroToolbox time={time}/>
          <HeroCanvas time={time}/>
          <div className="ld-toggle-strip"><span>›</span></div>
          <HeroPropertiesPanel/>
        </div>
      </div>

      {dragType && (() => {
        const meta = DEVICE_META[dragType];
        const Icon = meta.Icon;
        return (
          <div className="ld-drag-ghost" style={{ left: cur.x + 18, top: cur.y + 6 }}>
            <div className="ld-device-icon" style={{ background: meta.bg, border: `1px solid ${meta.color}`, width: 26, height: 26 }}>
              <Icon size={18}/>
            </div>
            <span>{meta.label}</span>
          </div>
        );
      })()}
      <Cursor x={cur.x} y={cur.y} clicking={clicking} ripple={ripple}/>
    </div>
  );
}

// ─── Auto-scaling embed wrapper. Fills its parent, no playback bar/scrubber.
// Self-contained raf loop providing TimelineContext to LandingHeroScene.
function LandingHeroEmbed() {
  const hostRef = React.useRef(null);
  const [scale, setScale] = React.useState(1);
  const [time, setTime] = React.useState(0);

  React.useEffect(() => {
    if (!hostRef.current) return;
    const el = hostRef.current;
    const measure = () => {
      const w = el.clientWidth;
      const h = el.clientHeight;
      if (w === 0 || h === 0) return;
      setScale(Math.min(w / HW, h / HH));
    };
    measure();
    const ro = new ResizeObserver(measure);
    ro.observe(el);
    return () => ro.disconnect();
  }, []);

  React.useEffect(() => {
    let raf;
    let start = null;
    const step = (ts) => {
      if (start == null) start = ts;
      setTime(((ts - start) / 1000) % HERO_DUR);
      raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, []);

  const ctxValue = React.useMemo(
    () => ({ time, duration: HERO_DUR, playing: true }),
    [time]
  );

  return (
    <div ref={hostRef} style={{
      position: 'absolute', inset: 0,
      overflow: 'hidden',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      background: '#fff',
    }}>
      <div style={{
        width: HW, height: HH,
        transform: `scale(${scale})`,
        transformOrigin: 'center center',
        flexShrink: 0,
      }}>
        <TimelineContext.Provider value={ctxValue}>
          <LandingHeroScene/>
        </TimelineContext.Provider>
      </div>
    </div>
  );
}

Object.assign(window, {
  LandingHeroScene, LandingHeroEmbed, HERO_DUR, HW, HH,
});
