/* 彩云间 — 共享 UI 组件（图标 / 进度 / 撒花 / 云卡片）*/

function Icon({ name, size = 22, stroke = 2, style = {} }) {
  const p = { fill: 'none', stroke: 'currentColor', strokeWidth: stroke, strokeLinecap: 'round', strokeLinejoin: 'round' };
  const paths = {
    sky:    <g {...p}><path d="M6 16a4 4 0 0 1 .6-7.95 5 5 0 0 1 9.65-1.8A3.5 3.5 0 1 1 17 16Z"/><circle cx="6.5" cy="6" r="2.2"/></g>,
    book:   <g {...p}><path d="M4 5.5A2.5 2.5 0 0 1 6.5 3H19v15H6.5A2.5 2.5 0 0 0 4 20.5Z"/><path d="M4 20.5A2.5 2.5 0 0 1 6.5 18H19v3H6.5A2.5 2.5 0 0 1 4 20.5Z"/></g>,
    user:   <g {...p}><circle cx="12" cy="8.5" r="3.5"/><path d="M5.5 19a6.5 6.5 0 0 1 13 0"/></g>,
    camera: <g {...p}><path d="M3 8.5A2 2 0 0 1 5 6.5h1.5L8 4.5h8l1.5 2H19a2 2 0 0 1 2 2V18a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z"/><circle cx="12" cy="13" r="3.6"/></g>,
    sparkle:<g {...p}><path d="M12 3c.6 4.2 1.8 5.4 6 6-4.2.6-5.4 1.8-6 6-.6-4.2-1.8-5.4-6-6 4.2-.6 5.4-1.8 6-6Z"/></g>,
    close:  <g {...p}><path d="M6 6l12 12M18 6L6 18"/></g>,
    back:   <g {...p}><path d="M15 5l-7 7 7 7"/></g>,
    chev:   <g {...p}><path d="M9 5l7 7-7 7"/></g>,
    share:  <g {...p}><path d="M12 15V4M8.5 7.5 12 4l3.5 3.5"/><path d="M6 12v6.5A1.5 1.5 0 0 0 7.5 20h9a1.5 1.5 0 0 0 1.5-1.5V12"/></g>,
    refresh:<g {...p}><path d="M19 8a7 7 0 1 0 1.5 5"/><path d="M20.5 4v4h-4"/></g>,
    lock:   <g {...p}><rect x="5.5" y="10.5" width="13" height="9" rx="2.2"/><path d="M8.5 10.5V8a3.5 3.5 0 0 1 7 0v2.5"/></g>,
    check:  <g {...p}><path d="M5 12.5l4.5 4.5L19 7.5"/></g>,
    pin:    <g {...p}><path d="M12 21s6.5-5.4 6.5-10.5A6.5 6.5 0 0 0 5.5 10.5C5.5 15.6 12 21 12 21Z"/><circle cx="12" cy="10.3" r="2.2"/></g>,
    cal:    <g {...p}><rect x="4" y="5.5" width="16" height="15" rx="2.5"/><path d="M4 9.5h16M8.5 3.5v4M15.5 3.5v4"/></g>,
    flame:  <g {...p}><path d="M12 3c.5 3-2.5 4.2-2.5 7a2.5 2.5 0 0 0 5 0c0-.8-.3-1.5-.3-1.5s2.3 1.4 2.3 4.5a4.5 4.5 0 0 1-9 0C7.5 8.5 12 7 12 3Z"/></g>,
    eye:    <g {...p}><path d="M2.5 12S6 6 12 6s9.5 6 9.5 6-3.5 6-9.5 6-9.5-6-9.5-6Z"/><circle cx="12" cy="12" r="2.6"/></g>,
    medal:  <g {...p}><circle cx="12" cy="14" r="5"/><path d="M8.5 9.3 6.5 3.5M15.5 9.3 17.5 3.5M12 12.2l.9 1.7 1.9.2-1.4 1.3.4 1.9-1.8-1-1.8 1 .4-1.9-1.4-1.3 1.9-.2Z"/></g>,
  };
  return <svg width={size} height={size} viewBox="0 0 24 24" style={style}>{paths[name] || null}</svg>;
}

// 等级进度环
function ProgressRing({ pct = 0, size = 64, stroke = 4, children }) {
  const r = (size - stroke) / 2, c = 2 * Math.PI * r;
  return (
    <div style={{ position:'relative', width:size, height:size, display:'grid', placeItems:'center' }}>
      <svg width={size} height={size} style={{ position:'absolute', transform:'rotate(-90deg)' }}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--cy-line)" strokeWidth={stroke}/>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--cy-accent)" strokeWidth={stroke}
          strokeLinecap="round" strokeDasharray={c} strokeDashoffset={c*(1-pct)}
          style={{ transition:'stroke-dashoffset .9s cubic-bezier(.2,.8,.2,1)' }}/>
      </svg>
      {children}
    </div>
  );
}

