// scenes-base.jsx — White Cube edition
// Reusable cinematic primitives. Bold editorial. White ground, black ink, AK red accent.

const AK_THEME_PRESETS = {
  whiteCube: {
    paper:  '#FFFFFF',
    paperLift: '#FFFFFF',
    ink:    '#0A0A0A',
    inkSoft:'#1F1F1F',
    gray1:  '#3A3A3A',
    gray2:  '#777777',
    gray3:  '#B5B5B5',
    inkDim: 'rgba(10,10,10,0.55)',
    inkMute:'rgba(10,10,10,0.32)',
    rule:   'rgba(10,10,10,0.10)',
    ruleStrong: 'rgba(10,10,10,0.28)',
    red:    '#E62321',
    redDeep:'#B81B19',
    cyan:   '#0049FF',
    grain: false,
  },
  newsprint: {
    paper:  '#F1ECDF',
    paperLift: '#F8F4E9',
    ink:    '#1A1612',
    inkSoft:'#2A2520',
    gray1:  '#4A4338',
    gray2:  '#7A7163',
    gray3:  '#B8AE9C',
    inkDim: 'rgba(26,22,18,0.55)',
    inkMute:'rgba(26,22,18,0.32)',
    rule:   'rgba(26,22,18,0.14)',
    ruleStrong: 'rgba(26,22,18,0.32)',
    red:    '#C8332E',
    redDeep:'#9E2722',
    cyan:   '#1B4FA0',
    grain: true,
  },
  onyx: {
    paper:  '#0E0E10',
    paperLift: '#15151A',
    ink:    '#F5F4F0',
    inkSoft:'#E5E2DA',
    gray1:  '#B8B5AB',
    gray2:  '#7A7872',
    gray3:  '#4A4945',
    inkDim: 'rgba(245,244,240,0.62)',
    inkMute:'rgba(245,244,240,0.36)',
    rule:   'rgba(245,244,240,0.12)',
    ruleStrong: 'rgba(245,244,240,0.30)',
    red:    '#FF4A47',
    redDeep:'#D63A37',
    cyan:   '#7AA8FF',
    grain: false,
  },
};

const AK_TYPE_PRESETS = {
  sans: {
    display: '"Inter", -apple-system, system-ui, sans-serif',
    body:    '"Inter", -apple-system, system-ui, sans-serif',
    mono:    '"JetBrains Mono", ui-monospace, monospace',
    displayWeight: 900,
    displayLetterSpacing: '-0.025em',
    italicDisplay: false,
  },
  serif: {
    display: '"Fraunces", "Times New Roman", serif',
    body:    '"Fraunces", "Times New Roman", serif',
    mono:    '"JetBrains Mono", ui-monospace, monospace',
    displayWeight: 800,
    displayLetterSpacing: '-0.035em',
    italicDisplay: true,
  },
  hybrid: {
    display: '"Fraunces", "Times New Roman", serif',
    body:    '"Inter", -apple-system, system-ui, sans-serif',
    mono:    '"JetBrains Mono", ui-monospace, monospace',
    displayWeight: 800,
    displayLetterSpacing: '-0.030em',
    italicDisplay: false,
  },
};

// Mutable runtime theme — scenes read this each render via a getter object.
window.__AK_THEME = { mood: 'whiteCube', type: 'sans' };

const AK = new Proxy({}, {
  get(_, prop) {
    const moodKey = window.__AK_THEME.mood || 'whiteCube';
    const typeKey = window.__AK_THEME.type || 'sans';
    const palette = AK_THEME_PRESETS[moodKey] || AK_THEME_PRESETS.whiteCube;
    const type = AK_TYPE_PRESETS[typeKey] || AK_TYPE_PRESETS.sans;
    if (prop in type) return type[prop];
    return palette[prop];
  },
});

window.AK = AK;
window.AK_THEME_PRESETS = AK_THEME_PRESETS;
window.AK_TYPE_PRESETS = AK_TYPE_PRESETS;

