'use client'

import { useState, useEffect, useRef } from 'react'
import { type NodeId, type NodeDef } from './ArchitectureSlide.data'

// ── CSS keyframes (injected via <style> in main component) ───────────────────
export const CSS_KF = `
  @keyframes v4FlowDown { from { stroke-dashoffset: 0 } to { stroke-dashoffset: -18px } }
  @keyframes v4Pulse { 0%,100% { opacity:1;transform:scale(1) } 50% { opacity:.4;transform:scale(1.4) } }
  @keyframes v4Caret { 0%,50% { opacity:1 } 51%,100% { opacity:0 } }
  @keyframes v4DotFall {
    0%   { transform: translateY(-5px); opacity: 0; }
    12%  { opacity: 1; }
    88%  { opacity: 1; }
    100% { transform: translateY(38px); opacity: 0; }
  }
`

export const MONO: React.CSSProperties = {
  fontFamily: '"JetBrains Mono","SF Mono",ui-monospace,monospace',
  fontVariantNumeric: 'tabular-nums',
}

// ── Theme detection ───────────────────────────────────────────────────────────
export function useIsLight() {
  const [isLight, setIsLight] = useState(false)
  useEffect(() => {
    const check = () => setIsLight(document.documentElement.classList.contains('theme-light'))
    check()
    const obs = new MutationObserver(check)
    obs.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] })
    return () => obs.disconnect()
  }, [])
  return isLight
}

// ── Ticker primitives ─────────────────────────────────────────────────────────
function useTicker(fn: () => void, min = 140, max = 360, skipChance = 0.1) {
  const ref = useRef(fn)
  ref.current = fn
  useEffect(() => {
    let tid: ReturnType<typeof setTimeout>
    const loop = () => {
      if (Math.random() > skipChance) ref.current()
      tid = setTimeout(loop, min + Math.random() * (max - min))
    }
    loop()
    return () => clearTimeout(tid)
  }, [min, max, skipChance])
}

function TickerShell({ color, children, isLight }: { color: string; children: React.ReactNode; isLight: boolean }) {
  return (
    <div style={{
      ...MONO,
      marginTop: 7, padding: '5px 9px',
      background: isLight ? '#f1f5f9' : 'rgba(0,0,0,.38)',
      border: `1px solid ${color}${isLight ? '55' : '55'}`, borderRadius: 6,
      fontSize: 10, color: isLight ? '#475569' : 'rgba(236,233,247,.88)',
      display: 'flex', alignItems: 'center', gap: 6,
      whiteSpace: 'nowrap', overflow: 'hidden', height: 22,
    }}>{children}</div>
  )
}

function Caret({ color }: { color: string }) {
  return (
    <span style={{
      display: 'inline-block', width: 5, height: 9, marginLeft: -2,
      background: color, animation: 'v4Caret 1s step-end infinite',
    }} />
  )
}

// ── Per-node tickers ──────────────────────────────────────────────────────────
function TickCertifAI({ color, isLight }: { color: string; isLight: boolean }) {
  const [n, setN] = useState(8421)
  const [hash, setHash] = useState('9f3a…e10b')
  const pool = 'abcdef0123456789'
  const r = (k: number) => Array.from({ length: k }, () => pool[Math.floor(Math.random() * pool.length)]).join('')
  useTicker(() => { setN(v => v + 1); setHash(`${r(4)}…${r(4)}`) }, 1000, 2000, 0.1)
  return (
    <TickerShell color={color} isLight={isLight}>
      <span style={{ color: isLight ? '#16a34a' : '#4ade80' }}>✓</span>
      <span style={{ color, opacity: .85 }}>sig</span>
      <span style={{ color: isLight ? '#1a1a2e' : '#f5f3fc', fontWeight: 600 }}>{n.toLocaleString()}</span>
      <span style={{ color: isLight ? '#94a3b8' : 'rgba(236,233,247,.55)' }}>{hash}</span>
    </TickerShell>
  )
}

