// transaction-journey.jsx — Direction 2: "One Transaction's Journey"
//
// 12s loop. Slower, narrative. Follow ONE ambiguous tx through each
// classifier, with confidence scores resolving in real time.
//
// Beats:
// 0.0 - 1.5s   A single raw tx hash drifts in from the left, "?" question marks
// 1.5 - 3.0s   It hits FUNCTION DECODER → method id resolves: "swap()"
// 3.0 - 4.5s   CHAIN DETECT → "Arbitrum One"
// 4.5 - 6.0s   PROTOCOL INTEL → "Uniswap v4"
// 6.0 - 7.5s   RULE LIBRARY → applies "DEX trade" rule
// 7.5 - 9.0s   CONSENSUS CHECK → 99.2% confidence
// 9.0 - 10.5s  Output: clean ledger row materializes on the right
// 10.5 - 12s   Hold on result, fade

function TransactionJourney() {
  const time = useTime();
  const W = 1920, H = 1080;
  const HUB = { x: 960, y: 600 };

  // The single transaction we're following
  const tx = {
    hash: '0xa1b2c3d4e5f60718',
    fromAddr: '0x4f...28ab',
    toAddr:   '0xc02a...c0d6',
    methodId: '0x7ff36ab5',
    rawValue: '2.4500 ETH',
  };

  // Six checkpoints the tx passes through
  const checkpoints = [
    { t: 1.5, label: 'FUNCTION DECODER',     resolved: 'swap(uint256,...)',    confidence: 28 },
    { t: 3.0, label: 'CHAIN DETECT',         resolved: 'Arbitrum One · 42161', confidence: 52 },
    { t: 4.5, label: 'PROTOCOL INTEL',       resolved: 'Uniswap v4 · Router',  confidence: 74 },
    { t: 6.0, label: 'RULE LIBRARY',         resolved: 'DEX swap → Sched D',   confidence: 88 },
    { t: 7.5, label: 'CONSENSUS CHECK',      resolved: '5/5 sources agree',    confidence: 99.2 },
    { t: 9.0, label: 'CLASSIFICATION CACHE', resolved: 'Cached · re-usable',   confidence: 99.2 },
  ];

  // Tx position along a horizontal track at y=540, moves through 6 stations
  const trackY = 540;
  const stations = checkpoints.map((c, i) => ({
    x: 220 + i * 280,
    y: trackY,
    ...c,
  }));

  // Tx travels: 0s at x=80 → reaches station[0] at t=1.5 → station[5] at t=9.0
  const txX = interpolate(
    [0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.0, 12],
    [80, stations[0].x, stations[1].x, stations[2].x, stations[3].x, stations[4].x, stations[5].x, 1700, 1700],
    Easing.easeInOutCubic
  )(time);

  // Background classifier diagram dims to focus on the journey
  const headlineOpacity = animate({ from: 0, to: 1, start: 0.2, end: 1.2 })(time)
                        * animate({ from: 1, to: 0, start: 11, end: 11.9 })(time);

  // Cumulative confidence — resolves over time
  const currentCheckpoint = stations.findIndex(s => time < s.t + 0.2);
  const activeIdx = currentCheckpoint === -1 ? stations.length - 1 : Math.max(0, currentCheckpoint - 1);
  const currentConfidence = activeIdx >= 0 ? stations[activeIdx].confidence : 0;

  return (
    <>
      <GridBackground opacity={0.6} />

      {/* Headline */}
      <div style={{
        position: 'absolute',
        left: 80, top: 80,
        opacity: headlineOpacity,
      }}>
        <div style={{
          fontFamily: FONTS.mono,
          fontSize: 13,
          letterSpacing: '0.28em',
          color: CTE.teal,
          marginBottom: 18,
        }}>
          ◆ &nbsp; ANATOMY OF A CLASSIFICATION
        </div>
        <div style={{
          fontFamily: FONTS.display,
          fontSize: 56,
          fontWeight: 600,
          color: CTE.text,
          letterSpacing: '-0.025em',
          lineHeight: 1.05,
          maxWidth: 900,
        }}>
          One unknown transaction.<br/>
          <span style={{ color: CTE.teal }}>Six checks.</span> Tax-ready in seconds.
        </div>
      </div>

      {/* Track line connecting the stations */}
      <svg width={W} height={H} style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>
        <defs>
          <linearGradient id="track-grad" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%" stopColor={CTE.teal} stopOpacity="0.0"/>
            <stop offset="50%" stopColor={CTE.teal} stopOpacity="0.6"/>
            <stop offset="100%" stopColor={CTE.teal} stopOpacity="0.0"/>
          </linearGradient>
        </defs>
        <line x1={80} y1={trackY} x2={1700} y2={trackY}
          stroke={`${CTE.teal}25`} strokeWidth={1.5} strokeDasharray="4 8" />

        {/* Filled portion behind tx */}
        <line x1={80} y1={trackY} x2={txX} y2={trackY}
          stroke={CTE.teal} strokeWidth={2.5}
          style={{ filter: `drop-shadow(0 0 6px ${CTE.teal})` }} />
      </svg>

      {/* Station nodes */}
      {stations.map((s, i) => {
        const reached = time >= s.t - 0.1;
        const justReached = time >= s.t - 0.1 && time <= s.t + 1.2;
        const pulse = justReached
          ? 1 + 0.6 * Math.exp(-(time - s.t) * 4) * Math.sin((time - s.t) * 14)
          : 1;
        const opacity = animate({ from: 0.3, to: 1, start: s.t - 0.6, end: s.t + 0.2 })(time);

        return (
          <React.Fragment key={i}>
            {/* Big circle node */}
            <div style={{
              position: 'absolute',
              left: s.x - 24, top: s.y - 24,
              width: 48, height: 48,
              borderRadius: 24,
              background: reached ? CTE.teal : CTE.bg3,
              border: `2px solid ${reached ? CTE.teal : CTE.bg3}`,
              boxShadow: reached ? `0 0 24px ${CTE.teal}88` : 'none',
              transform: `scale(${pulse})`,
              transition: 'background 200ms',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontFamily: FONTS.mono,
              fontSize: 14,
              fontWeight: 600,
              color: reached ? CTE.bg0 : CTE.textMuted,
            }}>
              {reached ? '✓' : i + 1}
            </div>

            {/* Label above */}
            <div style={{
              position: 'absolute',
              left: s.x - 130, top: s.y - 110,
              width: 260,
              textAlign: 'center',
              opacity: opacity * 0.9,
              fontFamily: FONTS.mono,
              fontSize: 11,
              letterSpacing: '0.18em',
              color: reached ? CTE.text : CTE.textMuted,
            }}>
              {s.label}
            </div>

            {/* Resolved value below */}
            <div style={{
              position: 'absolute',
              left: s.x - 140, top: s.y + 38,
              width: 280,
              textAlign: 'center',
              opacity: animate({ from: 0, to: 1, start: s.t, end: s.t + 0.4 })(time),
              transform: `translateY(${(1 - animate({ from: 0, to: 1, start: s.t, end: s.t + 0.4 })(time)) * 8}px)`,
              fontFamily: FONTS.mono,
              fontSize: 12,
              color: CTE.teal,
              letterSpacing: '0.04em',
              lineHeight: 1.4,
            }}>
              <div style={{ color: CTE.text, fontSize: 13 }}>{s.resolved}</div>
              <div style={{ color: CTE.textMuted, marginTop: 4, fontSize: 10, letterSpacing: '0.16em' }}>
                CONF · <span style={{ color: CTE.ok }}>{s.confidence}%</span>
              </div>
            </div>
          </React.Fragment>
        );
      })}

      {/* The traveling tx pill */}
      <TxPill x={txX} y={trackY} hash={tx.hash} confidence={currentConfidence} time={time} />

      {/* Logo in corner — quietly pulsing, indicates the engine is doing the work */}
      <div style={{ opacity: 0.55 }}>
        <LogoEngine
          x={1740} y={140}
          size={140}
          nodeActivation={Array(7).fill(0.7 + 0.3 * Math.sin(time * 2))}
          hubPulse={0.5 + 0.5 * Math.sin(time * 1.8)}
          intensity={0.7}
        />
      </div>

      {/* Final ledger row at the bottom */}
      <FinalRow time={time} x={W / 2 - 360} y={870} />
    </>
  );
}

