// hanc-ui.jsx — primitives that mirror the real HANC Scenario Architect UI.
// All styling inline (survives video-export serialization). Reads timeline
// globals from animations.jsx (Sprite/useSprite/Easing/interpolate).

// ── Theme (verbatim from public/index.html :root) ───────────────────────────
const T = {
  bg:'#140e09', surface:'#231a10', surface2:'#2d2213', surface3:'#3a2c1a',
  border:'#43331f', border2:'#5a4529',
  text:'#f5eee4', muted:'#bcac97', faint:'#8a7d6c',
  accent:'#ff7a2e', accent2:'#ffb072',
  ok:'#5fd39a', err:'#ff7b7b', info:'#8fb9ff', user:'#e88a44',
};
const UI_FONT = '"Manrope", system-ui, -apple-system, sans-serif';
const DISPLAY_FONT = UI_FONT;
const MONO = 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace';
const STAGE_BG =
  'radial-gradient(1100px 560px at 86% -12%, rgba(255,122,46,.20), transparent 60%),'+
  'radial-gradient(820px 520px at -8% 112%, rgba(255,140,60,.10), transparent 55%),'+
  'linear-gradient(155deg,#1e160d 0%,#140e09 60%,#0d0906 100%)';

const ease = (a,b,t)=>a+(b-a)*t;
const clamp01 = (v)=>Math.max(0,Math.min(1,v));

// progress of a step in [s,e] given local time lt, eased
function seg(lt, s, e, easeFn){
  const f = clamp01((lt - s) / Math.max(0.0001, e - s));
  return (easeFn||Easing.easeInOutCubic)(f);
}

// ── Logo ────────────────────────────────────────────────────────────────────
function Logo({ h = 30, style }) {
  return <div style={{ display:'flex', alignItems:'center', gap: h*0.30, ...style }}>
    <img src="hanc-mark.svg" alt="" style={{ height: h, display:'block', filter:'drop-shadow(0 3px 12px rgba(255,122,46,.45))' }} />
    <span style={{ fontFamily: UI_FONT, fontWeight:800, fontSize: h*0.82, letterSpacing:'-.02em', color: T.text }}>HANC Studio</span>
    <span style={{ fontFamily: UI_FONT, fontWeight:700, fontSize: h*0.30, lineHeight:1, letterSpacing:'.08em', textTransform:'uppercase', color:'#20140a', background:T.accent, padding:`${h*0.10}px ${h*0.22}px`, borderRadius:30 }}>beta</span>
  </div>;
}

// ── Animated mouse cursor ────────────────────────────────────────────────────
// frames: [{t,x,y}] in LOCAL seconds; clicks: [t,...] local seconds.
function Cursor({ frames, clicks = [], z = 9000 }) {
  const { localTime: lt } = useSprite();
  const xs = frames.map(f=>f.t);
  const x = interpolate(xs, frames.map(f=>f.x), Easing.easeInOutCubic)(lt);
  const y = interpolate(xs, frames.map(f=>f.y), Easing.easeInOutCubic)(lt);
  // click ring
  let ring = null, press = 1;
  for (const c of clicks) {
    const d = lt - c;
    if (d >= -0.06 && d <= 0.5) {
      const p = clamp01(d / 0.5);
      ring = <div style={{ position:'absolute', left:x, top:y, width:0, height:0 }}>
        <div style={{ position:'absolute', left:-3, top:-3,
          width: ease(8, 54, p), height: ease(8, 54, p),
          marginLeft:-ease(8,54,p)/2+4, marginTop:-ease(8,54,p)/2+4,
          border:`2px solid ${T.accent}`, borderRadius:'50%', opacity: 1-p }} />
      </div>;
      if (d >= 0 && d < 0.12) press = 0.86;
    }
  }
  return (
    <div style={{ position:'absolute', inset:0, pointerEvents:'none', zIndex:z }}>
      {ring}
      <div style={{ position:'absolute', left:x, top:y, transform:`scale(${press})`, transformOrigin:'top left',
        filter:'drop-shadow(0 2px 4px rgba(0,0,0,.5))' }}>
        <svg width="26" height="26" viewBox="0 0 24 24">
          <path d="M4 2 L4 19 L9 14.5 L12.2 21.5 L15 20.2 L11.8 13.2 L18.5 13 Z"
            fill="#fff" stroke="#0d0f14" strokeWidth="1.4" strokeLinejoin="round" />
        </svg>
      </div>
    </div>
  );
}

