/* ════════════════════════════════════════════════════════════════════
   QCM⁵ GENESIS — cinematic reveal · shared visual library
   Palettes, atom seal, starfield, engine fields, holo cards, hash stream.
   All components read the timeline via useTime() or take `t` props.
   Exports to window at end.
   ════════════════════════════════════════════════════════════════════ */

const PALETTES = {
  astrophysics:     { bg0:"#1a0a3d", bg1:"#06030f", a:"#ff6b00", b:"#7b2fff", c:"#ffd76a", glow:"#ffae5c", label:"MACRO · RATES DESK" },
  complexity:       { bg0:"#0a2a2a", bg1:"#03100b", a:"#00ff88", b:"#00ffff", c:"#4dffc4", glow:"#4dffc4", label:"VOLATILITY ARBITRAGE DESK" },
  "condensed-matter":{ bg0:"#1a1a2e", bg1:"#070710", a:"#ffb000", b:"#0044ff", c:"#e5e5e5", glow:"#ffd27a", label:"STRUCTURED PRODUCTS DESK" },
  electromagnetics: { bg0:"#06121f", bg1:"#01050c", a:"#18e0ff", b:"#ff2d9b", c:"#ffd76a", glow:"#6cf3ff", label:"EXOTIC OPTIONS DESK" },
};
const DESK_BY_ENGINE = { complexity:"vol-arb", astrophysics:"macro", "condensed-matter":"structured", electromagnetics:"exotic" };
const TIER_RANK = { "Quantum Seeker":{ label:"JUNIOR",    col:"#3366ff" },
                    "Quantum Explorer":{ label:"MID",     col:"#8800cc" },
                    "Quantum Pioneer":{ label:"SENIOR",   col:"#cc8800" },
                    "Quantum Founder":{ label:"PRINCIPAL",col:"#ff0044" } };
const GOLD = "#f3d585";

// deterministic PRNG
function mulberry(seed){ let a=seed>>>0; return function(){ a|=0; a=a+0x6D2B79F5|0; let t=Math.imul(a^a>>>15,1|a); t=t+Math.imul(t^t>>>7,61|t)^t; return ((t^t>>>14)>>>0)/4294967296; }; }
const hexCh = "0123456789abcdef";
function hexStr(rnd,len){ let s=""; for(let i=0;i<len;i++) s+=hexCh[Math.floor(rnd()*16)]; return s; }

// ── Atom seal ──────────────────────────────────────────────────────────────
// draw: 0..1 stroke-on reveal · spin: degrees · electrons: show orbiting dots
function AtomSeal({ size=300, color=GOLD, draw=1, spin=0, glow=0.6, electrons=true, t=0 }){
  const off = (v)=>String(1 - clamp(v,0,1));
  const ringDraws = [
    clamp(draw*1.4,0,1), clamp(draw*1.4-0.1,0,1), clamp(draw*1.4-0.2,0,1)
  ];
  const ell = [0,60,120];
  const e3 = ell.map((deg,i)=>{
    const ang = (t*0.6 + i/3)*Math.PI*2;
    // electron travels along ellipse rx17 ry6.4 rotated by deg
    const lx = Math.cos(ang)*17, ly = Math.sin(ang)*6.4;
    const rad = deg*Math.PI/180;
    const x = 50 + lx*Math.cos(rad) - ly*Math.sin(rad);
    const y = 50 + lx*Math.sin(rad) + ly*Math.cos(rad);
    return {x,y};
  });
  return (
    <svg viewBox="0 0 100 100" width={size} height={size} style={{ overflow:"visible", filter:`drop-shadow(0 0 ${10*glow}px ${color}) drop-shadow(0 0 ${28*glow}px ${color})` }}>
      <g style={{ transformOrigin:"50px 50px", transform:`rotate(${spin}deg)` }}>
        <g fill="none" stroke={color} strokeWidth="0.8" pathLength="1"
           strokeDasharray="1" >
          <circle cx="50" cy="50" r="46" strokeDashoffset={off(ringDraws[0])} opacity="0.85"/>
          <circle cx="50" cy="50" r="40" strokeDashoffset={off(ringDraws[1])} opacity="0.5"/>
          <circle cx="50" cy="50" r="25" strokeDashoffset={off(ringDraws[2])} opacity="0.7"/>
        </g>
        <g fill="none" stroke={color} strokeWidth="1.2" pathLength="1" strokeDasharray="1">
          <ellipse cx="50" cy="50" rx="17" ry="6.4" strokeDashoffset={off(clamp(draw*1.6-0.3,0,1))} transform="rotate(0 50 50)"/>
          <ellipse cx="50" cy="50" rx="17" ry="6.4" strokeDashoffset={off(clamp(draw*1.6-0.45,0,1))} transform="rotate(60 50 50)"/>
          <ellipse cx="50" cy="50" rx="17" ry="6.4" strokeDashoffset={off(clamp(draw*1.6-0.6,0,1))} transform="rotate(120 50 50)"/>
        </g>
      </g>
      {electrons && draw>0.85 && e3.map((p,i)=>(
        <circle key={i} cx={p.x} cy={p.y} r="2.1" fill={color} style={{ filter:`drop-shadow(0 0 4px ${color})` }}/>
      ))}
      <circle cx="50" cy="50" r={3.2*clamp(draw*2,0,1)} fill={color} style={{ filter:`drop-shadow(0 0 6px ${color})` }}/>
    </svg>
  );
}

