// Triplicity · Little Stars — shared KIDS UI primitives
// Reuses the adult chart logic (lookups / chart-data / wheel); only the visual
// vocabulary changes: rounded shapes, moonlight pastels, friendly type, calm motion.

// ── Static base tokens (mirror theme-kids.css) ───────────────────────────────
const KID = {
  bg0:'#0B1A33', skyTop:'#14305A', skyBot:'#0A1730',
  surface:'#16294A', surface2:'#1C3155',
  line:'rgba(193,201,240,0.16)', lineSoft:'rgba(193,201,240,0.08)',
  moon:'#FBF1D6', gold:'#F4D58A', aqua:'#9FE0D8', peach:'#F6B79E', lilac:'#CBBEF2',
  peri:'#93A6EC', periDeep:'#7C8FE6',
  white:'#F4F7FF', text:'#E6ECFB', gray:'#A9B6D4', grayDim:'#7E8CAD',
  zh:"'Noto Sans TC', sans-serif",
  zhSoft:"'Noto Serif TC', serif",
  en:"'Baloo 2', 'Noto Sans TC', cursive",
};

// ── Theme context — driven by Tweaks (accent palette / font / roundness / motion) ──
const KidThemeCtx = React.createContext(null);

const KID_PALETTES = {
  moonlight: { primary:'#93A6EC', primaryDeep:'#7C8FE6', glow:'147,166,236',
               accents:['#F4D58A','#9FE0D8','#F6B79E','#CBBEF2'] },
  aurora:    { primary:'#6FD8C4', primaryDeep:'#54C4AE', glow:'111,216,196',
               accents:['#9FE0D8','#8FE0B6','#B79CF0','#7FC8F0'] },
  candy:     { primary:'#F4A98F', primaryDeep:'#EE9277', glow:'244,169,143',
               accents:['#FFC95C','#FF9FB2','#7FD3F0','#C9BEF2'] },
};

function useKidTheme(){
  return React.useContext(KidThemeCtx) || {
    pal: KID_PALETTES.moonlight,
    primary: KID.peri, primaryDeep: KID.periDeep, glow:'147,166,236',
    accents: KID_PALETTES.moonlight.accents,
    font: KID.en, round: 1, animate: true, wheelStyle:'traditional',
  };
}

// roundness-aware radius — `round` scales the base radius (slider 0.4..1.4)
function rad(base, round){ return Math.max(2, Math.round(base * (round ?? 1))); }

// Pause off-screen work — true when the element is in (or near) the viewport.
// Used to stop requestAnimationFrame loops on artboards the user isn't looking at.
function useInView(ref, { rootMargin = '200px' } = {}){
  const [inView, setInView] = React.useState(false);
  React.useEffect(()=>{
    if(!ref.current) return;
    if(typeof IntersectionObserver === 'undefined'){ setInView(true); return; }
    const io = new IntersectionObserver(es=>{ setInView(es[0]?.isIntersecting ?? true); }, { rootMargin });
    io.observe(ref.current);
    return ()=>io.disconnect();
  },[]);
  return inView;
}

// Lazy-mount heavy artboard content — keeps a sized placeholder until the
// artboard nears the viewport, so the design canvas isn't rendering every
// step + result tier + PDF page at once.
function KidLazy({ width, height, children }){
  const ref = React.useRef(null);
  const inView = useInView(ref, { rootMargin: '600px' });
  const [everSeen, setEverSeen] = React.useState(false);
  React.useEffect(()=>{ if(inView && !everSeen) setEverSeen(true); }, [inView]);
  return (
    <div ref={ref} style={{ width, minHeight: height, position:'relative' }}>
      {everSeen ? children : (
        <div style={{ position:'absolute', inset:12, borderRadius:18,
          background:'rgba(193,201,240,0.04)', border:`1px solid ${KID.lineSoft}`,
          display:'flex', alignItems:'center', justifyContent:'center' }}>
          <SparkleStar size={20} color={KID.gold}/>
        </div>
      )}
    </div>
  );
}

// ── Soft glow helpers ────────────────────────────────────────────────────────
const glowRGBA = (rgb, a) => `rgba(${rgb},${a})`;