function TickComplAI({ color, isLight }: { color: string; isLight: boolean }) {
  const [evals, setEvals] = useState(1284)
  const [rate, setRate] = useState(99.2)
  useTicker(() => {
    setEvals(v => v + 1 + Math.floor(Math.random() * 3))
    setRate(r => Math.max(97, Math.min(99.9, r + (Math.random() - 0.5) * 0.4)))
  }, 200, 500, 0.1)
  return (
    <TickerShell color={color} isLight={isLight}>
      <span style={{ color: isLight ? '#16a34a' : '#4ade80' }}>●</span>
      <span style={{ color, opacity: .85 }}>eval</span>
      <span style={{ color: isLight ? '#1a1a2e' : '#f5f3fc', fontWeight: 600 }}>{evals.toLocaleString()}</span>
      <span style={{ color: isLight ? '#94a3b8' : 'rgba(236,233,247,.45)' }}>pass</span>
      <span style={{ color: isLight ? '#16a34a' : '#4ade80' }}>{rate.toFixed(1)}%</span>
    </TickerShell>
  )
}

function TickScanner({ color, isLight }: { color: string; isLight: boolean }) {
  const lines = [
    { k: 'PASS', c: '#16a34a', cd: '#4ade80', t: 'CWE-79 xss check' },
    { k: 'WARN', c: '#d97706', cd: '#fbbf24', t: 'drift: model v2.1→2.2' },
    { k: 'PASS', c: '#16a34a', cd: '#4ade80', t: 'bias: demographic parity' },
    { k: 'FAIL', c: '#dc2626', cd: '#f87171', t: 'license: GPL-3 detected' },
    { k: 'PASS', c: '#16a34a', cd: '#4ade80', t: 'prompt-inject: 214 vectors' },
    { k: 'SCAN', c: '#7c3aed', cd: '#a78bfa', t: 'artifact model-card.json' },
  ]
  const [i, setI] = useState(0)
  useTicker(() => setI(x => (x + 1) % lines.length), 700, 1200, 0.05)
  const l = lines[i]
  return (
    <TickerShell color={color} isLight={isLight}>
      <span style={{ color: isLight ? l.c : l.cd, fontWeight: 600, minWidth: 30 }}>{l.k}</span>
      <span style={{ color: isLight ? '#334155' : 'rgba(236,233,247,.85)', overflow: 'hidden', textOverflow: 'ellipsis', flex: 1 }}>{l.t}</span>
    </TickerShell>
  )
}

function TickLiteLLM({ color, isLight }: { color: string; isLight: boolean }) {
  const [rps, setRps] = useState(428)
  const [p50, setP50] = useState(84)
  useTicker(() => {
    setRps(v => Math.max(200, Math.min(800, v + (Math.random() - 0.5) * 60)))
    setP50(v => Math.max(40, Math.min(160, v + (Math.random() - 0.5) * 20)))
  }, 250, 500, 0.05)
  return (
    <TickerShell color={color} isLight={isLight}>
      <span style={{ color: '#d97706' }}>⚡</span>
      <span style={{ color, opacity: .9 }}>req/s</span>
      <span style={{ color: isLight ? '#1a1a2e' : '#f5f3fc', fontWeight: 600 }}>{Math.round(rps)}</span>
      <span style={{ color: isLight ? '#94a3b8' : 'rgba(236,233,247,.4)' }}>·</span>
      <span style={{ color, opacity: .9 }}>p50</span>
      <span style={{ color: isLight ? '#1a1a2e' : '#f5f3fc', fontWeight: 600 }}>{Math.round(p50)}ms</span>
      <Caret color={color} />
    </TickerShell>
  )
}

function TickLLM({ color, isLight }: { color: string; isLight: boolean }) {
  const [tokens, setTokens] = useState(14832)
  const [stream, setStream] = useState('t_a91f')
  const pool = 'abcdef0123456789'
  useTicker(() => {
    setTokens(v => v + 1 + Math.floor(Math.random() * 5))
    setStream('t_' + Array.from({ length: 4 }, () => pool[Math.floor(Math.random() * pool.length)]).join(''))
  }, 120, 340, 0.15)
  return (
    <TickerShell color={color} isLight={isLight}>
      <span style={{ color: isLight ? '#16a34a' : '#4ade80' }}>●</span>
      <span style={{ color, opacity: .85 }}>tok</span>
      <span style={{ color: isLight ? '#1a1a2e' : '#f5f3fc', fontWeight: 600 }}>{tokens.toLocaleString()}</span>
      <span style={{ color: isLight ? '#94a3b8' : 'rgba(236,233,247,.35)' }}>↑</span>
      <span style={{ color }}>{stream}</span>
      <Caret color={color} />
    </TickerShell>
  )
}