function ProgressBar({ pct = 0, h = 8 }) {
  return (
    <div style={{ height:h, borderRadius:99, background:'var(--cy-line)', overflow:'hidden' }}>
      <div style={{ height:'100%', width:`${Math.round(pct*100)}%`, borderRadius:99,
        background:'linear-gradient(90deg, var(--cy-accent2), var(--cy-accent))',
        transition:'width 1s cubic-bezier(.2,.8,.2,1)' }}/>
    </div>
  );
}

const RARITY = {
  common:   { label:'常见', color:'#6f9bc0' },
  uncommon: { label:'少见', color:'#cf8f4e' },
  rare:     { label:'稀有', color:'#b06ec0' },
};
function RarityTag({ rarity, small }) {
  const r = RARITY[rarity] || RARITY.common;
  return (
    <span style={{ display:'inline-flex', alignItems:'center', gap:5,
      fontSize: small?11:12.5, fontWeight:600, color:r.color,
      background:r.color+'1c', padding: small?'2px 8px':'3px 10px', borderRadius:99 }}>
      <span style={{ width:6, height:6, borderRadius:99, background:r.color }}/>{r.label}
    </span>
  );
}

// 撒花庆祝（云朵 + 花瓣 + 星点）
function Petals({ show, count = 22 }) {
  const items = React.useMemo(() => Array.from({ length: count }).map((_, i) => ({
    x: Math.random()*100, d: Math.random()*0.5, dur: 2.4+Math.random()*1.8,
    s: 0.6+Math.random()*0.9, rot: (Math.random()*2-1)*60,
    kind: ['petal','petal','spark','puff'][i%4],
    hue: ['#f7c6b0','#f3a6c0','#f6d98a','#bfe0f5'][i%4],
  })), [count]);
  if (!show) return null;
  return (
    <div style={{ position:'absolute', inset:0, overflow:'hidden', pointerEvents:'none', zIndex:60 }}>
      {items.map((it, i) => (
        <div key={i} style={{
          position:'absolute', top:-30, left:`${it.x}%`,
          animation:`cy-fall ${it.dur}s cubic-bezier(.3,.5,.5,1) ${it.d}s forwards`,
          transform:`scale(${it.s})`,
        }}>
          {it.kind === 'spark'
            ? <div style={{ color:it.hue }}><Icon name="sparkle" size={16}/></div>
            : it.kind === 'puff'
            ? <div style={{ width:18, height:11, borderRadius:99, background:it.hue, opacity:.9, boxShadow:`0 0 0 4px ${it.hue}55` }}/>
            : <div style={{ width:13, height:16, background:it.hue, borderRadius:'60% 60% 60% 0', transform:`rotate(${it.rot}deg)` }}/>}
        </div>
      ))}
    </div>
  );
}

// 锁定剪影 / 已收集缩略
function CloudThumb({ cloud, locked, onClick, h = 96 }) {
  return (
    <button onClick={onClick} className="cy-tap" style={{
      border:'none', cursor:'pointer', textAlign:'left', width:'100%',
      background: locked ? 'var(--cy-card-dim)' : 'var(--cy-card)',
      borderRadius:'var(--cy-r)', padding:'12px 12px 11px',
      boxShadow: locked ? 'none' : 'var(--cy-shadow)',
      display:'flex', flexDirection:'column', gap:6,
    }}>
      <div style={{ height:h, display:'grid', placeItems:'center', position:'relative' }}>
        {locked ? (
          <div style={{ width:'72%', height:'62%', borderRadius:'50% 50% 46% 46%',
            background:'var(--cy-line)', display:'grid', placeItems:'center', color:'var(--cy-ink-soft)', opacity:.7 }}>
            <Icon name="lock" size={22}/>
          </div>
        ) : (
          <CloudArt shape={cloud.art.shape} tone={cloud.art.tone} style={{ width:'100%', height:'100%' }}/>
        )}
      </div>
      {locked ? (
        <div style={{ fontFamily:'var(--cy-serif)', fontSize:15, color:'var(--cy-ink-soft)' }}>？ 待发现</div>
      ) : (
        <div style={{ display:'flex', flexDirection:'column', gap:2 }}>
          <div style={{ fontFamily:'var(--cy-serif)', fontSize:16, color:'var(--cy-ink)', fontWeight:600 }}>{cloud.name}</div>
          <div style={{ fontSize:11.5, color:'var(--cy-ink-soft)', letterSpacing:.3 }}>{cloud.latin}</div>
        </div>
      )}
    </button>
  );
}