// ─────────────────────────────────────────────────────────────────────────────
// Starfield — gentle twinkles + a few friendly sparkles + soft moon-glow blobs
// + (optional) a slow shooting star. Deterministic so it doesn't reflow on tweak.
// ─────────────────────────────────────────────────────────────────────────────
// subtle pastel star tints — most stars stay near-white, a few glow in accent hues
const STAR_TINTS = ['#EAF0FF','#EAF0FF','#EAF0FF','#FBF1D6','#9FE0D8','#F6B79E','#CBBEF2','#9FB6E8'];
function KidStarfield({ density = 1, animate = true, glow = '147,166,236', shoot = false }){
  const stars = React.useMemo(()=>{
    const arr = []; const count = Math.floor(70 * density);
    let seed = 9173; const rnd = () => { seed = (seed*9301 + 49297) % 233280; return seed/233280; };
    for (let i=0;i<count;i++){
      const color = STAR_TINTS[Math.floor(rnd()*STAR_TINTS.length)];
      arr.push({ x:rnd()*100, y:rnd()*100, size:0.6+rnd()*1.8, color,
                 op:0.3+rnd()*0.6, delay:rnd()*5, dur:2.4+rnd()*3.4, min:0.2+rnd()*0.3 });
    }
    return arr;
  }, [density]);

  const sparkles = React.useMemo(()=>{
    const arr = []; let seed = 4421; const rnd = () => { seed=(seed*9301+49297)%233280; return seed/233280; };
    const cols = [KID.moon, KID.aqua, KID.peach, KID.lilac, KID.gold];
    for (let i=0;i<Math.round(6*density);i++){
      arr.push({ x:8+rnd()*84, y:6+rnd()*70, s:7+rnd()*8, delay:rnd()*4, color: cols[Math.floor(rnd()*cols.length)] });
    }
    return arr;
  }, [density]);

  return (
    <div style={{position:'absolute', inset:0, overflow:'hidden', pointerEvents:'none'}}>
      {/* moon-glow washes */}
      <div style={{position:'absolute', left:'72%', top:'14%', width:'60%', height:'60%',
                   background:`radial-gradient(circle, ${glowRGBA(glow,0.20)} 0%, rgba(11,26,51,0) 65%)`, filter:'blur(6px)'}}/>
      <div style={{position:'absolute', left:'8%', top:'68%', width:'55%', height:'55%',
                   background:`radial-gradient(circle, ${glowRGBA('251,241,214',0.07)} 0%, rgba(11,26,51,0) 65%)`, filter:'blur(8px)'}}/>
      {/* tiny twinkles */}
      {stars.map((s,i)=>(
        <div key={i} style={{position:'absolute', left:`${s.x}%`, top:`${s.y}%`,
          width:`${s.size}px`, height:`${s.size}px`, borderRadius:'50%', background:s.color,
          '--tk-min':s.min, opacity:s.op,
          boxShadow: s.size>1.4 ? `0 0 ${s.size*3.5}px ${s.color}` : 'none',
          animation: animate ? `k-twinkle ${s.dur}s ease-in-out ${s.delay}s infinite` : 'none'}}/>
      ))}
      {/* friendly 4-point sparkles */}
      {sparkles.map((s,i)=>(
        <div key={'sp'+i} style={{position:'absolute', left:`${s.x}%`, top:`${s.y}%`,
          animation: animate ? `k-sparkle ${3.5+i*0.4}s ease-in-out ${s.delay}s infinite` : 'none'}}>
          <SparkleStar size={s.s} color={s.color}/>
        </div>
      ))}
      {/* slow shooting star */}
      {animate && shoot && (
        <div style={{position:'absolute', left:'6%', top:'12%', width:90, height:2,
          background:'linear-gradient(90deg, rgba(251,241,214,0) 0%, rgba(251,241,214,0.9) 100%)',
          borderRadius:2, filter:'drop-shadow(0 0 4px rgba(251,241,214,0.7))',
          animation:'k-shoot 7s ease-in 1.5s infinite'}}/>
      )}
    </div>
  );
}

// 4-point twinkle star
function SparkleStar({ size = 12, color = '#FBF1D6' }){
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" style={{display:'block', filter:`drop-shadow(0 0 3px ${color}aa)`}}>
      <path d="M12 0 C13.2 8 16 10.8 24 12 C16 13.2 13.2 16 12 24 C10.8 16 8 13.2 0 12 C8 10.8 10.8 8 12 0 Z" fill={color}/>
    </svg>
  );
}

