/* Shared slide components and constants for the Entrepreneurs Cockpit deck.
   Exposes globals via window assignment at the bottom. */

const TYPE_SCALE = {
  hero: 128,
  title: 80,
  subtitle: 48,
  body: 34,
  small: 26,
  micro: 22
};

const SPACING = {
  paddingTop: 72,
  paddingBottom: 72,
  paddingX: 80,
  titleGap: 40,
  itemGap: 24
};

// SlideShell: standard frame for every slide
function SlideShell({ children, eyebrow, telemetry, gridBg = true, scan = false, hudCorners = true, style = {} }) {
  return (
    <div
      className={[
      gridBg && 'slide-grid',
      scan && 'slide-scan',
      hudCorners && 'hud-corners tl br'].
      filter(Boolean).join(' ')}
      style={{
        position: 'absolute',
        inset: 0,
        padding: `${SPACING.paddingTop + 40}px ${SPACING.paddingX}px ${SPACING.paddingBottom}px`,
        display: 'flex',
        flexDirection: 'column',
        ...style
      }}>
      
      {eyebrow &&
      <div className="eyebrow" style={{ position: 'absolute', top: 40, left: SPACING.paddingX, zIndex: 3 }}>
          <span className="dot" />{eyebrow}
        </div>
      }
      <div style={{ position: 'relative', zIndex: 2, flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0, gap: "10px", justifyContent: "flex-start" }}>
        {children}
      </div>
      {telemetry && <Telemetry items={telemetry} />}
    </div>);

}

// SlideTitle: large display title, optional subtitle
function SlideTitle({ children, style = {} }) {
  return (
    <h1
      style={{ ...{
          fontFamily: 'var(--font-display)',
          fontSize: TYPE_SCALE.title,
          fontWeight: 600,
          lineHeight: 1.02,
          letterSpacing: '-0.025em',
          margin: 0,
          color: 'var(--ink)',
          ...style
        }, fontSize: "70px" }}>
      
      {children}
    </h1>);

}

function SlideSubtitle({ children, style = {} }) {
  return (
    <p
      style={{
        fontFamily: 'var(--font-display)',
        fontSize: TYPE_SCALE.subtitle,
        fontWeight: 400,
        lineHeight: 1.18,
        letterSpacing: '-0.015em',
        margin: 0,
        color: 'var(--ink-soft)',
        ...style
      }}>
      
      {children}
    </p>);

}

// Body text block
function Body({ children, size = 'body', style = {} }) {
  return (
    <p
      style={{ ...{
          fontFamily: 'var(--font-display)',
          fontSize: TYPE_SCALE[size],
          fontWeight: 400,
          lineHeight: 1.45,
          margin: 0,
          color: 'var(--ink-soft)',
          textWrap: 'pretty',
          ...style
        }, fontSize: "34px" }}>
      
      {children}
    </p>);

}

// Mono caption
function Mono({ children, style = {} }) {
  return (
    <span
      style={{ ...{
          fontFamily: 'var(--font-mono)',
          fontSize: TYPE_SCALE.small,
          letterSpacing: '0.04em',
          color: 'var(--ink-soft)',
          ...style
        }, padding: "0px", margin: "0px", borderStyle: "solid", borderWidth: "0px", fontSize: "36px", textAlign: "center" }}>
      
      {children}
    </span>);

}

// Reveal: child appears on step. The slide manages "step" via global state.
function Reveal({ step, current, children, as: As = 'div', style = {}, ...rest }) {
  const shown = current >= step;
  return (
    <As
      className={`reveal-item ${shown ? 'shown' : ''}`}
      style={style}
      {...rest}>
      
      {children}
    </As>);

}