// ── Motion background — animated brand-color shapes (white cube only) ──────
// Two large soft red blobs drifting on white, plus a subtle ink line that
// crosses the frame. Reads as movement without competing with foreground type.
function BrandMotionBG({ intensity = 1, opacity = 1 }) {
  const { localTime } = useSprite();
  const t = localTime;

  // Blob A: drifts diagonally
  const ax = 200 + Math.sin(t * 0.35) * 240;
  const ay = 700 + Math.cos(t * 0.28) * 180;

  // Blob B: counter-drift
  const bx = 1500 + Math.sin(t * 0.22 + 2) * 280;
  const by = 250 + Math.cos(t * 0.31 + 1) * 200;

  // Ink line sweep
  const sweep = (Math.sin(t * 0.4) + 1) / 2; // 0..1

  return (
    <div style={{
      position: 'absolute', inset: 0, overflow: 'hidden', pointerEvents: 'none',
      opacity,
    }}>
      {/* Soft red blob A */}
      <div style={{
        position: 'absolute',
        left: ax - 380, top: ay - 380,
        width: 760, height: 760, borderRadius: '50%',
        background: `radial-gradient(circle, ${AK.red}22 0%, ${AK.red}00 65%)`,
        filter: 'blur(8px)',
        transform: `scale(${1 + 0.08 * Math.sin(t * 0.6)})`,
      }}/>

      {/* Soft red blob B — smaller, deeper */}
      <div style={{
        position: 'absolute',
        left: bx - 280, top: by - 280,
        width: 560, height: 560, borderRadius: '50%',
        background: `radial-gradient(circle, ${AK.redDeep}1A 0%, ${AK.redDeep}00 60%)`,
        filter: 'blur(6px)',
        transform: `scale(${1 + 0.10 * Math.sin(t * 0.5 + 1)})`,
      }}/>

      {/* Ink hairline sweep */}
      <div style={{
        position: 'absolute',
        left: 0, right: 0,
        top: 540 + Math.sin(t * 0.45) * 220,
        height: 1,
        background: `linear-gradient(90deg, transparent 0%, ${AK.ink}33 ${sweep*70}%, ${AK.red}55 ${sweep*70+10}%, ${AK.ink}22 ${sweep*70+25}%, transparent 100%)`,
      }}/>

      {/* Vertical red rule, slow drift */}
      <div style={{
        position: 'absolute',
        left: 200 + Math.sin(t * 0.25) * 1400,
        top: 0, bottom: 0,
        width: 2,
        background: `linear-gradient(180deg, transparent 0%, ${AK.red}33 30%, ${AK.red}55 50%, ${AK.red}33 70%, transparent 100%)`,
        opacity: 0.8,
      }}/>

      {/* Tiny dot grid for depth */}
      <div style={{
        position: 'absolute', inset: 0,
        backgroundImage: `radial-gradient(${AK.ink}10 1px, transparent 1.5px)`,
        backgroundSize: '40px 40px',
        opacity: 0.45,
      }}/>
    </div>
  );
}

window.BrandMotionBG = BrandMotionBG;