// ── Constellation motif — colourful pastel stars on faint connecting lines ──────
// Replaces the earlier mascot. Subtle, dreamy, "star-sign" feel.
const KID_CONSTELLATIONS = {
  // a gentle, balanced shape (normalized 0..200 x, 0..150 y)
  default: {
    pts: [[30,46],[74,26],[120,50],[166,32],[150,92],[104,112],[58,92],[96,72]],
    lines: [[0,1],[1,2],[2,3],[3,4],[4,5],[5,6],[6,0],[1,7],[7,5]],
  },
};
function KidConstellation({ size = 240, animate = true, accents }){
  const t = useKidTheme();
  const acc = accents || t.accents;
  const cols = [KID.moon, acc[0], acc[1], acc[2], acc[3], KID.aqua];
  const { pts, lines } = KID_CONSTELLATIONS.default;
  const W = 200, H = 150; const h = size * (H / W);
  return (
    <div style={{ width:size, height:h, position:'relative',
                  animation: animate ? 'k-floatSlow 9s ease-in-out infinite' : 'none' }}>
      <div style={{position:'absolute', inset:'-18%', borderRadius:'50%',
        background:`radial-gradient(circle, ${glowRGBA(t.glow,0.16)} 0%, rgba(11,26,51,0) 68%)`}}/>
      <svg width={size} height={h} viewBox={`0 0 ${W} ${H}`} style={{position:'relative', overflow:'visible', display:'block'}}>
        <g stroke={glowRGBA(t.glow,0.4)} strokeWidth="0.9" strokeLinecap="round" fill="none">
          {lines.map(([a,b],i)=>(
            <line key={i} x1={pts[a][0]} y1={pts[a][1]} x2={pts[b][0]} y2={pts[b][1]}/>
          ))}
        </g>
        {pts.map(([x,y],i)=>{
          const c = cols[i % cols.length]; const r = i % 3 === 0 ? 3.4 : 2.6;
          return (
            <g key={i} style={{ transformOrigin:`${x}px ${y}px`,
                 animation: animate ? `k-sparkle ${3+ (i%4)*0.6}s ease-in-out ${i*0.35}s infinite` : 'none' }}>
              <circle cx={x} cy={y} r={r*3} fill={c} opacity="0.18"/>
              <circle cx={x} cy={y} r={r} fill={c}/>
              <circle cx={x} cy={y} r={r*0.4} fill="#FFFFFF" opacity="0.9"/>
            </g>
          );
        })}
      </svg>
    </div>
  );
}

// ── Brand mark — Triplicity logo, with a soft glow on the navy ─────────────────
function KidBrandMark({ size = 26, theme }){
  const t = theme || useKidTheme();
  return (
    <div style={{display:'flex', alignItems:'center', gap:11}}>
      <div style={{position:'relative', width:size+10, height:size+10, display:'flex', alignItems:'center', justifyContent:'center'}}>
        <div style={{position:'absolute', inset:'-20%', borderRadius:'50%',
                     background:`radial-gradient(circle, ${glowRGBA(t.glow,0.4)} 0%, rgba(11,26,51,0) 70%)`}}/>
        <img src="/chart-childv2-assets/logo.png" alt="Triplicity" style={{position:'relative', width:size+6, height:size+6, objectFit:'contain',
             filter:'brightness(1.25) drop-shadow(0 0 6px rgba(174,185,230,0.35))'}}/>
      </div>
      <div style={{display:'flex', flexDirection:'column', lineHeight:1.05}}>
        <span style={{fontFamily:KID.zh, fontSize:14, color:KID.white, letterSpacing:'0.06em', fontWeight:700}}>親子星盤</span>
        <span style={{fontFamily:t.font, fontSize:9.5, color:t.primary, letterSpacing:'0.2em', marginTop:2, fontWeight:600}}>LITTLE STARS</span>
      </div>
    </div>
  );
}

// ── Eyebrow label (★ STEP ONE) ─────────────────────────────────────────────────
function KidEyebrow({ children, color, style }){
  const t = useKidTheme();
  return (
    <div style={{display:'inline-flex', alignItems:'center', gap:7, fontFamily:t.font, fontSize:11,
                 letterSpacing:'0.18em', color: color || t.primary, fontWeight:600, whiteSpace:'nowrap', ...style}}>
      <SparkleStar size={11} color={color || KID.gold}/>
      <span style={{whiteSpace:'nowrap'}}>{children}</span>
    </div>
  );
}