// useStepReveal: per-slide step counter that advances on ArrowRight when slide is active.
// State persists across slide changes — returning to a slide keeps its step;
// when entering forward (next), starts at 0; when entering backward (prev), starts at maxStep.
function useStepReveal(maxStep, isActive, slideIdx) {
  const [step, setStep] = React.useState(0);
  const lastIdxRef = React.useRef(-1);
  React.useEffect(() => {
    if (!isActive) return;
    // Determine direction: did we come from a higher or lower slide index?
    const stage = document.querySelector('deck-stage');
    if (stage && typeof slideIdx === 'number') {
      const prevSlide = lastIdxRef.current;
      if (prevSlide !== slideIdx) {
        if (prevSlide > slideIdx) {
          // Entered going backward — show the slide fully revealed
          setStep(maxStep);
        } else {
          // First entry or forward navigation — start at 0
          setStep(0);
        }
        lastIdxRef.current = slideIdx;
      }
    }
  }, [isActive, slideIdx, maxStep]);
  React.useEffect(() => {
    if (!isActive) return;
    const onKey = (e) => {
      if (e.key === 'ArrowRight' || e.key === ' ' || e.key === 'PageDown') {
        if (step < maxStep) {
          e.preventDefault();
          e.stopPropagation();
          setStep((s) => Math.min(maxStep, s + 1));
        }
      } else if (e.key === 'ArrowLeft' || e.key === 'PageUp') {
        if (step > 0) {
          e.preventDefault();
          e.stopPropagation();
          setStep((s) => Math.max(0, s - 1));
        }
      }
    };
    window.addEventListener('keydown', onKey, true);
    return () => window.removeEventListener('keydown', onKey, true);
  }, [isActive, step, maxStep]);
  return step;
}

// Hook: returns {active, idx} where idx is the current global slide index
function useIsActiveSlide(ref) {
  const [state, setState] = React.useState({ active: false, idx: -1 });
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let section = el;
    while (section && section.tagName !== 'SECTION') section = section.parentElement;
    if (!section) return;
    const stage = document.querySelector('deck-stage');
    if (!stage) return;
    const update = (e) => {
      const isActive = section.hasAttribute('data-deck-active');
      const idx = e?.detail?.index ?? -1;
      setState({ active: isActive, idx });
    };
    update();
    stage.addEventListener('slidechange', update);
    return () => stage.removeEventListener('slidechange', update);
  }, []);
  return state;
}

// Telemetry bottom-left helper
function Telemetry({ items }) {
  return (
    <div className="telemetry">
      {items.map((seg, i) =>
      <React.Fragment key={i}>
          {i > 0 && <span className="sep">/</span>}
          {seg.live && <span className="live">●&nbsp;</span>}
          {seg.label}
        </React.Fragment>
      )}
    </div>);

}

// Image placeholder
function Placeholder({ label, w = '100%', h = 280, style = {} }) {
  return (
    <div className="placeholder" style={{ width: w, height: h, ...style }}>
      <span>[ {label} ]</span>
    </div>);

}

// Hand-drawn-style line wrapper. Pulls SVG paths via children.
function DrawSVG({ width, height, children, style = {} }) {
  return (
    <svg
      width={width}
      height={height}
      viewBox={`0 0 ${width} ${height}`}
      style={{ overflow: 'visible', ...style }}
      xmlns="http://www.w3.org/2000/svg">
      
      {children}
    </svg>);

}

// Red dot / blue dot atomic
function Dot({ kind = 'red', size = 26, glow = true }) {
  const color = kind === 'red' ? 'var(--red-dot)' : 'var(--blue-dot)';
  const glowColor = kind === 'red' ? 'rgba(255,59,107,0.45)' : 'rgba(0,212,255,0.5)';
  return (
    <span
      style={{
        display: 'inline-block',
        width: size,
        height: size,
        borderRadius: '50%',
        background: color,
        boxShadow: glow ? `0 0 ${size * 0.8}px ${glowColor}` : 'none',
        verticalAlign: 'middle'
      }} />);


}

Object.assign(window, {
  TYPE_SCALE, SPACING,
  SlideShell, SlideTitle, SlideSubtitle, Body, Mono,
  Reveal, useStepReveal, useIsActiveSlide,
  Telemetry, Placeholder, DrawSVG, Dot
});