// ── Lower-third caption ──────────────────────────────────────────────────────
function Caption({ kicker, text, lt, start, end }) {
  const a = seg(lt, start, start+0.4, Easing.easeOutCubic);
  const o = end!=null ? a * (1 - seg(lt, end-0.35, end, Easing.easeInCubic)) : a;
  return (
    <div style={{ position:'absolute', left:60, bottom:54, opacity:o,
      transform:`translateY(${(1-a)*14}px)`, maxWidth:900, zIndex:8000 }}>
      <div style={{ display:'inline-flex', alignItems:'center', gap:10, marginBottom:12 }}>
        {kicker!=null && <span style={{ display:'inline-flex', alignItems:'center', height:30, padding:'0 13px',
          borderRadius:8, background:T.accent, color:'#fff', fontFamily:MONO, fontSize:14, fontWeight:600,
          letterSpacing:'.02em' }}>{kicker}</span>}
      </div>
      <div style={{ fontFamily:UI_FONT, fontSize:30, fontWeight:600, color:T.text, lineHeight:1.25,
        letterSpacing:'-.01em', textShadow:'0 2px 18px rgba(0,0,0,.6)' }}>{text}</div>
    </div>
  );
}

// ── Form atoms (match .field / .btn / .seg / .chip) ──────────────────────────
function Field({ label, hint, children, value, ph, w='100%', focus=false, help=false }) {
  return (
    <div style={{ width:w }}>
      {label!=null && <div style={{ display:'flex', alignItems:'center', gap:7, marginBottom:2 }}>
        <span style={{ fontSize:15, fontWeight:600, color:T.text }}>{label}</span>
        {help && <span style={{ width:17, height:17, borderRadius:'50%', border:`1px solid ${T.border2}`,
          color:T.faint, fontSize:11, display:'inline-flex', alignItems:'center', justifyContent:'center' }}>?</span>}
      </div>}
      {hint!=null && <div style={{ fontSize:12.5, color:T.muted, marginBottom:7 }}>{hint}</div>}
      {children!=null ? children : (
        <div style={{ height:46, borderRadius:8, background:T.surface2,
          border:`1px solid ${focus?T.accent:T.border}`, display:'flex', alignItems:'center',
          padding:'0 13px', fontSize:15, color: value? T.text : T.faint, transition:'border-color .1s' }}>
          {value || ph}{focus && <Caret />}
        </div>
      )}
    </div>
  );
}
function Caret(){ const lt = useSprite().localTime; const on = Math.floor(lt*1.8)%2===0;
  return <span style={{ display:'inline-block', width:2, height:19, marginLeft:1,
    background:T.accent, opacity:on?1:0, verticalAlign:'-3px' }} />; }

function Btn({ children, primary, big, ghost, w, on }) {
  const bg = primary||on ? T.accent : ghost ? 'transparent' : T.surface2;
  return <div style={{ height: big?52:40, padding:`0 ${big?20:14}px`, borderRadius:8,
    background:bg, border:`1px solid ${primary||on?'transparent':T.border}`,
    color: primary||on?'#fff':T.text, fontWeight: primary?600:500, fontSize: big?16:13.5,
    display:'inline-flex', alignItems:'center', justifyContent:'center', gap:8, width:w,
    fontFamily:UI_FONT, whiteSpace:'nowrap' }}>{children}</div>;
}

function Seg({ items, active }) {
  return <div style={{ display:'inline-flex', background:T.surface2, border:`1px solid ${T.border}`,
    borderRadius:8, padding:3, gap:2 }}>
    {items.map((it,i)=>(
      <div key={i} style={{ height:30, padding:'0 14px', borderRadius:6, display:'flex', alignItems:'center',
        fontSize:13, fontWeight: i===active?600:500, background:i===active?T.accent:'transparent',
        color:i===active?'#fff':T.muted }}>{it}</div>
    ))}
  </div>;
}