// ── Rounded form field ─────────────────────────────────────────────────────────
function KidField({ label, placeholder, value, children, round = 1, inputProps }){
  const t = useKidTheme();
  const baseStyle = {
    width:'100%', padding:'13px 16px', background:'rgba(193,201,240,0.06)',
    border:`1.5px solid ${KID.line}`, borderRadius:rad(14, round), color:KID.white,
    fontSize:15, fontFamily:KID.zh, outline:'none', transition:'border-color .2s' };
  return (
    <div style={{marginBottom:18}}>
      <label style={{display:'block', fontFamily:KID.zh, fontSize:12.5, color:KID.gray,
                     marginBottom:9, fontWeight:600, letterSpacing:'0.04em'}}>{label}</label>
      {children || (
        inputProps
          ? <input placeholder={placeholder} {...inputProps} style={{...baseStyle, ...(inputProps.style||{})}}/>
          : <input defaultValue={value} placeholder={placeholder} style={baseStyle}/>
      )}
    </div>
  );
}

// ── Pill choices ────────────────────────────────────────────────────────────────
function KidPill({ active, children, round = 1, onClick }){
  const t = useKidTheme();
  return (
    <span onClick={onClick} style={{
      display:'inline-flex', alignItems:'center', padding:'9px 16px',
      borderRadius:rad(999, round),
      border:`1.5px solid ${active ? t.primary : KID.line}`,
      background: active ? glowRGBA(t.glow,0.18) : 'transparent',
      color: active ? KID.white : KID.gray, fontSize:13, fontFamily:KID.zh, cursor:'pointer',
      letterSpacing:'0.02em', whiteSpace:'nowrap', fontWeight: active?600:400,
      boxShadow: active ? `0 0 0 3px ${glowRGBA(t.glow,0.10)}` : 'none', transition:'all .15s' }}>
      {children}
    </span>
  );
}

// ── Buttons ───────────────────────────────────────────────────────────────────
function KidButton({ children, primary = true, round = 1, full = false, onClick, style }){
  const t = useKidTheme();
  return (
    <button onClick={onClick} style={{
      width: full ? '100%' : 'auto',
      display:'inline-flex', alignItems:'center', justifyContent:'center', gap:10,
      padding:'14px 26px', borderRadius:rad(16, round), cursor:'pointer',
      fontFamily:KID.zh, fontSize:14.5, fontWeight:700, letterSpacing:'0.04em',
      border: primary ? 'none' : `1.5px solid ${t.primary}`,
      background: primary ? `linear-gradient(180deg, ${t.primary} 0%, ${t.primaryDeep} 100%)` : 'transparent',
      color: primary ? '#0B1A33' : t.primary,
      boxShadow: primary ? `0 8px 22px ${glowRGBA(t.glow,0.4)}, inset 0 1px 0 rgba(255,255,255,0.35)` : 'none',
      transition:'transform .12s, box-shadow .2s', ...style }}>
      {children}
    </button>
  );
}

