// components.jsx — shared UI primitives + icon set

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

// ============================================================
// Icons (compact SVG set, currentColor)
// ============================================================
const Icon = {};
const _icon = (name, body, viewBox) => Icon[name] = ({size=18, ...rest}) => (
  <svg width={size} height={size} viewBox={viewBox||"0 0 24 24"} fill="none"
    stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...rest}>{body}</svg>
);

_icon('home', <><path d="M3 11l9-7 9 7v9a1 1 0 01-1 1h-5v-7H10v7H4a1 1 0 01-1-1z"/></>);
_icon('create', <><circle cx="12" cy="12" r="9"/><path d="M12 8v8M8 12h8"/></>);
_icon('fortune', <><circle cx="12" cy="12" r="9"/><path d="M12 3v9l6 4"/><path d="M3 12h6M21 12h-3"/></>);
_icon('credits', <><rect x="3" y="6" width="18" height="13" rx="2"/><path d="M3 10h18"/><path d="M7 15h3"/></>);
_icon('history', <><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></>);
_icon('star', <><path d="M12 3l2.5 5.5L20 9.5l-4 4 1 6-5-3-5 3 1-6-4-4 5.5-1z"/></>);
_icon('sparkles', <><path d="M5 12l1.5-3L8 12l3 1.5L8 15l-1.5 3L5 15l-3-1.5z"/><path d="M16 4l1 2 2 1-2 1-1 2-1-2-2-1 2-1z"/></>);
_icon('photo', <><rect x="3" y="5" width="18" height="14" rx="2"/><circle cx="9" cy="11" r="2"/><path d="M21 17l-5-5-9 8"/></>);
_icon('video', <><rect x="3" y="6" width="13" height="12" rx="2"/><path d="M16 10l5-3v10l-5-3z"/></>);
_icon('face', <><circle cx="12" cy="12" r="9"/><circle cx="9" cy="10" r=".7" fill="currentColor" stroke="none"/><circle cx="15" cy="10" r=".7" fill="currentColor" stroke="none"/><path d="M9 15c1 1 2 1.5 3 1.5s2-.5 3-1.5"/></>);
_icon('multiface', <><circle cx="9" cy="10" r="3.5"/><circle cx="16" cy="13" r="3"/><path d="M3 19c0-2.5 2.5-4 6-4M11 20c0-1.5 2-3 5-3"/></>);
_icon('wand', <><path d="M15 6l3 3-9 9H6v-3z"/><path d="M14 7l3 3M5 4l1 1M19 5l-1 1M20 12l1-1"/></>);
_icon('lock', <><rect x="5" y="11" width="14" height="9" rx="2"/><path d="M8 11V8a4 4 0 018 0v3"/></>);
_icon('upload', <><path d="M12 3v12M7 8l5-5 5 5"/><path d="M5 17v2a2 2 0 002 2h10a2 2 0 002-2v-2"/></>);
_icon('download', <><path d="M12 3v12M17 10l-5 5-5-5"/><path d="M5 17v2a2 2 0 002 2h10a2 2 0 002-2v-2"/></>);
_icon('check', <><path d="M5 12l5 5L20 7"/></>);
_icon('checkCircle', <><circle cx="12" cy="12" r="9"/><path d="M8 12l3 3 5-5"/></>);
_icon('x', <><path d="M6 6l12 12M6 18L18 6"/></>);
_icon('chevronRight', <><path d="M9 6l6 6-6 6"/></>);
_icon('chevronLeft', <><path d="M15 6l-6 6 6 6"/></>);
_icon('chevronUp', <><path d="M6 15l6-6 6 6"/></>);
_icon('chevronDown', <><path d="M6 9l6 6 6-6"/></>);
_icon('arrowRight', <><path d="M5 12h14M13 5l7 7-7 7"/></>);
_icon('plus', <><path d="M12 5v14M5 12h14"/></>);
_icon('minus', <><path d="M5 12h14"/></>);
_icon('refresh', <><path d="M3 12a9 9 0 019-9 9 9 0 016.6 3M21 4v5h-5"/><path d="M21 12a9 9 0 01-9 9 9 9 0 01-6.6-3M3 20v-5h5"/></>);
_icon('settings', <><circle cx="12" cy="12" r="3"/><path d="M19 12c0 .7-.1 1.3-.3 2l2 1.5-2 3.5-2.4-1c-1 .8-2.2 1.4-3.4 1.7L12.5 22h-1l-.5-2.3a8 8 0 01-3.4-1.7l-2.4 1-2-3.5 2-1.5c-.2-.7-.3-1.3-.3-2s.1-1.3.3-2L3.2 8.5l2-3.5 2.4 1c1-.8 2.2-1.4 3.4-1.7L11.5 2h1l.5 2.3a8 8 0 013.4 1.7l2.4-1 2 3.5-2 1.5c.2.7.3 1.3.3 2z"/></>);
_icon('share', <><circle cx="6" cy="12" r="2.5"/><circle cx="18" cy="6" r="2.5"/><circle cx="18" cy="18" r="2.5"/><path d="M8 11l8-4M8 13l8 4"/></>);
_icon('copy', <><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V5a2 2 0 012-2h10"/></>);
_icon('heart', <><path d="M12 20s-7-4.5-7-10a4 4 0 017-2.6A4 4 0 0119 10c0 5.5-7 10-7 10z"/></>);
_icon('heartBroken', <><path d="M12 20s-7-4.5-7-10a4 4 0 017-2.6A4 4 0 0119 10c0 5.5-7 10-7 10z"/><path d="M9 8l3 4-2 1 2 3"/></>);
_icon('user', <><circle cx="12" cy="9" r="3.5"/><path d="M4 20c0-3.5 3.5-6 8-6s8 2.5 8 6"/></>);
_icon('users', <><circle cx="9" cy="9" r="3.5"/><circle cx="17" cy="10" r="2.5"/><path d="M3 19c0-3 2.5-5 6-5s6 2 6 5"/><path d="M16 15c2.5 0 5 1.5 5 4"/></>);
_icon('crown', <><path d="M3 8l4 6 5-9 5 9 4-6v10H3z"/></>);
_icon('coins', <><ellipse cx="9" cy="8" rx="6" ry="3"/><path d="M3 8v3c0 1.5 2.6 3 6 3s6-1.5 6-3V8"/><ellipse cx="15" cy="14" rx="6" ry="3"/><path d="M9 14v3c0 1.6 2.5 3 6 3s6-1.4 6-3v-3"/></>);
_icon('clock', <><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></>);
_icon('info', <><circle cx="12" cy="12" r="9"/><path d="M12 8h0M11 12h1v5h1"/></>);
_icon('warning', <><path d="M12 4l9 16H3z"/><path d="M12 10v4M12 17h0"/></>);
_icon('mail', <><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 6l9 7 9-7"/></>);
_icon('paypal', <><path d="M7 6h6c3 0 5 2 4 5s-3 4-6 4H9l-1 5H5z"/><path d="M9 9h4c2 0 3 1.5 3 3"/></>);
_icon('telegramStar', <><path d="M12 3l2.5 5.5L20 9.5l-4 4 1 6-5-3-5 3 1-6-4-4 5.5-1z"/></>);
_icon('gift', <><rect x="3" y="9" width="18" height="11" rx="2"/><path d="M3 13h18M12 9v11"/><path d="M9 9c-2 0-3-1-3-2s1-2 2-2c2 0 4 4 4 4M15 9c2 0 3-1 3-2s-1-2-2-2c-2 0-4 4-4 4"/></>);
_icon('flame', <><path d="M12 3c1.5 4 5 5 5 9a5 5 0 11-10 0c0-2 1-3 2-4 0 2 2 2 2 0 0-3-1-3 1-5z"/></>);
_icon('zap', <><path d="M13 3L4 14h6l-1 7 9-11h-6z"/></>);
_icon('filter', <><path d="M3 5h18l-7 9v6l-4-2v-4z"/></>);
_icon('search', <><circle cx="11" cy="11" r="7"/><path d="M21 21l-5-5"/></>);
_icon('trash', <><path d="M4 7h16M9 7V4h6v3"/><path d="M6 7l1 13h10l1-13"/></>);
_icon('externalLink', <><path d="M14 4h6v6M10 14L20 4M14 12v6a2 2 0 01-2 2H6a2 2 0 01-2-2v-6a2 2 0 012-2h6"/></>);
_icon('eye', <><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7z"/><circle cx="12" cy="12" r="3"/></>);
_icon('grid', <><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></>);
_icon('language', <><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3a14 14 0 010 18M12 3a14 14 0 000 18"/></>);
_icon('helpCircle', <><circle cx="12" cy="12" r="9"/><path d="M9 9c.5-2 4-3 5 0 .5 1.5-1 2-2 3v1M12 17v0"/></>);
_icon('shield', <><path d="M12 3l8 3v5c0 5-4 9-8 10-4-1-8-5-8-10V6z"/></>);
_icon('moon', <><path d="M20 14a8 8 0 11-10-10 6 6 0 0010 10z"/></>);
_icon('book', <><path d="M4 5a2 2 0 012-2h12v17H6a2 2 0 01-2-2z"/><path d="M4 18a2 2 0 012-2h12"/></>);
_icon('palette', <><circle cx="12" cy="12" r="9"/><circle cx="7.5" cy="11" r="1"/><circle cx="11" cy="7" r="1"/><circle cx="16" cy="9" r="1"/><circle cx="15" cy="14" r="1"/><path d="M12 21a3 3 0 010-6 2 2 0 002-2c0-1-1-2-2-2"/></>);
_icon('image', <><rect x="3" y="5" width="18" height="14" rx="2"/><circle cx="9" cy="11" r="2"/><path d="M3 17l5-5 6 5 3-3 4 4"/></>);
_icon('film', <><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 7h4M3 12h4M3 17h4M17 7h4M17 12h4M17 17h4M7 3v18M17 3v18"/></>);
_icon('wallet', <><rect x="3" y="6" width="18" height="13" rx="2"/><path d="M3 10h18"/><circle cx="17" cy="14" r="1.5"/></>);
_icon('trophy', <><path d="M7 4h10v4a5 5 0 01-10 0z"/><path d="M5 4h2v3a3 3 0 01-3-3zM17 4h2c0 1.5-1.5 3-3 3V4z"/><path d="M9 13v3l-1 4h8l-1-4v-3"/></>);

window.Icon = Icon;

// ============================================================
// Visual helpers
// ============================================================
function StarField({count=40}){
  const stars = useMemo(()=>{
    const arr = [];
    for (let i=0; i<count; i++) arr.push({
      x: Math.random()*100,
      y: Math.random()*100,
      d: Math.random()*3,
      s: Math.random()*1.5+0.5,
    });
    return arr;
  }, [count]);
  return (
    <div className="bg-stars" aria-hidden="true">
      {stars.map((s, i) => (
        <div key={i} className="star" style={{
          left: s.x+'%', top: s.y+'%',
          width: s.s+'px', height: s.s+'px',
          animationDelay: s.d+'s'
        }}/>
      ))}
    </div>
  );
}
window.StarField = StarField;

// AI banner that uses one of the cropped reference images
function AIBanner({ kind='campaign-upsell', children, height=140 }){
  const assetBase = (window.RavanaMiniApp && window.RavanaMiniApp.assetBase) || '/miniapp-assets';
  return (
    <div className="ai-banner" style={{ height }}>
      <img src={`${assetBase}/assets/${kind}.jpg`} alt=""/>
      <div className="ai-overlay"/>
      <div className="ai-content">{children}</div>
    </div>
  );
}
window.AIBanner = AIBanner;

// Generic placeholder media (no AI-image embedded)
function PlaceholderMedia({ label='media', aspect='4/5', kind='photo' }){
  return (
    <div style={{aspectRatio: aspect, borderRadius: 14, overflow: 'hidden', border: '1px solid rgba(155,92,255,0.18)'}}>
      <div className="placeholder-art" style={{position: 'static', height: '100%'}}>
        <div className="mono">{label}</div>
      </div>
    </div>
  );
}
window.PlaceholderMedia = PlaceholderMedia;

// Step indicator (for flow wizards)
function Stepper({ steps, current }){
  return (
    <div className="stepper">
      {steps.map((s, i) => (
        <div key={i} className={"step " + (i < current ? "done" : i === current ? "active" : "")}/>
      ))}
    </div>
  );
}
window.Stepper = Stepper;

// Reusable header for nested screens
function ScreenHeader({ title, subtitle, onBack, right }){
  return (
    <div className="row-between" style={{marginBottom: 4, gap: 12, alignItems:'flex-start'}}>
      <div style={{display:'flex', alignItems:'center', gap: 10, flex: 1, minWidth: 0}}>
        {onBack && (
          <button className="icon-btn" onClick={onBack} aria-label="Back" style={{flex:'none'}}><Icon.chevronLeft size={18}/></button>
        )}
        <div style={{flex: 1, minWidth: 0}}>
          <div className="h-screen" style={{whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>{title}</div>
          {subtitle && <div className="mute" style={{marginTop:2}}>{subtitle}</div>}
        </div>
      </div>
      <div style={{flex:'none', marginTop: 4}}>{right}</div>
    </div>
  );
}
window.ScreenHeader = ScreenHeader;

// Sheet (bottom modal)
function Sheet({ open, onClose, children, dialog=false }){
  if (!open) return null;
  return (
    <div className="scrim" onClick={onClose} style={dialog ? {alignItems:'center'} : undefined}>
      <div className={dialog ? 'dialog' : 'sheet'} onClick={e=>e.stopPropagation()}>
        {children}
      </div>
    </div>
  );
}
window.Sheet = Sheet;

// Active job card
function ActiveJobCard({ job, lang, onClick }){
  const status = job.status;
  return (
    <button className="active-job" onClick={onClick} style={{border:0, width:'100%', textAlign:'left', cursor:'pointer'}}>
      <div className="thumb pulse-cyan">
        {job.type === 'multiface' ? <Icon.multiface size={18}/> :
         job.type === 'image_gen' ? <Icon.wand size={18}/> : <Icon.face size={18}/>}
      </div>
      <div style={{minWidth:0}}>
        <div style={{fontSize:13, fontWeight:600, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis'}}>{job.name}</div>
        <div className="dim" style={{display:'flex',gap:8,alignItems:'center',marginTop:2}}>
          <span style={{color:'var(--cyan)'}}>● {t('status_'+status, lang)}</span>
          {job.eta && <span>· ETA {job.eta}</span>}
        </div>
      </div>
      <Icon.chevronRight size={16}/>
    </button>
  );
}
window.ActiveJobCard = ActiveJobCard;

// Cost preview box
function CostPanel({ items }){
  return (
    <div className="card" style={{padding: '6px 14px'}}>
      {items.map((row, i) => (
        <div className="kv-row" key={i}>
          <span className="k">{row.k}</span>
          <span className={"v " + (row.tone || '')}>{row.v}</span>
        </div>
      ))}
    </div>
  );
}
window.CostPanel = CostPanel;

// Premium chip with crown
function PremiumChip({ kind='free', lang }){
  if (kind === 'premium') return <span className="chip chip-gold"><Icon.crown size={12}/> Premium</span>;
  if (kind === 'ref_premium') return <span className="chip chip-purple"><Icon.users size={12}/> Ref Premium</span>;
  if (kind === 'returning') return <span className="chip chip-cyan"><Icon.sparkles size={12}/> {t('old_payer', lang)}</span>;
  return <span className="chip">{t('free', lang)}</span>;
}
window.PremiumChip = PremiumChip;