// ── Modern intro background — aurora beams + spotlight + grid mask ─────────
// Transparent base, animated diagonal red aurora beams, radial spotlight mask,
// fine dot grid that fades to edges. Inspired by Aceternity / 21st.dev components.
function BrandIntroBG({ opacity = 1 }) {
  const { localTime } = useSprite();
  const t = localTime;

  // Beam rotations — three diagonal aurora streaks slowly rotating
  const a1 = 18 + Math.sin(t * 0.18) * 8;
  const a2 = -28 + Math.cos(t * 0.14) * 6;
  const a3 = 8 + Math.sin(t * 0.22 + 1) * 10;

  // Spotlight drift — soft red glow drifting horizontally at center-ish
  const sx = 50 + Math.sin(t * 0.20) * 18; // %
  const sy = 48 + Math.cos(t * 0.16) * 10;

  // Grid drift
  const gx = (t * 8) % 40;
  const gy = (t * 6) % 40;

  return (
    <div style={{
      position: 'absolute', inset: 0, overflow: 'hidden', pointerEvents: 'none',
      opacity,
    }}>
      {/* Fine dot grid — radial-masked so it fades to edges */}
      <div style={{
        position: 'absolute', inset: -40,
        backgroundImage: `radial-gradient(${AK.ink} 1px, transparent 1.6px)`,
        backgroundSize: '40px 40px',
        backgroundPosition: `${gx}px ${gy}px`,
        opacity: 0.18,
        WebkitMaskImage: 'radial-gradient(ellipse at center, black 30%, transparent 75%)',
        maskImage: 'radial-gradient(ellipse at center, black 30%, transparent 75%)',
      }}/>

      {/* Aurora beam 1 — wide red sweep */}
      <div style={{
        position: 'absolute',
        left: '-30%', top: '40%',
        width: '160%', height: 280,
        background: `linear-gradient(90deg, transparent 0%, ${AK.red}33 35%, ${AK.red}66 50%, ${AK.red}33 65%, transparent 100%)`,
        filter: 'blur(40px)',
        transform: `translateY(-50%) rotate(${a1}deg)`,
        transformOrigin: 'center',
        mixBlendMode: 'multiply',
      }}/>

      {/* Aurora beam 2 — counter-rotating, deeper */}
      <div style={{
        position: 'absolute',
        left: '-20%', top: '55%',
        width: '140%', height: 200,
        background: `linear-gradient(90deg, transparent 0%, ${AK.redDeep}22 40%, ${AK.redDeep}55 50%, ${AK.redDeep}22 60%, transparent 100%)`,
        filter: 'blur(50px)',
        transform: `translateY(-50%) rotate(${a2}deg)`,
        transformOrigin: 'center',
        mixBlendMode: 'multiply',
      }}/>

      {/* Aurora beam 3 — thin sharp accent */}
      <div style={{
        position: 'absolute',
        left: '-10%', top: '50%',
        width: '120%', height: 60,
        background: `linear-gradient(90deg, transparent 0%, ${AK.red}00 30%, ${AK.red} 50%, ${AK.red}00 70%, transparent 100%)`,
        filter: 'blur(8px)',
        transform: `translateY(-50%) rotate(${a3}deg)`,
        transformOrigin: 'center',
        opacity: 0.6,
      }}/>

      {/* Spotlight — drifting soft white glow that lifts center */}
      <div style={{
        position: 'absolute', inset: 0,
        background: `radial-gradient(circle at ${sx}% ${sy}%, ${AK.white}E6 0%, ${AK.white}00 35%)`,
        mixBlendMode: 'screen',
      }}/>

      {/* Vignette — fade content to edges for cinematic frame */}
      <div style={{
        position: 'absolute', inset: 0,
        background: `radial-gradient(ellipse at center, transparent 50%, ${AK.paper}AA 100%)`,
        pointerEvents: 'none',
      }}/>
    </div>
  );
}
window.BrandIntroBG = BrandIntroBG;
function PaperBG() {
  const showGrain = window.__AK_THEME.mood === 'newsprint';
  return (
    <div style={{ position: 'absolute', inset: 0, background: AK.paper, overflow: 'hidden' }}>
      {showGrain && (
        <div style={{
          position: 'absolute', inset: 0,
          opacity: 0.22, mixBlendMode: 'multiply', pointerEvents: 'none',
          backgroundImage: `url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence baseFrequency='0.85' numOctaves='2' seed='8'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.18 0'/></filter><rect width='240' height='240' filter='url(%23n)'/></svg>")`,
        }}/>
      )}
    </div>
  );
}

function FilmCorners() {
  const c = AK.ink;
  const off = 56;
  const len = 28;
  const w = 1.5;
  return (
    <>
      <div style={{ position:'absolute', left:off, top:off, width:len, height:w, background:c }}/>
      <div style={{ position:'absolute', left:off, top:off, width:w, height:len, background:c }}/>
      <div style={{ position:'absolute', right:off, top:off, width:len, height:w, background:c }}/>
      <div style={{ position:'absolute', right:off, top:off, width:w, height:len, background:c }}/>
      <div style={{ position:'absolute', left:off, bottom:off, width:len, height:w, background:c }}/>
      <div style={{ position:'absolute', left:off, bottom:off, width:w, height:len, background:c }}/>
      <div style={{ position:'absolute', right:off, bottom:off, width:len, height:w, background:c }}/>
      <div style={{ position:'absolute', right:off, bottom:off, width:w, height:len, background:c }}/>
    </>
  );
}

