// ui.jsx — shared primitives. Reads theme via useTheme().
// Exports to window: Ico, Phone, MiniHeader, Capsule, Card, Pill, Seg, Btn,
//   MacroBar, Ring, Photo, Stat, Divider, TabBar

(function injectPressStyle(){
  if (document.getElementById('cc-press-style')) return;
  const s = document.createElement('style'); s.id = 'cc-press-style';
  s.textContent = `.cc-tap{transition:transform .12s ease, box-shadow .2s ease, filter .15s ease; cursor:pointer; -webkit-tap-highlight-color:transparent;}
  .cc-tap:active{transform:scale(.965);}`;
  document.head.appendChild(s);
})();

// ───────────────────────── icons (simple line glyphs) ─────────────────────────
function Ico({ name, size = 22, color = 'currentColor', sw = 1.9, fill = 'none' }) {
  const P = {
    camera: <><path d="M3 8.5A2 2 0 0 1 5 6.5h1.4l1-1.6A1.5 1.5 0 0 1 9.7 4.2h4.6a1.5 1.5 0 0 1 1.3.7l1 1.6H18a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><circle cx="12" cy="12.5" r="3.4"/></>,
    image: <><rect x="3.5" y="4.5" width="17" height="15" rx="3"/><circle cx="8.5" cy="9.5" r="1.6"/><path d="M5 18l4.5-4.5 3 3L16 12l3.5 3.5"/></>,
    upload: <><path d="M12 15.5V4.5"/><path d="M7.5 9 12 4.5 16.5 9"/><path d="M5 16.5v1.5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-1.5"/></>,
    flame: <path d="M12 3.2c.6 2.6-.9 3.8-2 5.2-1.3 1.6-1.6 3-.8 4.2.4-.9 1-1.5 1.9-2 .6 1.7-.6 2.6-.3 4 .2 1.2 1.2 2.2 2.7 2.2 2 0 3.6-1.5 3.6-3.7 0-3.3-2.4-4.2-2-7.2-1.2.5-2 1.4-2.3 2.6-.6-1.9.1-3.6-.8-5.5z"/>,
    timer: <><circle cx="12" cy="13.5" r="6.5"/><path d="M12 13.5V9.8"/><path d="M9.5 3.5h5"/></>,
    leaf: <><path d="M19 5c0 7-4.5 11-11 11 0-7 4.5-11 11-11z"/><path d="M6.5 17.5C9 13 13 10 17 8.5"/></>,
    drop: <path d="M12 3.5s5.5 6 5.5 9.7A5.5 5.5 0 0 1 12 18.7a5.5 5.5 0 0 1-5.5-5.5C6.5 9.5 12 3.5 12 3.5z"/>,
    spark: <path d="M12 3.5l1.7 5 5 1.7-5 1.7L12 17l-1.7-5-5-1.7 5-1.7z"/>,
    chevron: <path d="M9.5 5.5 16 12l-6.5 6.5"/>,
    back: <path d="M14.5 5.5 8 12l6.5 6.5"/>,
    check: <path d="M5 12.5 10 17.5 19 7"/>,
    x: <path d="M6 6l12 12M18 6 6 18"/>,
    scan: <><path d="M4 8.5V6a2 2 0 0 1 2-2h2.5"/><path d="M15.5 4H18a2 2 0 0 1 2 2v2.5"/><path d="M20 15.5V18a2 2 0 0 1-2 2h-2.5"/><path d="M8.5 20H6a2 2 0 0 1-2-2v-2.5"/></>,
    history: <><path d="M4.5 12a7.5 7.5 0 1 1 2.3 5.4"/><path d="M4.5 17v-4.5H9"/><path d="M12 8.5V12l2.6 1.6"/></>,
    home: <><path d="M4 11 12 4.5 20 11"/><path d="M6 9.7V19h12V9.7"/></>,
    user: <><circle cx="12" cy="8.5" r="3.4"/><path d="M5.5 19.5a6.5 6.5 0 0 1 13 0"/></>,
    plus: <path d="M12 5.5v13M5.5 12h13"/>,
    minus: <path d="M5.5 12h13"/>,
    bowl: <><path d="M4 11h16a8 8 0 0 1-16 0z"/><path d="M9 7.5c0-1.2 1-1.6 1.4-2.4M12.5 7.5c0-1.2 1-1.6 1.4-2.4"/></>,
    target: <><circle cx="12" cy="12" r="7.5"/><circle cx="12" cy="12" r="3.2"/></>,
    heart: <path d="M12 19.5S4.5 15 4.5 9.7A3.7 3.7 0 0 1 12 7.4a3.7 3.7 0 0 1 7.5 2.3C19.5 15 12 19.5 12 19.5z"/>,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={fill} stroke={color}
      strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round"
      style={{ display: 'block', flexShrink: 0 }}>
      {P[name] || null}
    </svg>
  );
}