function Chip({ children, on, round=true }) {
  return <div style={{ height:36, padding:'0 15px', borderRadius: round?20:8,
    border:`1px solid ${on?T.accent:T.border}`, background:on?'rgba(255,106,26,.12)':T.surface2,
    color:on?T.accent2:T.text, fontSize:13, display:'inline-flex', alignItems:'center', gap:7,
    fontFamily:UI_FONT }}>{children}</div>;
}

// ── Card shell ───────────────────────────────────────────────────────────────
function Card({ x, y, w, h, children, pad=0, style }) {
  return <div style={{ position:'absolute', left:x, top:y, width:w, height:h, padding:pad,
    background:T.surface, border:`1px solid ${T.border}`, borderRadius:16,
    boxShadow:'0 30px 90px rgba(0,0,0,.5)', overflow:'hidden', ...style }}>{children}</div>;
}

// ── Graph node + edge (workflow builder) ─────────────────────────────────────
function gNodeStyle(kind){
  if (kind==='term') return { bg:T.surface3, bd:T.border2, tc:T.text, radius:26 };
  if (kind==='decide') return { bg:'rgba(255,106,26,.10)', bd:T.accent, tc:T.accent2, radius:12 };
  return { bg:'rgba(59,108,255,.10)', bd:'#3b6cff', tc:'#a9c2ff', radius:12 };
}
function GNode({ x, y, w, h, label, kind='step', appear=1 }) {
  const s = gNodeStyle(kind);
  return <div style={{ position:'absolute', left:x, top:y, width:w, height:h,
    background:s.bg, border:`1.5px solid ${s.bd}`, borderRadius:s.radius,
    display:'flex', alignItems:'center', justifyContent:'center', textAlign:'center',
    color:s.tc, fontSize:15, fontWeight:600, fontFamily:UI_FONT, padding:'0 14px',
    opacity:appear, transform:`scale(${ease(.88,1,appear)})`, transformOrigin:'center',
    boxShadow: appear>0.5 ? '0 6px 22px rgba(0,0,0,.35)':'none' }}>{label}</div>;
}
function Edge({ x1, y1, x2, y2, appear=1, label }) {
  const ang = Math.atan2(y2-y1, x2-x1)*180/Math.PI;
  const len = Math.hypot(x2-x1,y2-y1)*appear;
  return <div style={{ position:'absolute', left:x1, top:y1, width:len, height:2,
    background:T.border2, transform:`rotate(${ang}deg)`, transformOrigin:'0 50%', opacity:appear }}>
    <div style={{ position:'absolute', right:-1, top:-3, width:0, height:0,
      borderLeft:`8px solid ${T.border2}`, borderTop:'4px solid transparent', borderBottom:'4px solid transparent',
      opacity: appear>0.9?1:0 }} />
    {label && <div style={{ position:'absolute', left:'50%', top:-22, transform:`translateX(-50%) rotate(${-ang}deg)`,
      fontSize:12.5, color:T.muted, whiteSpace:'nowrap', fontFamily:UI_FONT }}>{label}</div>}
  </div>;
}

// ── Check row (self-test) ────────────────────────────────────────────────────
function CheckRow({ text, done }) {
  return <div style={{ display:'flex', alignItems:'center', gap:12, padding:'13px 16px',
    background:T.surface2, border:`1px solid ${done?'rgba(78,208,138,.5)':T.border}`, borderRadius:10 }}>
    <div style={{ width:24, height:24, borderRadius:'50%', flex:'none',
      background: done?T.ok:'transparent', border:`1.5px solid ${done?T.ok:T.border2}`,
      display:'flex', alignItems:'center', justifyContent:'center', transition:'.2s' }}>
      {done && <svg width="14" height="14" viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"
        fill="none" stroke="#0d0f14" strokeWidth="3.2" strokeLinecap="round" strokeLinejoin="round"/></svg>}
    </div>
    <span style={{ fontSize:15, color: done?T.text:T.muted, fontFamily:UI_FONT }}>{text}</span>
  </div>;
}

Object.assign(window, {
  T, UI_FONT, DISPLAY_FONT, MONO, STAGE_BG, ease, clamp01, seg,
  Logo, Cursor, Caption, Field, Caret, Btn, Seg, Chip, Card, GNode, Edge, CheckRow,
});