// ── Live timecode + status — top bar of the "film" ──────────────────────────
function FilmTopBar({ chapter = '', tc = '00:00' }) {
  return (
    <div style={{
      position: 'absolute',
      left: 96, right: 96, top: 96,
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      fontFamily: AK.mono,
      fontSize: 13,
      letterSpacing: '0.18em',
      textTransform: 'uppercase',
      color: AK.ink,
      fontWeight: 500,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
        <span style={{
          display: 'inline-block', width: 9, height: 9, borderRadius: 5,
          background: AK.red, animation: 'akpulse 1.6s ease-in-out infinite',
        }}/>
        <span>REC</span>
        <span style={{ width: 24, height: 1, background: AK.ruleStrong }}/>
        <span style={{ color: AK.inkDim }}>AK Networks · Portefólio · 2025</span>
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
        <span style={{ color: AK.inkDim }}>{chapter}</span>
        <span style={{ width: 24, height: 1, background: AK.ruleStrong }}/>
        <span>{tc}</span>
      </div>
    </div>
  );
}

// ── Bottom bar — chapter / progress ─────────────────────────────────────────
function FilmBottomBar({ leftLabel = '', rightLabel = '', progress = 0 }) {
  return (
    <div style={{
      position: 'absolute',
      left: 96, right: 96, bottom: 96,
      display: 'flex', alignItems: 'center', gap: 24,
      fontFamily: AK.mono,
      fontSize: 12,
      letterSpacing: '0.22em',
      textTransform: 'uppercase',
      color: AK.ink,
      fontWeight: 500,
    }}>
      <span style={{ minWidth: 200 }}>{leftLabel}</span>
      <div style={{ flex: 1, height: 1, background: AK.rule, position: 'relative' }}>
        <div style={{
          position: 'absolute', left: 0, top: 0, bottom: 0,
          width: `${progress * 100}%`, background: AK.ink,
        }}/>
      </div>
      <span style={{ color: AK.inkDim, minWidth: 220, textAlign: 'right' }}>{rightLabel}</span>
    </div>
  );
}

// ── Big numerical counter that ticks ───────────────────────────────────────
function CounterChip({ value, label, x, y, delay = 0 }) {
  const { localTime } = useSprite();
  const t = clamp((localTime - delay) / 0.5, 0, 1);
  const e = Easing.easeOutCubic(t);
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      opacity: e, transform: `translateY(${(1-e)*8}px)`,
      display: 'flex', alignItems: 'baseline', gap: 14,
    }}>
      <div style={{
        fontFamily: AK.display, fontWeight: 800,
        fontSize: 14, color: AK.ink,
        letterSpacing: '0.04em',
        background: AK.ink, color: AK.paper,
        padding: '6px 12px', borderRadius: 3,
        fontVariantNumeric: 'tabular-nums',
      }}>{value}</div>
      <div style={{
        fontFamily: AK.mono, fontSize: 12,
        letterSpacing: '0.22em', textTransform: 'uppercase',
        color: AK.inkDim, fontWeight: 500,
      }}>{label}</div>
    </div>
  );
}

// ── Display title — ULTRA bold, scale-clip mask reveal per word ────────────
// Each word lives inside a clip-rect that opens from below.
function MaskTitle({
  text, x, y, size = 220, lineHeight = 0.92, weight,
  color, delay = 0, perWord = 0.10, maxWidth = 1700,
  letterSpacing,
  italic,
  font,
  textAlign,
  highlight,
  highlightColor,
}) {
  const { localTime } = useSprite();
  const words = text.split(' ');
  const resolvedFont = font || AK.display;
  const resolvedWeight = weight ?? AK.displayWeight ?? 900;
  const resolvedColor = color || AK.ink;
  const resolvedLS = letterSpacing || AK.displayLetterSpacing || '-0.045em';
  const resolvedItalic = italic ?? AK.italicDisplay ?? false;
  const hlColor = highlightColor || AK.red;
  const hlSet = new Set(
    Array.isArray(highlight) ? highlight : (highlight ? [highlight] : [])
  );
  const stripPunct = (s) => s.replace(/[.,;:!?·]+$/g, '').toLowerCase();
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      width: maxWidth,
      fontFamily: resolvedFont,
      fontWeight: resolvedWeight,
      fontSize: size,
      lineHeight,
      letterSpacing: resolvedLS,
      color: resolvedColor,
      fontStyle: resolvedItalic ? 'italic' : 'normal',
      textTransform: 'none',
      textWrap: 'balance',
      textAlign: textAlign || 'left',
    }}>
      {words.map((w, i) => {
        const t = clamp((localTime - delay - i * perWord) / 0.7, 0, 1);
        const e = Easing.easeOutCubic(t);
        const isHL = hlSet.has(stripPunct(w));
        return (
          <React.Fragment key={i}>
            <span style={{
              display: 'inline-block',
              overflow: 'hidden',
              verticalAlign: 'top',
              paddingBottom: '0.06em',
            }}>
              <span style={{
                display: 'inline-block',
                transform: `translateY(${(1-e) * 110}%)`,
                willChange: 'transform',
                color: isHL ? hlColor : 'inherit',
              }}>{w}</span>
            </span>
            {i < words.length - 1 ? ' ' : ''}
          </React.Fragment>
        );
      })}
    </div>
  );
}

