// components.jsx — UI partagée : icônes, anneaux, cartes, segmented, toggles
const { useState, useEffect, useRef } = React;

// ── Icônes (line, 24×24) ──────────────────────────────────────
const ICON_PATHS = {
  today:   <><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M5 5l1.5 1.5M17.5 17.5L19 19M19 5l-1.5 1.5M6.5 17.5L5 19"/></>,
  meals:   <><path d="M5 3v18M5 9c0-3 .5-6 0-6M8 3v6a1 1 0 01-2 0M7 3v6"/><path d="M17 3c-1.5 0-2.5 2-2.5 5s1 4 2.5 4 2.5-1 2.5-4-1-5-2.5-5zM17 12v9"/></>,
  courses: <><circle cx="9" cy="20" r="1.4"/><circle cx="18" cy="20" r="1.4"/><path d="M2 3h2.5l2.2 12.3a1.5 1.5 0 001.5 1.2h9a1.5 1.5 0 001.5-1.2L21 7H6"/></>,
  progress:<><path d="M3 3v18h18"/><path d="M7 14l4-5 3.5 3L20 6"/></>,
  supps:   <><rect x="3.5" y="9" width="17" height="6" rx="3" transform="rotate(-45 12 12)"/><path d="M9.5 9.5l5 5"/></>,
  flame:   <><path d="M12 3s5 4 5 9a5 5 0 11-10 0c0-1.5.7-2.8 1.5-3.5C8.5 10 9 12 10 12c1.5 0 1-4 2-9z"/></>,
  camera:  <><path d="M3 8a2 2 0 012-2h2l1.5-2h7L17 6h2a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2z"/><circle cx="12" cy="12.5" r="3.5"/></>,
  plus:    <><path d="M12 5v14M5 12h14"/></>,
  minus:   <><path d="M5 12h14"/></>,
  check:   <><path d="M4 12.5l5 5 11-11"/></>,
  drop:    <><path d="M12 3c3 4 6 7 6 10.5A6 6 0 016 13.5C6 10 9 7 12 3z"/></>,
  chevron: <><path d="M9 6l6 6-6 6"/></>,
  scan:    <><path d="M4 8V6a2 2 0 012-2h2M16 4h2a2 2 0 012 2v2M20 16v2a2 2 0 01-2 2h-2M8 20H6a2 2 0 01-2-2v-2"/><path d="M4 12h16"/></>,
  scale:   <><circle cx="12" cy="12" r="9"/><path d="M12 12l3.5-4.5"/><circle cx="12" cy="12" r="1.2" fill="currentColor"/></>,
  info:    <><circle cx="12" cy="12" r="9"/><path d="M12 11v5M12 8h.01"/></>,
  close:   <><path d="M6 6l12 12M18 6L6 18"/></>,
  spark:   <><path d="M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8z"/><path d="M18 16l.7 2 .7-2 2-.7-2-.7-.7-2-.7 2-2 .7z" opacity="0.7"/></>,
  sunrise: <><path d="M12 4v3M5 9l1.5 1.5M19 9l-1.5 1.5M3 18h18M7 18a5 5 0 0110 0"/></>,
  bowl:    <><path d="M3 11h18a8 8 0 01-8 8h-2a8 8 0 01-8-8z"/><path d="M12 7c0-1.5 1-2.5 1-2.5M9 7c0-1 .5-1.5.5-1.5"/></>,
  apple:   <><path d="M12 7c-1.5-2-4-2.5-5.5-1C4.5 7.5 5 12 7 15c1 1.5 2 2.5 3 2.5s1.5-.8 2-.8 1 .8 2 .8 2-1 3-2.5c2-3 2.5-7.5.5-9-1.5-1-3.5-.5-5 1z"/><path d="M12 7c.5-1.5 1.5-2.5 2.5-2.8"/></>,
  moon:    <><path d="M20 14.5A8 8 0 119.5 4a6.5 6.5 0 0010.5 10.5z"/></>,
  fish:    <><path d="M3 12c3-5 9-6 14-3-1 1.2-1 4.8 0 6-5 3-11 2-14-3z"/><path d="M17 9l4-3v12l-4-3M8 12h.01"/></>,
  milk:    <><path d="M8 3h8v3l1 3v11a1 1 0 01-1 1H8a1 1 0 01-1-1V9l1-3z"/><path d="M7 9h10"/></>,
  box:     <><path d="M3 8l9-5 9 5v8l-9 5-9-5z"/><path d="M3 8l9 5 9-5M12 13v8"/></>,
  lock:    <><rect x="5" y="11" width="14" height="9" rx="2"/><path d="M8 11V8a4 4 0 018 0v3"/></>,
  user:    <><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 4-6 8-6s8 2 8 6"/></>,
};

function Icon({ name, size = 22, color = 'currentColor', sw = 1.8, fill = false, style }) {
  const p = ICON_PATHS[name] || null;
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={fill ? color : 'none'}
      stroke={fill ? 'none' : color} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round"
      style={{ display: 'block', flexShrink: 0, ...style }}>{p}</svg>
  );
}