function TxPill({ x, y, hash, confidence, time }) {
  // Subtle hover wobble while traveling
  const wobble = Math.sin(time * 8) * 1.2;

  return (
    <div style={{
      position: 'absolute',
      left: x, top: y + wobble,
      transform: 'translate(-50%, -50%)',
      display: 'flex',
      alignItems: 'center',
      gap: 10,
      padding: '12px 18px',
      background: `linear-gradient(180deg, ${CTE.bg3} 0%, ${CTE.bg2} 100%)`,
      border: `1.5px solid ${CTE.teal}`,
      borderRadius: 24,
      boxShadow: `0 0 28px ${CTE.teal}66, 0 8px 24px ${CTE.bg0}`,
      fontFamily: FONTS.mono,
      fontSize: 13,
      color: CTE.text,
      letterSpacing: '0.04em',
      whiteSpace: 'nowrap',
      zIndex: 10,
    }}>
      <span style={{
        width: 8, height: 8, borderRadius: 4,
        background: CTE.teal,
        boxShadow: `0 0 8px ${CTE.teal}`,
      }} />
      <span>tx</span>
      <span style={{ color: CTE.teal, fontWeight: 600 }}>{hash}</span>
      <span style={{ color: CTE.textMuted }}>|</span>
      <span style={{ color: confidence >= 95 ? CTE.ok : confidence >= 60 ? CTE.warn : CTE.err, fontVariantNumeric: 'tabular-nums' }}>
        {confidence.toFixed(1)}%
      </span>
    </div>
  );
}

