/* TerminalShared.jsx — shared small components for the Terminal Desk */

const { useState, useEffect, useRef, useMemo, useCallback } = React;

/* ─────────── Chip ─────────── */
function Chip({ children, amber, live, dark, btn, on, onClick, style }) {
  const cls = ['chip'];
  if (amber) cls.push('amber');
  if (live)  cls.push('live');
  if (dark)  cls.push('dark');
  if (btn)   cls.push('btn');
  if (on)    cls.push('on');
  return <span className={cls.join(' ')} onClick={onClick} style={style}>{children}</span>;
}

/* ─────────── Panel ─────────── */
function Panel({ title, count, action, children, bodyClass, style }) {
  return (
    <div className="panel" style={style}>
      <div className="panel-title">
        <span className="dots"><span/><span/><span/></span>
        <span className="grow">{title}</span>
        {count != null && <span className="count">{count}</span>}
        {action}
      </div>
      <div className={"panel-body "+(bodyClass||'')}>{children}</div>
    </div>
  );
}

/* ─────────── Ticker ─────────── */
function TickerBar({ week, weekNumber }) {
  const [paused, setPaused] = useState(false);
  const items = useMemo(()=>{
    const f = (week.funding || []).map(x => (
      <span className="ticker-item" key={"f-"+x.co}>
        <b>{x.co}</b>
        <em>{x.amount}</em>
        {x.valuation && x.valuation !== '—' ? <span style={{opacity:.7}}>@ {x.valuation}</span> : null}
        <span style={{opacity:.7}}>[{x.stage}]</span>
      </span>
    ));
    const t = (week.tweets || []).slice(0,3).map((x,i)=>(
      <span className="ticker-item" key={"t-"+i}><b>{x.handle}</b><span style={{opacity:.7}}>{x.quote.slice(0,58)}…</span></span>
    ));
    const r = (week.repos || []).map((x,i)=>(
      <span className="ticker-item" key={"r-"+i}><b style={{color:'var(--amber-300)'}}>❯</b><span>{x.name}</span></span>
    ));
    const banner = <span className="ticker-item" key="banner"><b style={{color:'var(--amber-400)'}}>◉ KARATAGE RESEARCH DESK</b><span style={{opacity:.7}}>WEEKLY DISPATCH · {week.label}</span></span>;
    const all = [banner, ...f, ...t, ...r];
    const sep = (i) => <span className="ticker-sep" key={"s-"+i}>·</span>;
    const interleaved = [];
    all.forEach((el,i)=>{ interleaved.push(el); interleaved.push(sep(i)); });
    return interleaved;
  }, [week.id]);

  // Duplicate content for seamless loop
  return (
    <div className="ticker-bar">
      <Chip
        live={!paused}
        dark={paused}
        btn
        onClick={()=>setPaused(p=>!p)}
        style={{cursor:'pointer'}}
      >
        {paused ? 'PAUSED' : 'LIVE'}
      </Chip>
      <div className="ticker-viewport">
        <div className={"ticker-track"+(paused?' paused':'')}>
          <div style={{display:'flex', gap:36}}>{items}</div>
          <div style={{display:'flex', gap:36}}>{items}</div>
        </div>
      </div>
      <span style={{color:'var(--amber-300)'}}>{weekNumber}</span>
      <span style={{opacity:.6}}>·</span>
      <span>{new Date().toISOString().slice(0,10)}</span>
    </div>
  );
}

/* ─────────── Header ─────────── */
function Header({ week, weekNumber, allWeeks, onTagSelected, activeTags, search, setSearch }) {
  return (
    <div className="header">
      <div className="logo">Robotics <span className="dot">x</span> AI Research</div>
      <Chip>WEEKLY DISPATCH</Chip>
      <Chip amber>● W{weekNumber.replace('W','')}</Chip>
      <span className="eyebrow" style={{marginLeft:4}}>
        {week.label} · {week.dateRange}
      </span>
      <div className="spacer"/>
      <div className="search">
        <span style={{color:'var(--ink-600)'}}>⌕</span>
        <input
          placeholder="filter · tweets · repos · people"
          value={search}
          onChange={e=>setSearch(e.target.value)}
        />
      </div>
    </div>
  );
}

/* ─────────── Tweet embed ─────────── */
function TweetMedia({ media }) {
  const n = Math.min(media.length, 4);
  return (
    <div className={"tweet-media tweet-media-" + n}>
      {media.map((m, i) => {
        if (m.type === 'video' || m.type === 'animated_gif') {
          const isGif = m.type === 'animated_gif';
          return (
            <video
              key={i}
              src={m.src}
              poster={m.poster}
              controls={!isGif}
              autoPlay={isGif}
              loop={isGif}
              muted={isGif}
              playsInline
              preload="metadata"
            />
          );
        }
        return <img key={i} src={m.src} alt="" loading="lazy" />;
      })}
    </div>
  );
}

function TweetEmbed({ url, handle, quote, text, media }) {
  const hasText = !!(text && text.trim());
  const hasMedia = Array.isArray(media) && media.length > 0;
  const showCaption = hasText && quote && quote.trim() && quote.trim() !== text.trim();
  return (
    <div className="tweet-card">
      <div className="tweet-head">
        <a className="handle" href={url} target="_blank" rel="noreferrer" style={{border:0}}>{handle}</a>
        <a className="opens" href={url} target="_blank" rel="noreferrer" style={{border:0}}>open on 𝕏 →</a>
      </div>
      {hasMedia && <TweetMedia media={media} />}
      <div className="tweet-embed">
        {hasText
          ? <div className="tweet-text">{text}</div>
          : <div className="quote-fallback">{quote}</div>}
        {showCaption && <div className="tweet-caption">{quote}</div>}
      </div>
    </div>
  );
}

window.Chip = Chip;
window.Panel = Panel;
window.TickerBar = TickerBar;
window.Header = Header;
window.TweetEmbed = TweetEmbed;
window.TweetMedia = TweetMedia;