// ── Anneau de progression ─────────────────────────────────────
function Ring({ value, max, size = 132, stroke = 13, color, track, children, delay = 120 }) {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const pct = Math.min(value / max, 1);
  const [draw, setDraw] = useState(0);
  // rAF tween (CSS transitions on SVG dash can freeze at the start frame)
  useEffect(() => {
    let raf, start;
    const dur = 1000, from = 0, to = pct;
    const ease = x => 1 - Math.pow(1 - x, 3);
    const tick = (ts) => {
      if (start == null) start = ts;
      const k = Math.min((ts - start) / dur, 1);
      setDraw(from + (to - from) * ease(k));
      if (k < 1) raf = requestAnimationFrame(tick);
    };
    const t = setTimeout(() => { raf = requestAnimationFrame(tick); }, delay);
    return () => { clearTimeout(t); cancelAnimationFrame(raf); };
  }, [pct, delay]);
  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} strokeWidth={stroke} />
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth={stroke}
          strokeLinecap="round"
          style={{ strokeDasharray: c, strokeDashoffset: c * (1 - draw) }} />
      </svg>
      <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column',
        alignItems: 'center', justifyContent: 'center' }}>{children}</div>
    </div>
  );
}

// ── Mini barre (glucides / lipides) ──────────────────────────
function MacroBar({ label, value, max, color, t }) {
  const pct = Math.min(value / max, 1) * 100;
  return (
    <div style={{ flex: 1 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 6 }}>
        <span style={{ fontSize: 12, fontWeight: 600, color: t.textMuted, letterSpacing: 0.2 }}>{label}</span>
        <span style={{ fontSize: 12, fontWeight: 700, color: t.text, fontFamily: 'Space Grotesk, sans-serif' }}>
          {value}<span style={{ color: t.textFaint, fontWeight: 500 }}>/{max}g</span></span>
      </div>
      <div style={{ height: 7, borderRadius: 99, background: t.ringTrack, overflow: 'hidden' }}>
        <div style={{ height: '100%', width: pct + '%', background: color, borderRadius: 99,
          transition: 'width 1s cubic-bezier(.4,0,.1,1)' }} />
      </div>
    </div>
  );
}

// ── Carte ─────────────────────────────────────────────────────
function Card({ children, t, style, onClick, pad = 18 }) {
  return (
    <div onClick={onClick} style={{
      background: t.surface, borderRadius: 22, padding: pad,
      border: `1px solid ${t.borderSoft}`, boxShadow: t.shadow,
      cursor: onClick ? 'pointer' : 'default', ...style }}>{children}</div>
  );
}

// ── Pastille checkbox ronde ──────────────────────────────────
function CheckDot({ on, color, t, size = 26 }) {
  return (
    <div style={{ width: size, height: size, borderRadius: 99, flexShrink: 0,
      border: on ? 'none' : `2px solid ${t.border}`, background: on ? color : 'transparent',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      transition: 'all .2s' }}>
      {on && <Icon name="check" size={size * 0.6} color={t.onAccent} sw={2.6} />}
    </div>
  );
}

// ── Segmented / chips ─────────────────────────────────────────
function Chips({ items, active, onPick, t }) {
  return (
    <div style={{ display: 'flex', gap: 8, overflowX: 'auto', paddingBottom: 2,
      scrollbarWidth: 'none', msOverflowStyle: 'none' }}>
      {items.map(it => {
        const on = active === it.id;
        return (
          <button key={it.id} onClick={() => onPick(it.id)} style={{
            flexShrink: 0, padding: '9px 16px', borderRadius: 99, border: 'none', cursor: 'pointer',
            fontSize: 13.5, fontWeight: 600, fontFamily: 'inherit',
            background: on ? t.text : t.surfaceAlt,
            color: on ? t.bg : t.textMuted, transition: 'all .18s' }}>{it.label}</button>
        );
      })}
    </div>
  );
}


// ── Image de plat (générée IA via backend, fallback icône) ────
function useMealImage(mealName) {
  const [url, setUrl] = useState(null);
  useEffect(() => {
    let alive = true;
    if (!window.FuelFitAPI) return;
    window.FuelFitAPI.getMealImage(mealName)
      .then(u => { if (alive) setUrl(u); })
      .catch(() => {}); // fallback silencieux sur l'icône
    return () => { alive = false; };
  }, [mealName]);
  return url;
}

function MealImage({ meal, t, size = 54, radius = 15 }) {
  const url = useMealImage(meal.name);
  return (
    <div style={{ width: size, height: size, borderRadius: radius, flexShrink: 0, position: 'relative', overflow: 'hidden',
      background: `linear-gradient(140deg, color-mix(in srgb, ${t[meal.tint]} 32%, ${t.surface}), color-mix(in srgb, ${t[meal.tint]} 12%, ${t.surface}))`,
      display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      {url
        ? <img src={url} alt={meal.name} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
        : <Icon name={meal.icon} size={size * 0.48} color={t[meal.tint]} />}
    </div>
  );
}

Object.assign(window, { Icon, Ring, MacroBar, Card, CheckDot, Chips, MealImage, useMealImage });