Object.assign(window, { Icon, ProgressRing, ProgressBar, RarityTag, RARITY, Petals, CloudThumb });

// ── 头像预设 ─────────────────────────────────────────────
const CY_AVATARS = [
  { id:0, name:'白云', bg:'linear-gradient(140deg,#9fcef2,#c7e4f9)' },
  { id:1, name:'暖阳', bg:'linear-gradient(140deg,#ffd58c,#ffb583)' },
  { id:2, name:'弯月', bg:'linear-gradient(140deg,#48699b,#1e3357)' },
  { id:3, name:'彩虹', bg:'linear-gradient(140deg,#bfe6db,#ecd6f0)' },
  { id:4, name:'细雨', bg:'linear-gradient(140deg,#a6bccd,#cad7e2)' },
  { id:5, name:'星河', bg:'linear-gradient(140deg,#5a4690,#27315f)' },
];

function AvatarMotif({ id }) {
  const W = '#ffffff';
  switch (id) {
    case 1: // 暖阳
      return <g>
        <circle cx="20" cy="19" r="7.5" fill="#fff3cf"/>
        {[0,45,90,135,180,225,270,315].map(a => {
          const r = a*Math.PI/180;
          return <line key={a} x1={20+Math.cos(r)*10} y1={19+Math.sin(r)*10} x2={20+Math.cos(r)*13} y2={19+Math.sin(r)*13} stroke="#fff3cf" strokeWidth="2" strokeLinecap="round"/>;
        })}
        <g fill={W}><circle cx="26" cy="32" r="7"/><circle cx="33" cy="32" r="9"/><circle cx="20" cy="33" r="6"/><rect x="20" y="31" width="20" height="9" rx="4.5"/></g>
      </g>;
    case 2: // 弯月
      return <g>
        <path d="M30 12a13 13 0 1 0 0 24 10 10 0 0 1 0-24Z" fill="#fbf4dc"/>
        <path d="M16 14l1.3 3 3 1.3-3 1.3-1.3 3-1.3-3-3-1.3 3-1.3Z" fill={W}/>
        <circle cx="33" cy="30" r="1.6" fill={W}/>
      </g>;
    case 3: // 彩虹
      return <g fill="none">
        <path d="M11 32a13 13 0 0 1 26 0" stroke="#f29ba8" strokeWidth="3"/>
        <path d="M15 32a9 9 0 0 1 18 0" stroke="#f6cf86" strokeWidth="3"/>
        <path d="M19 32a5 5 0 0 1 10 0" stroke="#9fd2c3" strokeWidth="3"/>
        <g fill={W}><circle cx="14" cy="33" r="5"/><circle cx="34" cy="33" r="5"/></g>
      </g>;
    case 4: // 细雨
      return <g>
        <g fill={W}><circle cx="20" cy="20" r="7"/><circle cx="29" cy="20" r="9"/><circle cx="14" cy="21" r="5.5"/><rect x="14" y="18" width="20" height="9" rx="4.5"/></g>
        <g stroke="#dcecf7" strokeWidth="2.4" strokeLinecap="round"><line x1="17" y1="31" x2="15" y2="36"/><line x1="24" y1="31" x2="22" y2="37"/><line x1="31" y1="31" x2="29" y2="36"/></g>
      </g>;
    case 5: // 星河
      return <g fill={W}>
        <path d="M24 11l1.8 4.4 4.4 1.8-4.4 1.8L24 23.4l-1.8-4.4-4.4-1.8 4.4-1.8Z"/>
        <path d="M33 26l1 2.4 2.4 1-2.4 1-1 2.4-1-2.4-2.4-1 2.4-1Z" opacity=".9"/>
        <circle cx="14" cy="30" r="1.8" opacity=".85"/>
        <circle cx="30" cy="15" r="1.3" opacity=".7"/>
      </g>;
    default: // 白云
      return <g fill={W}>
        <circle cx="20" cy="24" r="8"/><circle cx="30" cy="23" r="10"/><circle cx="13" cy="26" r="6"/>
        <rect x="13" y="24" width="24" height="11" rx="5.5"/>
      </g>;
  }
}

function Avatar({ id = 0, size = 48, ring = false }) {
  const a = CY_AVATARS[id] || CY_AVATARS[0];
  return (
    <div style={{ width:size, height:size, borderRadius:99, background:a.bg, overflow:'hidden',
      boxShadow: ring ? '0 0 0 3px var(--cy-card)' : 'none' }}>
      <svg viewBox="0 0 48 48" style={{ width:'100%', height:'100%' }} aria-hidden="true">
        <AvatarMotif id={id}/>
      </svg>
    </div>
  );
}

Object.assign(window, { CY_AVATARS, Avatar });