function FinalRow({ time, x, y }) {
  const opacity = animate({ from: 0, to: 1, start: 9.6, end: 10.4, ease: Easing.easeOutCubic })(time)
                * animate({ from: 1, to: 0, start: 11.4, end: 11.9 })(time);
  const ty = (1 - animate({ from: 0, to: 1, start: 9.6, end: 10.4 })(time)) * 16;

  return (
    <div style={{
      position: 'absolute',
      left: x, top: y,
      width: 720,
      opacity,
      transform: `translateY(${ty}px)`,
    }}>
      <div style={{
        fontFamily: FONTS.mono,
        fontSize: 11,
        letterSpacing: '0.22em',
        color: CTE.textMuted,
        marginBottom: 12,
      }}>
        ◆ &nbsp; OUTPUT · CLASSIFIED LEDGER ROW
      </div>
      <div style={{
        background: `${CTE.bg2}EE`,
        border: `1.5px solid ${CTE.teal}66`,
        borderRadius: 6,
        padding: '16px 20px',
        display: 'grid',
        gridTemplateColumns: '92px 80px 110px 130px 64px 1fr',
        gap: 14,
        alignItems: 'center',
        fontFamily: FONTS.mono,
        fontSize: 14,
        color: CTE.text,
        boxShadow: `0 0 32px ${CTE.teal}22`,
      }}>
        <span style={{ color: CTE.textDim, fontVariantNumeric: 'tabular-nums' }}>03/14/26</span>
        <span style={{ fontWeight: 600 }}>ETH</span>
        <span style={{ fontVariantNumeric: 'tabular-nums' }}>2.4500</span>
        <span>
          <span style={{
            color: CTE.swap,
            background: `${CTE.swap}1F`,
            border: `1px solid ${CTE.swap}55`,
            borderRadius: 3,
            padding: '4px 10px',
            fontSize: 11,
            letterSpacing: '0.14em',
          }}>SWAP · UNI v4</span>
        </span>
        <span style={{ color: CTE.ok, fontVariantNumeric: 'tabular-nums' }}>99.2%</span>
        <span style={{ color: CTE.textDim }}>Sched D · Short-term</span>
      </div>
    </div>
  );
}

Object.assign(window, { TransactionJourney });