// ── Starfield ────────────────────────────────────────────────────────────────
function Starfield({ count=140, seed=7, color="#ffffff", t=0, drift=14, twinkle=true, depth=1 }){
  const stars = React.useMemo(()=>{
    const r = mulberry(seed); const arr=[];
    for(let i=0;i<count;i++){ arr.push({ x:r()*100, y:r()*100, s:0.5+r()*2.2, ph:r()*Math.PI*2, sp:0.4+r()*1.4, z:0.3+r()*1 }); }
    return arr;
  },[count,seed]);
  return (
    <div style={{ position:"absolute", inset:0, overflow:"hidden" }}>
      {stars.map((st,i)=>{
        const tw = twinkle ? 0.4+0.6*Math.abs(Math.sin(t*st.sp+st.ph)) : 0.85;
        const yy = (st.y + t*drift*st.z*depth) % 105;
        return <div key={i} style={{ position:"absolute", left:st.x+"%", top:yy+"%", width:st.s*st.z, height:st.s*st.z, borderRadius:"50%", background:color, opacity:tw*0.9, boxShadow:`0 0 ${st.s*2}px ${color}` }}/>;
      })}
    </div>
  );
}

// ── Engine field background ──────────────────────────────────────────────────
function EngineField({ engine="astrophysics", t=0, intensity=1 }){
  const p = PALETTES[engine];
  const rot = t*6;
  return (
    <div style={{ position:"absolute", inset:0, overflow:"hidden", background:`radial-gradient(ellipse 120% 90% at 50% 38%, ${p.bg0} 0%, ${p.bg1} 62%, #000 100%)` }}>
      {/* drifting nebula blooms */}
      <div style={{ position:"absolute", inset:"-20%",
        background:`radial-gradient(circle at ${30+8*Math.sin(t*0.3)}% ${40+6*Math.cos(t*0.24)}%, ${p.a}22 0%, transparent 34%),
                    radial-gradient(circle at ${72+7*Math.cos(t*0.21)}% ${58+6*Math.sin(t*0.27)}%, ${p.b}22 0%, transparent 38%),
                    radial-gradient(circle at 50% 80%, ${p.glow}18 0%, transparent 46%)`,
        filter:"blur(8px)", opacity:intensity, mixBlendMode:"screen" }}/>
      {/* slow conic shimmer */}
      <div style={{ position:"absolute", inset:"-30%", transformOrigin:"50% 50%", transform:`rotate(${rot}deg)`,
        background:`conic-gradient(from 0deg at 50% 50%, transparent 0deg, ${p.a}10 60deg, transparent 140deg, ${p.b}10 240deg, transparent 320deg)`,
        mixBlendMode:"screen", opacity:0.6*intensity }}/>
    </div>
  );
}

// ── Hash stream (faint streaming hex columns) ────────────────────────────────
function HashStream({ t=0, color="#ffffff", opacity=0.10, cols=18, seed=3 }){
  const data = React.useMemo(()=>{
    const r = mulberry(seed); const arr=[];
    for(let i=0;i<cols;i++){ const rows=[]; for(let j=0;j<14;j++) rows.push(hexStr(r,8)); arr.push({ x:(i+0.5)/cols*100, sp:0.3+r()*0.7, rows, off:r()*100 }); }
    return arr;
  },[cols,seed]);
  return (
    <div style={{ position:"absolute", inset:0, overflow:"hidden", opacity, fontFamily:'"Space Mono", monospace', fontSize:12, color, letterSpacing:"0.1em" }}>
      {data.map((c,i)=>{
        const yy = ((c.off - t*c.sp*8) % 110 + 110) % 110;
        return (
          <div key={i} style={{ position:"absolute", left:c.x+"%", top:-yy+"%", transform:"translateX(-50%)", lineHeight:1.7, whiteSpace:"nowrap", textAlign:"center" }}>
            {c.rows.map((h,j)=><div key={j} style={{ opacity: j===0?1:(1-j/16) }}>{h}</div>)}
          </div>
        );
      })}
    </div>
  );
}