// ── Slab: a ULTRA bold word in a black bar (placa tipográfica) ─────────────
function SlabWord({ word, x, y, size = 240, delay = 0, color = AK.paper, bg = AK.ink, padding = '0.05em 0.18em' }) {
  const { localTime } = useSprite();
  const t = clamp((localTime - delay) / 0.6, 0, 1);
  const e = Easing.easeOutCubic(t);
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      overflow: 'hidden',
      transform: `scaleX(${e})`,
      transformOrigin: 'left center',
    }}>
      <div style={{
        fontFamily: AK.display, fontWeight: 900,
        fontSize: size, lineHeight: 1, color, background: bg,
        letterSpacing: '-0.045em',
        padding,
        whiteSpace: 'nowrap',
        transform: `scaleX(${1/Math.max(e,0.001)})`,
        transformOrigin: 'left center',
        opacity: e > 0.05 ? 1 : 0,
      }}>{word}</div>
    </div>
  );
}

// ── Eyebrow — small mono caption with leading rule ─────────────────────────
function Eyebrow({ x, y, label, delay = 0, color = AK.ink, ruleColor = AK.red }) {
  const { localTime } = useSprite();
  const t = clamp((localTime - delay) / 0.6, 0, 1);
  const e = Easing.easeOutCubic(t);
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      display: 'flex', alignItems: 'center', gap: 14,
      opacity: e, transform: `translateX(${(1-e) * -10}px)`,
    }}>
      <div style={{ width: 32 * e, height: 3, background: ruleColor }}/>
      <span style={{
        fontFamily: AK.mono, fontSize: 13,
        letterSpacing: '0.24em', textTransform: 'uppercase',
        color, fontWeight: 600,
      }}>{label}</span>
    </div>
  );
}

// ── Body line — bold sentence with progressive opacity ─────────────────────
function BodyLine({ text, x, y, size = 30, width = 1100, delay = 0, color = AK.ink, weight = 500, lineHeight = 1.35, font }) {
  const { localTime } = useSprite();
  const t = clamp((localTime - delay) / 0.9, 0, 1);
  const e = Easing.easeOutCubic(t);
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      width, fontFamily: font || AK.display,
      fontSize: size, fontWeight: weight,
      color, lineHeight,
      letterSpacing: '-0.012em',
      opacity: e,
      transform: `translateY(${(1-e)*10}px)`,
      textWrap: 'pretty',
    }}>{text}</div>
  );
}

// ── Bullets list — stacked, with ticking number ────────────────────────────
function NumberedList({ items, x, y, delay = 0, perItem = 0.18, size = 30, gap = 22, width = 1300, color = AK.ink, accent = AK.red }) {
  const { localTime } = useSprite();
  return (
    <div style={{ position: 'absolute', left: x, top: y, width }}>
      {items.map((b, i) => {
        const local = clamp((localTime - delay - i*perItem) / 0.55, 0, 1);
        const e = Easing.easeOutCubic(local);
        const num = String(i+1).padStart(2, '0');
        return (
          <div key={i} style={{
            display: 'flex', alignItems: 'baseline', gap: 28,
            marginBottom: gap,
            opacity: e,
            transform: `translateX(${(1-e)*16}px)`,
            paddingBottom: 12,
            borderBottom: `1px solid ${AK.rule}`,
          }}>
            <div style={{
              fontFamily: AK.mono, fontWeight: 600,
              fontSize: 13, color: accent, letterSpacing: '0.12em',
              fontVariantNumeric: 'tabular-nums',
              minWidth: 28,
            }}>{num}</div>
            <div style={{
              fontFamily: AK.display, fontWeight: 500,
              fontSize: size, lineHeight: 1.3, color,
              letterSpacing: '-0.012em',
              flex: 1,
              textWrap: 'pretty',
            }}>{b}</div>
          </div>
        );
      })}
    </div>
  );
}

// ── Clean white fade between scenes ────────────────────────────────────────
function SceneShell({ children }) {
  const { localTime, duration } = useSprite();
  const enterT = clamp(localTime / 0.4, 0, 1);
  const exitT = clamp((localTime - (duration - 0.4)) / 0.4, 0, 1);
  const enterE = Easing.easeOutCubic(enterT);
  const exitE = Easing.easeInCubic(exitT);
  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      <PaperBG/>
      <div style={{ position: 'absolute', inset: 0, opacity: enterE * (1 - exitE) }}>{children}</div>
    </div>
  );
}

// ── Pulse dot — for live indicator ─────────────────────────────────────────
const _styleEl = document.createElement('style');
_styleEl.textContent = `
@keyframes akpulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.45; transform: scale(0.85); } }
@keyframes akblink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
`;
document.head.appendChild(_styleEl);

Object.assign(window, {
  AK,
  PaperBG, FilmTopBar, FilmBottomBar, FilmCorners,
  MaskTitle, SlabWord, Eyebrow, BodyLine, NumberedList,
  CounterChip, SceneShell,
});