// ───────────────────────── mini-program capsule ─────────────────────────
function Capsule({ dark = false }) {
  const c = dark ? 'rgba(255,255,255,0.85)' : 'rgba(40,34,24,0.7)';
  const bd = dark ? 'rgba(255,255,255,0.28)' : 'rgba(40,34,24,0.14)';
  return (
    <div style={{
      display: 'flex', alignItems: 'center', height: 32, borderRadius: 16,
      border: `1px solid ${bd}`, background: dark ? 'rgba(255,255,255,0.08)' : 'rgba(255,255,255,0.55)',
      backdropFilter: 'blur(6px)',
    }}>
      <div style={{ width: 43, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 5 }}>
        <span style={{ width: 4.5, height: 4.5, borderRadius: 9, background: c }} />
        <span style={{ width: 4.5, height: 4.5, borderRadius: 9, background: c }} />
        <span style={{ width: 4.5, height: 4.5, borderRadius: 9, background: c }} />
      </div>
      <div style={{ width: 0.8, height: 18, background: bd }} />
      <div style={{ width: 43, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <span style={{ width: 14, height: 14, borderRadius: 9, border: `1.6px solid ${c}`, position: 'relative' }}>
          <span style={{ position: 'absolute', inset: 3, borderRadius: 9, border: `1.4px solid ${c}` }} />
        </span>
      </div>
    </div>
  );
}

// ───────────────────────── phone shell ─────────────────────────
function Phone({ children, dark = false }) {
  const t = useTheme();
  return (
    <IOSDevice dark={dark}>
      <div className="cc-scroll" style={{
        position: 'absolute', inset: 0, overflowY: 'auto',
        background: dark ? '#15110C' : t.bg,
        fontFamily: "'Noto Sans SC','PingFang SC',sans-serif",
      }}>
        {children}
      </div>
    </IOSDevice>
  );
}

function MiniHeader({ title, onBack, dark = false, bg, ink }) {
  const t = useTheme();
  const fg = ink || (dark ? '#fff' : t.ink);
  return (
    <div style={{
      position: 'sticky', top: 0, zIndex: 30,
      paddingTop: 50, paddingBottom: 8,
      background: bg || (dark ? 'rgba(21,17,12,0.86)' : 'rgba(255,255,255,0.82)'),
      backdropFilter: 'blur(14px)',
      borderBottom: `1px solid ${dark ? 'rgba(255,255,255,0.06)' : t.line}`,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', height: 40, padding: '0 14px 0 16px' }}>
        <div style={{ width: 86, display: 'flex', alignItems: 'center' }}>
          {onBack && (
            <div className="cc-tap" onClick={onBack} style={{
              width: 34, height: 34, borderRadius: 17, marginLeft: -6,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              background: dark ? 'rgba(255,255,255,0.08)' : t.soft,
            }}>
              <Ico name="back" size={20} color={t.primary} sw={2.2} />
            </div>
          )}
        </div>
        <div className="num" style={{
          flex: 1, textAlign: 'center', fontFamily: t.display,
          fontWeight: 700, fontSize: 18, color: fg, letterSpacing: '.01em',
        }}>{title}</div>
        <div style={{ width: 86, display: 'flex', justifyContent: 'flex-end' }}>
          <Capsule dark={dark} />
        </div>
      </div>
    </div>
  );
}

// ───────────────────────── building blocks ─────────────────────────
function Card({ children, style = {}, pad = 16, onClick, tap }) {
  const t = useTheme();
  return (
    <div className={tap ? 'cc-tap' : undefined} onClick={onClick} style={{
      background: t.surface, borderRadius: t.R, padding: pad,
      boxShadow: '0 1px 2px rgba(43,34,24,0.04), 0 8px 24px -12px rgba(43,34,24,0.12)',
      border: `1px solid ${t.line}`, ...style,
    }}>{children}</div>
  );
}

function Pill({ children, color, bg, style = {} }) {
  const t = useTheme();
  return (
    <span className="num" style={{
      display: 'inline-flex', alignItems: 'center', gap: 5,
      padding: '4px 11px', borderRadius: 999, fontWeight: 600, fontSize: 13,
      color: color || t.dark, background: bg || t.soft, fontFamily: t.display,
      whiteSpace: 'nowrap',
      ...style,
    }}>{children}</span>
  );
}

function Seg({ value, options, onChange, full = true }) {
  const t = useTheme();
  return (
    <div style={{
      display: 'flex', gap: 4, padding: 4, borderRadius: t.rSm + 4,
      background: t.bg, border: `1px solid ${t.line}`, width: full ? '100%' : 'auto',
    }}>
      {options.map(o => {
        const on = o === value;
        return (
          <div key={o} className="cc-tap" onClick={() => onChange && onChange(o)} style={{
            flex: full ? 1 : 'none', textAlign: 'center', padding: '8px 14px',
            borderRadius: t.rSm, fontWeight: 600, fontSize: 14,
            fontFamily: t.display,
            color: on ? '#fff' : t.inkSoft,
            background: on ? t.primary : 'transparent',
            boxShadow: on ? '0 4px 12px -4px ' + t.primary : 'none',
            transition: 'all .18s ease',
          }}>{o}</div>
        );
      })}
    </div>
  );
}

function Btn({ children, onClick, kind = 'primary', icon, style = {}, big = false }) {
  const t = useTheme();
  const base = {
    display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
    fontFamily: t.display, fontWeight: 700, borderRadius: 999,
    fontSize: big ? 17 : 15, padding: big ? '16px 22px' : '12px 18px',
    width: '100%', border: 'none',
  };
  const kinds = {
    primary: { background: t.primary, color: '#fff', boxShadow: `0 10px 24px -8px ${t.primary}` },
    soft: { background: t.soft, color: t.dark },
    ghost: { background: 'transparent', color: t.inkSoft, border: `1px solid ${t.line}` },
    dark: { background: t.ink, color: '#fff' },
  };
  return (
    <button className="cc-tap" onClick={onClick} style={{ ...base, ...kinds[kind], ...style }}>
      {icon && <Ico name={icon} size={big ? 22 : 19} color={kinds[kind].color} sw={2.1} />}
      {children}
    </button>
  );
}

function MacroBar({ label, grams, pct, color, kcal }) {
  const t = useTheme();
  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
        <span style={{ fontSize: 13, color: t.inkSoft, fontWeight: 500 }}>{label}</span>
        <span className="num" style={{ fontFamily: t.display, fontWeight: 600, fontSize: 14, color: t.ink }}>
          {grams}<span style={{ fontSize: 11, color: t.inkSoft }}>g</span>
          <span style={{ color: t.inkFaint, fontWeight: 500, marginLeft: 6, fontSize: 12 }}>{pct}%</span>
        </span>
      </div>
      <div style={{ height: 9, borderRadius: 9, background: t.bg, overflow: 'hidden' }}>
        <div style={{
          height: '100%', width: pct + '%', background: color, borderRadius: 9,
        }} />
      </div>
    </div>
  );
}

function Ring({ pct = 60, size = 132, stroke = 13, color, track, children }) {
  const t = useTheme();
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const off = c * (1 - Math.min(pct, 100) / 100);
  return (
    <div style={{ position: 'relative', width: size, height: size }}>
      <svg width={size} height={size} style={{ transform: 'rotate(-90deg)' }}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={track || t.bg} strokeWidth={stroke} />
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color || t.primary}
          strokeWidth={stroke} strokeLinecap="round" strokeDasharray={c} strokeDashoffset={off}
          style={{ transition: 'stroke-dashoffset 1s cubic-bezier(.3,1,.4,1)' }} />
      </svg>
      <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column',
        alignItems: 'center', justifyContent: 'center' }}>{children}</div>
    </div>
  );
}

function Photo({ label = '美食照片', h = 150, r, style = {} }) {
  const t = useTheme();
  return (
    <div className="cc-ph" style={{
      height: h, borderRadius: r != null ? r : t.rSm + 4, background: t.soft,
      backgroundImage: 'repeating-linear-gradient(135deg, rgba(0,0,0,0.04) 0 11px, rgba(0,0,0,0) 11px 22px)',
      ...style,
    }}>
      <span style={{ fontFamily: t.display }}>{label}</span>
    </div>
  );
}

function Divider() { const t = useTheme(); return <div style={{ height: 1, background: t.line, margin: '14px 0' }} />; }

Object.assign(window, { Ico, Capsule, Phone, MiniHeader, Card, Pill, Seg, Btn, MacroBar, Ring, Photo, Divider });