// ── Holographic card ─────────────────────────────────────────────────────────
// card: {art,name,tokenLabel,agentId,engine,tier,rarity,seal}
// foil: 0..1 sweep position (>1 = past). caption: show name plate.
function HoloCard({ card, w=300, foil=-1, caption=true, glow=0.5, chrome=true }){
  const h = w*1.42;
  const p = PALETTES[card.engine] || PALETTES.astrophysics;
  const tier = TIER_RANK[card.tier] || { label:card.tier||"", col:"#3366ff" };
  return (
    <div style={{ position:"relative", width:w, height:h, borderRadius:w*0.05, overflow:"hidden",
      boxShadow:`0 ${w*0.08}px ${w*0.16}px rgba(0,0,0,0.7), 0 0 ${w*0.12*glow}px ${p.glow}${glow>0.4?"55":"22"}`,
      background:"#05060a", outline: chrome?`1.5px solid rgba(255,255,255,0.18)`:"none", outlineOffset:-1 }}>
      {card.art
        ? <img src={card.art} alt="" style={{ position:"absolute", inset:0, width:"100%", height:"100%", objectFit:"cover", display:"block" }}/>
        : <div style={{ position:"absolute", inset:0, background:`radial-gradient(circle at 50% 40%, ${p.bg0}, ${p.bg1})` }}/>}
      {/* chrome bezel light */}
      {chrome && <div style={{ position:"absolute", inset:0, borderRadius:w*0.05, pointerEvents:"none",
        background:"linear-gradient(135deg, rgba(255,255,255,0.30) 0%, transparent 18%, transparent 82%, rgba(255,255,255,0.16) 100%)", mixBlendMode:"screen" }}/>}
      {/* foil sweep */}
      {foil>=0 && foil<=1 && (
        <div style={{ position:"absolute", top:0, bottom:0, left:`${-40+foil*180}%`, width:"55%",
          background:"linear-gradient(105deg, transparent, rgba(255,120,200,0.35), rgba(120,200,255,0.40), rgba(150,255,180,0.30), transparent)",
          mixBlendMode:"screen", filter:"blur(2px)", transform:"skewX(-12deg)" }}/>
      )}
      {/* top wordmark */}
      <div style={{ position:"absolute", top:w*0.05, left:w*0.06, fontFamily:'"Space Grotesk",sans-serif', fontWeight:700, fontSize:w*0.058, letterSpacing:"0.04em", color:"#fff", textShadow:"0 2px 8px rgba(0,0,0,0.8)" }}>
        QCM<sup style={{ fontSize:"0.6em" }}>5</sup>
      </div>
      {/* caption plate */}
      {caption && (
        <div style={{ position:"absolute", left:0, right:0, bottom:0, padding:`${w*0.14}px ${w*0.06}px ${w*0.05}px`,
          background:"linear-gradient(to top, rgba(4,5,9,0.96) 32%, rgba(4,5,9,0.5) 72%, transparent)" }}>
          <div style={{ fontFamily:'"Cormorant Garamond",serif', fontWeight:600, fontSize:w*0.108, lineHeight:0.96, color:"#f5f3ef", marginBottom:w*0.02 }}>{card.name}</div>
          <div style={{ display:"flex", alignItems:"flex-end", justifyContent:"space-between", gap:8 }}>
            <div style={{ fontFamily:'"Space Mono",monospace', fontSize:w*0.04, letterSpacing:"0.1em", color:"rgba(245,243,239,0.55)" }}>{card.agentId}</div>
            <div style={{ display:"flex", alignItems:"center", gap:w*0.03, flexShrink:0 }}>
              <div style={{ fontFamily:'"Space Grotesk",sans-serif', fontWeight:600, fontSize:w*0.032, letterSpacing:"0.14em", color:tier.col, textTransform:"uppercase" }}>{tier.label} · R:{card.rarity}</div>
              <div style={{ fontFamily:'"Space Mono",monospace', fontWeight:700, fontSize:w*0.082, color:p.a, textShadow:`0 0 10px ${p.a}88` }}>#{card.tokenLabel}</div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ── Utility overlays ─────────────────────────────────────────────────────────
function Vignette({ strength=0.6 }){
  return <div style={{ position:"absolute", inset:0, pointerEvents:"none",
    background:`radial-gradient(ellipse 80% 70% at 50% 46%, transparent 40%, rgba(0,0,0,${strength}) 100%)` }}/>;
}
function Grain({ opacity=0.05 }){
  return <div style={{ position:"absolute", inset:0, pointerEvents:"none", opacity, mixBlendMode:"overlay",
    backgroundImage:"url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E\")" }}/>;
}

// ── Slash overlay — liquidation mark for a card ───────────────────────────
function SlashOverlay({ progress=1, pnl="-$2.4M", reason="LIQUIDATED" }){
  if(progress<=0) return null;
  const p = clamp(progress,0,1);
  return (
    <div style={{ position:"absolute", inset:0, pointerEvents:"none", overflow:"hidden" }}>
      {/* red wash */}
      <div style={{ position:"absolute", inset:0, background:"linear-gradient(135deg, rgba(255,32,48,0.0) 0%, rgba(255,32,48,0.55) 100%)", opacity:p*0.7, mixBlendMode:"multiply" }}/>
      {/* the slash stroke — draws across diagonally */}
      <svg viewBox="0 0 100 142" preserveAspectRatio="none" style={{ position:"absolute", inset:0, width:"100%", height:"100%" }}>
        <defs>
          <linearGradient id="slashG" x1="0" y1="0" x2="1" y2="1">
            <stop offset="0%"  stopColor="#ff1530"/>
            <stop offset="50%" stopColor="#ff5060"/>
            <stop offset="100%" stopColor="#ff1530"/>
          </linearGradient>
        </defs>
        <line x1="-8" y1="148" x2="108" y2="-8" stroke="url(#slashG)" strokeWidth="5" pathLength="1" strokeDasharray="1" strokeDashoffset={1-p} style={{ filter:"drop-shadow(0 0 6px #ff2040) drop-shadow(0 0 14px #ff2040)" }}/>
      </svg>
      {/* badge */}
      <div style={{ position:"absolute", top:"30%", left:"50%", transform:`translate(-50%,-50%) rotate(-12deg) scale(${0.6+0.4*p})`, opacity:p, textAlign:"center" }}>
        <div style={{ fontFamily:'"Space Grotesk",sans-serif', fontWeight:800, fontSize:36, letterSpacing:"0.16em", color:"#fff", textShadow:"0 0 12px #ff0030, 0 2px 8px rgba(0,0,0,0.6)", border:"3px solid #ff2040", padding:"6px 14px", background:"rgba(60,0,8,0.55)", whiteSpace:"nowrap" }}>{reason}</div>
        <div style={{ fontFamily:'"Space Mono",monospace', fontWeight:700, fontSize:32, color:"#ff3050", marginTop:8, textShadow:"0 0 10px #ff0030" }}>{pnl}</div>
      </div>
    </div>
  );
}

// ── Ticker tape — scrolling stock-ticker strip ────────────────────────────
function TickerTape({ t=0, items=[], speed=70, color="#9bff9b", height=34 }){
  // items: [{sym,price,delta}]
  const total = items.length;
  const offset = (t*speed) % (total*220);
  return (
    <div style={{ position:"absolute", left:0, right:0, height, overflow:"hidden", background:"rgba(0,0,0,0.55)", borderTop:"1px solid rgba(255,255,255,0.08)", borderBottom:"1px solid rgba(255,255,255,0.08)" }}>
      <div style={{ position:"absolute", top:0, left:-offset, height:"100%", display:"flex", alignItems:"center", whiteSpace:"nowrap", fontFamily:'"Space Mono",monospace', fontSize:14, letterSpacing:"0.08em" }}>
        {[...items,...items,...items].map((it,i)=>(
          <span key={i} style={{ marginRight:36, display:"inline-flex", alignItems:"center", gap:10 }}>
            <span style={{ color:"#fff", fontWeight:700 }}>{it.sym}</span>
            <span style={{ color:"rgba(255,255,255,0.7)" }}>{it.price}</span>
            <span style={{ color: it.delta.startsWith("-") ? "#ff4060" : color, fontWeight:700 }}>{it.delta}</span>
          </span>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { PALETTES, GOLD, DESK_BY_ENGINE, TIER_RANK, mulberry, hexStr, AtomSeal, Starfield, EngineField, HashStream, HoloCard, Vignette, Grain, SlashOverlay, TickerTape });