function TickEmbeddings({ color, isLight }: { color: string; isLight: boolean }) {
  const [vecs, setVecs] = useState(284112)
  useTicker(() => setVecs(v => v + 1 + Math.floor(Math.random() * 8)), 180, 420, 0.1)
  return (
    <TickerShell color={color} isLight={isLight}>
      <span style={{ color: isLight ? '#16a34a' : '#4ade80' }}>●</span>
      <span style={{ color, opacity: .85 }}>idx</span>
      <span style={{ color: isLight ? '#1a1a2e' : '#f5f3fc', fontWeight: 600 }}>{vecs.toLocaleString()}</span>
      <span style={{ color: isLight ? '#94a3b8' : 'rgba(236,233,247,.4)' }}>· 1024d</span>
      <Caret color={color} />
    </TickerShell>
  )
}

function TickTools({ color, isLight }: { color: string; isLight: boolean }) {
  const ops = [
    'search("BSI C5 controls")', 'fetch eur-lex.europa.eu',
    'grep -r "DSGVO"', 'read docs/policy.md',
    'mcp.call(filesystem)', 'search("vLLM 0.6 release")',
  ]
  const [i, setI] = useState(0)
  useTicker(() => setI(x => (x + 1) % ops.length), 900, 1600, 0.05)
  return (
    <TickerShell color={color} isLight={isLight}>
      <span style={{ color: isLight ? '#16a34a' : '#4ade80' }}>●</span>
      <span style={{ color, opacity: .85 }}>call</span>
      <span style={{ color: isLight ? '#334155' : '#f5f3fc', overflow: 'hidden', textOverflow: 'ellipsis', flex: 1 }}>{ops[i]}</span>
    </TickerShell>
  )
}

export const NODE_TICKER: Record<NodeId, React.ComponentType<{ color: string; isLight: boolean }>> = {
  certifai: TickCertifAI,
  complai: TickComplAI,
  scanner: TickScanner,
  litellm: TickLiteLLM,
  llm: TickLLM,
  embeddings: TickEmbeddings,
  tools: TickTools,
}

// ── Animated connector ────────────────────────────────────────────────────────
export function LayerConnector({ tint }: { tint: string }) {
  const tracks = [
    { x: '32%', primary: false },
    { x: '50%', primary: true  },
    { x: '68%', primary: false },
  ]
  return (
    <div style={{ position: 'relative', height: 34, width: '100%', maxWidth: 960, margin: '0 auto' }}>
      {tracks.map(({ x, primary }, ti) => {
        const color = primary ? '#fbbf24' : tint
        const dots = primary ? 4 : 3
        const dur = primary ? 1.6 : 2.4
        return (
          <div key={ti} style={{ position: 'absolute', left: x, top: 0, bottom: 0, transform: 'translateX(-50%)' }}>
            <div style={{
              position: 'absolute', left: -0.75, top: 0, bottom: 0, width: 1.5,
              background: `linear-gradient(180deg, ${color}00, ${color}55 40%, ${color}55 60%, ${color}00)`,
            }} />
            {Array.from({ length: dots }, (_, j) => (
              <div key={j} style={{
                position: 'absolute', top: 0, left: -3, width: 6, height: 6, borderRadius: '50%',
                background: color, boxShadow: `0 0 7px ${color}`,
                animation: `v4DotFall ${dur}s ${-(j / dots) * dur}s linear infinite`,
              }} />
            ))}
          </div>
        )
      })}
    </div>
  )
}

