/* Clear Mint — V6 shared kit: Robot mascot, ScoreGauge, helpers.
   Depends on cm-charts (CMIcon). */
const Ik = window.CMIcon;

/* ---- Robot mascot ---- */
/* pose ids reference assets/robot/r{sheet}-{n}.png */
function Robot({ pose='r1-7', size=120, float=true, cls='', style }) {
  return (
    <span className={`cm-robot ${float?(typeof float==='string'?float:'float'):''} ${cls}`}
          style={{ width:size, height:size, ...style }}>
      <img src={`assets/robot/${pose}.png`} alt="Clear Mint assistant" draggable="false"/>
    </span>
  );
}
window.Robot = Robot;

/* ---- Stars ---- */
function Stars({ n=5, size=14 }) {
  const Star = (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor">
      <path d="M12 2.5l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 9.8l6.5-.9z"/>
    </svg>
  );
  return <div className="cm-stars">{Array.from({length:n}).map((_,i)=><span key={i}>{Star}</span>)}</div>;
}
window.Stars = Stars;

/* ---- Semicircle score gauge ---- */
function ScoreGauge({ score=92, max=100, size=190, label='Excellent', stars=5, thickness, scoreSize, showStars=true }) {
  const W = size, H = Math.round(size*0.66);
  const t = thickness || Math.round(size*0.11);
  const cx = W/2, cy = Math.round(size*0.52), r = (W - t)/2 - 2;
  const arc = `M ${cx-r} ${cy} A ${r} ${r} 0 0 1 ${cx+r} ${cy}`;
  const frac = Math.max(0, Math.min(1, score/max));
  const theta = Math.PI*(1-frac);
  const mx = cx + r*Math.cos(theta), my = cy - r*Math.sin(theta);
  const gid = 'sg'+Math.round(size+score);
  return (
    <div className="cm-scoregauge" style={{ width:W, height:H }}>
      <svg width={W} height={H} viewBox={`0 0 ${W} ${H}`} style={{display:'block'}}>
        <defs>
          <linearGradient id={gid} x1={cx-r} y1="0" x2={cx+r} y2="0" gradientUnits="userSpaceOnUse">
            <stop offset="0%" stopColor="#C35B5B"/>
            <stop offset="48%" stopColor="#D4A95D"/>
            <stop offset="100%" stopColor="#2E8B57"/>
          </linearGradient>
        </defs>
        <path d={arc} fill="none" stroke="var(--line)" strokeWidth={t} strokeLinecap="round"/>
        <path d={arc} fill="none" stroke={`url(#${gid})`} strokeWidth={t} strokeLinecap="round"/>
        <circle cx={mx} cy={my} r={t*0.42} fill="#fff" stroke="var(--ink-700)" strokeWidth="2"/>
      </svg>
      <div className="sg-center">
        <div className="sg-score" style={{ fontSize: scoreSize||Math.round(size*0.26) }}>{score}</div>
        <div className="sg-label">{label}</div>
        {showStars && <div style={{marginTop:5}}><Stars n={stars} size={Math.round(size*0.07)}/></div>}
      </div>
    </div>
  );
}
window.ScoreGauge = ScoreGauge;

/* ---- Mini sparkline ---- */
function Spark({ data, w=120, h=34, color='var(--green-500)', fill=true }) {
  const min=Math.min(...data), max=Math.max(...data), rng=(max-min)||1;
  const X=i=>(i/(data.length-1))*w, Y=v=>h-4-((v-min)/rng)*(h-8);
  const line=data.map((v,i)=>`${i?'L':'M'}${X(i).toFixed(1)},${Y(v).toFixed(1)}`).join(' ');
  const gid='spk'+Math.round(w+h+data.length+data[0]);
  return (
    <svg width="100%" height={h} viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{display:'block'}}>
      {fill && <><defs><linearGradient id={gid} x1="0" y1="0" x2="0" y2="1">
        <stop offset="0%" stopColor={color} stopOpacity=".18"/><stop offset="100%" stopColor={color} stopOpacity="0"/>
      </linearGradient></defs>
      <path d={`${line} L${w},${h} L0,${h} Z`} fill={`url(#${gid})`}/></>}
      <path d={line} fill="none" stroke={color} strokeWidth="2" strokeLinejoin="round" strokeLinecap="round"/>
    </svg>
  );
}
window.Spark = Spark;

/* ---- Section heading with eyebrow ---- */
function SecHead({ eyebrow, title, link, onLink }) {
  return (
    <div className="cm-sechead">
      <div>
        {eyebrow && <div className="eyebrow">{eyebrow}</div>}
        <h2>{title}</h2>
      </div>
      {link && <span className="link" onClick={onLink}>{link}<Ik.ChevR size={14}/></span>}
    </div>
  );
}
window.SecHead = SecHead;

Object.assign(window, { Robot, Stars, ScoreGauge, Spark, SecHead });

/* ---- store hook: re-render React when CM state changes ---- */
function useStore() {
  const [, force] = React.useState(0);
  React.useEffect(function(){
    if (!window.CM) return;
    return window.CM.subscribe(function(){ force(function(n){ return n + 1; }); });
  }, []);
  return window.CM;
}
window.useStore = useStore;

/* ---- BrandIcon: real merchant/bank logos with graceful fallback ----
   Always attempts the logo API: curated domain map first, then a guessed
   "<brand>.com" domain for unmapped vendors. A failed guess falls back to
   the initials chip via __logoFallback (domain passed as '' so it never
   shows a generic favicon for a wrong guess). */
function BrandIcon({ name, size=38, radius=10 }) {
  const mapped = window.resolveLogoDomain ? window.resolveLogoDomain(name) : null;
  const guess = (!mapped && window.guessLogoDomain) ? window.guessLogoDomain(name) : null;
  let src = window.getBrandIconSrc ? window.getBrandIconSrc(name) : null;
  if (!src && guess && window.primaryLogoUrl) src = window.primaryLogoUrl(guess, 64);
  if (src) return <img src={src} width={size} height={size} alt={name||''}
    onError={e=>{ if(window.__logoFallback) window.__logoFallback(e.target, name||'', mapped||''); }}
    style={{ width:size, height:size, borderRadius:radius, objectFit:'contain', border:'1px solid #E2E8F0', background:'#fff', flexShrink:0, padding:2 }}/>;
  const bank = window.BANK_DATA && window.BANK_DATA[name];
  const palette = ['#003168','#00703C','#EC2027','#C41230','#0079C1','#1F7A53','#6B21A8'];
  const bg = bank ? bank.bg : palette[((name||'A').charCodeAt(0))%palette.length];
  const initials = bank ? bank.initials : (name||'•').replace(/[^A-Za-z0-9]/g,'').slice(0,2).toUpperCase() || '•';
  return <span style={{ width:size, height:size, borderRadius:radius, background:bg, display:'flex',
    alignItems:'center', justifyContent:'center', color:'#fff', fontWeight:800,
    fontSize:Math.round(size*0.34), flexShrink:0, letterSpacing:'-.02em' }}>{initials}</span>;
}
window.BrandIcon = BrandIcon;