// ── City autocomplete input (production only; pass a `cc` city-controller) ──────
// Visually identical to a KidField input, plus a dropdown while typing.
function KidCityInput({ cc, round = 1, placeholder = '開始輸入城市…' }){
  const baseStyle = {
    width:'100%', padding:'13px 16px', background:'rgba(193,201,240,0.06)',
    border:`1.5px solid ${KID.line}`, borderRadius:rad(14, round), color:KID.white,
    fontSize:15, fontFamily:KID.zh, outline:'none', transition:'border-color .2s' };
  return (
    <div style={{position:'relative'}}>
      <input value={cc.value} placeholder={placeholder} autoComplete="off"
        onChange={e=>cc.onInput(e.target.value)} onKeyDown={cc.onKeyDown}
        onFocus={()=>cc.value && cc.results.length && cc.setOpen(true)}
        style={baseStyle}/>
      {cc.open && cc.results.length > 0 && (
        <div style={{position:'absolute', top:'calc(100% + 6px)', left:0, right:0, zIndex:40,
          background:'#13284A', border:`1.5px solid ${KID.line}`, borderRadius:rad(14, round),
          overflow:'hidden', boxShadow:'0 16px 40px rgba(0,0,0,0.5)', maxHeight:264, overflowY:'auto'}}>
          {cc.results.map((it, i)=>(
            <div key={i} onMouseDown={e=>{ e.preventDefault(); cc.choose(i); }}
              style={{padding:'11px 16px', cursor:'pointer', display:'flex', gap:8, alignItems:'baseline',
                borderBottom: i<cc.results.length-1?`1px solid ${KID.lineSoft}`:'none',
                background: i===cc.activeIdx ? glowRGBA(KID_PALETTES.moonlight.glow,0.16) : 'transparent',
                color: i===cc.activeIdx ? '#fff' : KID.text, fontSize:14}}>
              <span>{it.name}</span>
              <span style={{fontSize:11, color:KID.grayDim}}>{(it.admin1?it.admin1+', ':'')+(it.country||'')}</span>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ── Guardian-angel planet emblem (守護孩子的小天使) ─────────────────────────────
// A cute, on-brand "guardian angel" rendering of a planet: soft cloud-wings +
// a halo + a glowing orb in the planet's colour with its glyph. Iconographic
// (not photoreal) so it fits the celestial visual language.
function KidGuardianAngel({ planet, size = 132, animate = true }){
  const t = useKidTheme();
  const color = (planet && planet.color) || KID.peri;
  const glyph = (planet && planet.glyph) || '★';
  const gid = 'k-ga-' + ((planet && planet.key) || 'x');
  const wing = (cx, cy, rx, ry) => <ellipse cx={cx} cy={cy} rx={rx} ry={ry} fill="#F4F7FF" opacity="0.92"/>;
  return (
    <div style={{ width:size, height:size, position:'relative',
                  animation: animate ? 'k-floatSlow 7s ease-in-out infinite' : 'none' }}>
      <div style={{position:'absolute', inset:'-16%', borderRadius:'50%',
        background:`radial-gradient(circle, ${glowRGBA(t.glow,0.28)} 0%, rgba(11,26,51,0) 68%)`}}/>
      <svg width={size} height={size} viewBox="0 0 140 140" style={{position:'relative', overflow:'visible', display:'block'}}>
        <defs>
          <radialGradient id={gid} cx="38%" cy="32%" r="72%">
            <stop offset="0%" stopColor="#FFFFFF" stopOpacity="0.95"/>
            <stop offset="42%" stopColor={color}/>
            <stop offset="100%" stopColor={color} stopOpacity="0.78"/>
          </radialGradient>
        </defs>
        {/* cloud wings (behind orb) */}
        <g>
          {wing(104,70,16,11)}{wing(114,80,13,9)}{wing(107,90,11,8)}
          {wing(36,70,16,11)}{wing(26,80,13,9)}{wing(33,90,11,8)}
        </g>
        {/* halo */}
        <ellipse cx="70" cy="30" rx="21" ry="6.5" fill="none" stroke={KID.gold} strokeWidth="3" opacity="0.95"/>
        <ellipse cx="70" cy="30" rx="21" ry="6.5" fill="none" stroke="#FFF6DD" strokeWidth="1" opacity="0.8"/>
        {/* orb */}
        <circle cx="70" cy="80" r="31" fill={`url(#${gid})`}/>
        <circle cx="70" cy="80" r="31" fill="none" stroke="#FFFFFF" strokeWidth="1.4" opacity="0.45"/>
        {/* glyph */}
        <text x="70" y="82" textAnchor="middle" dominantBaseline="central" fontSize="30"
          fontFamily="'Noto Serif TC', serif" fill="#0B1A33" opacity="0.82" style={{fontVariantEmoji:'text'}}>{glyph}</text>
        {/* sparkles */}
        <g style={{transformOrigin:'118px 50px', animation: animate?'k-sparkle 3.2s ease-in-out infinite':'none'}}>
          <path d="M118 44 C118.8 49 120.5 50.5 125 51 C120.5 51.5 118.8 53 118 58 C117.2 53 115.5 51.5 111 51 C115.5 50.5 117.2 49 118 44 Z" fill={KID.moon}/>
        </g>
        <g style={{transformOrigin:'24px 54px', animation: animate?'k-sparkle 3.8s ease-in-out 0.6s infinite':'none'}}>
          <path d="M24 50 C24.6 53.4 25.8 54.4 29 54.8 C25.8 55.2 24.6 56.2 24 59.6 C23.4 56.2 22.2 55.2 19 54.8 C22.2 54.4 23.4 53.4 24 50 Z" fill={KID.aqua}/>
        </g>
      </svg>
    </div>
  );
}

Object.assign(window, {
  KID, KidThemeCtx, KID_PALETTES, useKidTheme, rad, glowRGBA, useInView, KidLazy,
  KidStarfield, SparkleStar, KidConstellation, KidGuardianAngel, KidBrandMark, KidEyebrow,
  KidField, KidPill, KidButton, KidCityInput,
});