// ── Node card ─────────────────────────────────────────────────────────────────
export function NodeCard({ node, selected, onClick, isLight }: {
  node: NodeDef; selected: boolean; onClick: () => void; isLight: boolean
}) {
  const [hover, setHover] = useState(false)
  const active = hover || selected
  const c = node.color
  const Ticker = NODE_TICKER[node.id]
  const Icon = node.icon

  return (
    <button
      onClick={onClick}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        flex: 1,
        background: active
          ? `linear-gradient(180deg, ${c}${isLight ? '20' : '33'}, ${c}${isLight ? '0a' : '12'})`
          : isLight
            ? 'linear-gradient(180deg, #ffffff, #f8fafc)'
            : 'linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.015))',
        border: `1px solid ${active ? c : isLight ? 'rgba(0,0,0,.1)' : 'rgba(255,255,255,.14)'}`,
        borderRadius: 12, padding: '12px 14px',
        cursor: 'pointer', textAlign: 'left',
        color: isLight ? '#1a1a2e' : '#ece9f7', fontFamily: 'inherit',
        display: 'flex', flexDirection: 'column',
        transition: 'all .2s ease',
        transform: active ? 'translateY(-1px)' : 'none',
        boxShadow: active
          ? `0 8px 26px ${c}44, 0 0 0 4px ${c}14`
          : isLight ? '0 1px 4px rgba(0,0,0,.06)' : '0 1px 0 rgba(255,255,255,.04)',
        minWidth: 0, position: 'relative',
      }}
    >
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{
          width: 36, height: 36, borderRadius: 10, flexShrink: 0,
          background: `linear-gradient(135deg, ${c}3a, ${c}10)`,
          border: `1px solid ${c}66`,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: c,
          boxShadow: node.primary ? `inset 0 0 14px ${c}40` : 'none',
        }}>
          <Icon style={{ width: 18, height: 18 }} />
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{
            fontSize: 13, fontWeight: 600,
            color: isLight ? '#1a1a2e' : '#f7f5fc',
            letterSpacing: -0.1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
          }}>{node.title}</div>
          <div style={{
            fontSize: 10.5,
            color: isLight ? '#64748b' : 'rgba(236,233,247,.65)',
            marginTop: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
          }}>{node.subtitle}</div>
        </div>
      </div>
      <Ticker color={c} isLight={isLight} />
      {node.primary && (
        <div style={{
          position: 'absolute', top: -1, right: -1,
          width: 6, height: 6, borderRadius: '50%',
          background: '#fbbf24', boxShadow: '0 0 8px #fbbf24',
          animation: 'v4Pulse 1.6s ease-in-out infinite',
        }} />
      )}
    </button>
  )
}

// ── 3D slab ───────────────────────────────────────────────────────────────────
export function LayerSlab({ label, sublabel, nodes, tint, depth, selectedId, onSelect, isLight }: {
  label: string; sublabel: string; nodes: NodeDef[]
  tint: string; depth: number
  selectedId: NodeId | null; onSelect: (id: NodeId) => void
  isLight: boolean
}) {
  const isProxy = nodes.length === 1 && !!nodes[0].primary
  return (
    <div style={{
      position: 'relative', margin: '0 auto',
      padding: '14px 20px 18px', width: '100%', maxWidth: 960,
      background: isLight
        ? `linear-gradient(180deg, ${tint}18 0%, ${tint}08 60%, rgba(248,250,252,.98) 100%)`
        : `linear-gradient(180deg, ${tint}26 0%, ${tint}12 60%, rgba(14,8,28,.85) 100%)`,
      border: `1px solid ${tint}${isLight ? '44' : '66'}`,
      borderRadius: 16,
      boxShadow: isLight
        ? `0 -2px 16px ${tint}18, 0 8px 30px rgba(0,0,0,.05), inset 0 1px 0 ${tint}44`
        : `0 -6px 30px ${tint}22, 0 24px 60px rgba(0,0,0,.6), inset 0 1px 0 ${tint}55, inset 0 -1px 0 rgba(0,0,0,.4)`,
      transform: `perspective(2000px) rotateX(12deg) translateZ(${depth}px)`,
    }}>
      <div style={{
        position: 'absolute', top: 0, left: 20, right: 20, height: 1,
        background: `linear-gradient(90deg, transparent, ${tint}${isLight ? 'aa' : 'cc'}, transparent)`,
        pointerEvents: 'none',
      }} />
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10 }}>
        <div style={{
          fontSize: 9.5, letterSpacing: 2, textTransform: 'uppercase' as const, fontWeight: 600,
          color: tint,
          background: isLight ? `${tint}18` : `${tint}20`,
          padding: '3px 9px', borderRadius: 99,
          border: `1px solid ${tint}${isLight ? '44' : '50'}`, whiteSpace: 'nowrap',
        }}>{label}</div>
        <div style={{
          fontSize: 11,
          color: isLight ? '#64748b' : 'rgba(236,233,247,.55)',
          whiteSpace: 'nowrap',
        }}>{sublabel}</div>
      </div>
      <div style={{ display: 'flex', gap: 10, justifyContent: isProxy ? 'center' : undefined }}>
        {isProxy ? (
          <div style={{ width: '42%', minWidth: 260, display: 'flex' }}>
            <NodeCard node={nodes[0]} selected={selectedId === nodes[0].id} onClick={() => onSelect(nodes[0].id)} isLight={isLight} />
          </div>
        ) : (
          nodes.map(n => (
            <NodeCard key={n.id} node={n} selected={selectedId === n.id} onClick={() => onSelect(n.id)} isLight={isLight} />
          ))
        )}
      </div>
    </div>
  )
}
