// Shared UI primitives: Mascot, Icons, Avatar, helpers.

const Mascot = ({ size = 40, mood = "default" }) => (
  <svg width={size} height={size} viewBox="0 0 64 64" aria-hidden="true">
    {/* body */}
    <ellipse cx="32" cy="38" rx="22" ry="20" fill="#3a2a1a"/>
    {/* ears */}
    <circle cx="14" cy="20" r="7" fill="#3a2a1a"/>
    <circle cx="50" cy="20" r="7" fill="#3a2a1a"/>
    <circle cx="14" cy="20" r="3" fill="#E8682C"/>
    <circle cx="50" cy="20" r="3" fill="#E8682C"/>
    {/* face mask */}
    <ellipse cx="32" cy="42" rx="14" ry="11" fill="#d9b894"/>
    {/* eyes */}
    <circle cx="25" cy="34" r="2.4" fill="#1a0f08"/>
    <circle cx="39" cy="34" r="2.4" fill="#1a0f08"/>
    <circle cx="25.7" cy="33.3" r="0.8" fill="#fff"/>
    <circle cx="39.7" cy="33.3" r="0.8" fill="#fff"/>
    {/* nose */}
    <ellipse cx="32" cy="42" rx="2.6" ry="2" fill="#1a0f08"/>
    {/* mouth */}
    <path d={mood === "happy" ? "M28 46 Q32 50 36 46" : "M28 46 Q32 48 36 46"}
          stroke="#1a0f08" strokeWidth="1.3" fill="none" strokeLinecap="round"/>
  </svg>
);

const Icon = ({ name, size = 18, stroke = 1.6, color = "currentColor" }) => {
  const props = { width: size, height: size, viewBox: "0 0 24 24", fill: "none",
    stroke: color, strokeWidth: stroke, strokeLinecap: "round", strokeLinejoin: "round" };
  switch (name) {
    case "home": return <svg {...props}><path d="M3 11 12 3l9 8v10a1 1 0 0 1-1 1h-5v-7h-6v7H4a1 1 0 0 1-1-1z"/></svg>;
    case "list": return <svg {...props}><rect x="4" y="4" width="16" height="16" rx="2"/><path d="M8 9h8M8 13h8M8 17h5"/></svg>;
    case "calendar": return <svg {...props}><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 10h18M8 3v4M16 3v4"/></svg>;
    case "bolt": return <svg {...props}><path d="M13 2 4 14h7l-1 8 9-12h-7z"/></svg>;
    case "flex": return <svg {...props}><path d="M4 14c2 0 4-1 4-4 0-3 2-5 5-5s5 2 5 5v2c0 4-3 7-7 7-3 0-5-1-7-2"/><path d="M11 9c1.5 1 2 2.5 2 4"/></svg>;
    case "chart": return <svg {...props}><path d="M3 3v18h18"/><path d="M7 14l4-4 4 4 5-6"/></svg>;
    case "heart": return <svg {...props}><path d="M12 21s-7-4.5-9.5-9C1 9 3 5 6.5 5c2 0 3.5 1 5.5 3 2-2 3.5-3 5.5-3C21 5 23 9 21.5 12 19 16.5 12 21 12 21z"/></svg>;
    case "apple": return <svg {...props}><path d="M12 6c-1-3-4-3-5-1 2 0 3 1 3 3M16 8c-2 0-3 1-4 1s-2-1-4-1c-3 0-4 3-4 6 0 4 3 8 5 8 1 0 2-1 3-1s2 1 3 1c2 0 5-4 5-8 0-3-1-6-4-6z"/></svg>;
    case "user": return <svg {...props}><circle cx="12" cy="8" r="4"/><path d="M4 21c0-4 4-7 8-7s8 3 8 7"/></svg>;
    case "shield": return <svg {...props}><path d="M12 3 4 6v6c0 5 3.5 8 8 9 4.5-1 8-4 8-9V6z"/></svg>;
    case "search": return <svg {...props}><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>;
    case "plus": return <svg {...props}><path d="M12 5v14M5 12h14"/></svg>;
    case "minus": return <svg {...props}><path d="M5 12h14"/></svg>;
    case "check": return <svg {...props}><path d="M5 12l5 5L20 6"/></svg>;
    case "x": return <svg {...props}><path d="M6 6l12 12M18 6 6 18"/></svg>;
    case "play": return <svg {...props}><path d="M6 4l14 8-14 8z" fill={color} stroke="none"/></svg>;
    case "pause": return <svg {...props}><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></svg>;
    case "chevron-right": return <svg {...props}><path d="m9 6 6 6-6 6"/></svg>;
    case "chevron-left": return <svg {...props}><path d="m15 6-6 6 6 6"/></svg>;
    case "chevron-down": return <svg {...props}><path d="m6 9 6 6 6-6"/></svg>;
    case "more": return <svg {...props}><circle cx="5" cy="12" r="1.5"/><circle cx="12" cy="12" r="1.5"/><circle cx="19" cy="12" r="1.5"/></svg>;
    case "timer": return <svg {...props}><circle cx="12" cy="13" r="8"/><path d="M12 9v4l2 2M9 2h6"/></svg>;
    case "scale": return <svg {...props}><path d="M4 21h16l-2-12H6z"/><path d="M9 9V6a3 3 0 0 1 6 0v3"/></svg>;
    case "fire": return <svg {...props}><path d="M12 3c0 4-4 5-4 9 0 4 2 7 4 7s4-3 4-7c0-2-1-4-2-5 1 0 2 1 2 3 0-3-2-7-4-7z"/></svg>;
    case "trophy": return <svg {...props}><path d="M8 4h8v6a4 4 0 0 1-8 0z"/><path d="M5 4h3v3a3 3 0 0 1-3-3zM16 4h3a3 3 0 0 1-3 3zM10 14h4l1 4H9z"/></svg>;
    case "trending-up": return <svg {...props}><path d="m3 17 6-6 4 4 8-8"/><path d="M14 7h7v7"/></svg>;
    case "filter": return <svg {...props}><path d="M3 5h18l-7 8v6l-4-2v-4z"/></svg>;
    case "video": return <svg {...props}><rect x="2" y="6" width="14" height="12" rx="2"/><path d="m22 8-6 4 6 4z"/></svg>;
    case "image": return <svg {...props}><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m3 17 5-5 4 4 3-3 6 6"/></svg>;
    case "edit": return <svg {...props}><path d="M11 4H4v16h16v-7"/><path d="m14 3 7 7-9 9H5v-7z"/></svg>;
    case "copy": return <svg {...props}><rect x="8" y="8" width="12" height="12" rx="2"/><path d="M16 8V4H4v12h4"/></svg>;
    case "trash": return <svg {...props}><path d="M3 6h18M8 6V4h8v2M6 6v14h12V6"/></svg>;
    case "logout": return <svg {...props}><path d="M9 4H5v16h4M16 8l4 4-4 4M20 12H10"/></svg>;
    case "settings": return <svg {...props}><circle cx="12" cy="12" r="3"/><path d="M19 12a7 7 0 0 0-.1-1.2l2-1.5-2-3.5-2.4.9a7 7 0 0 0-2-1.2L14 3h-4l-.5 2.5a7 7 0 0 0-2 1.2L5 5.8l-2 3.5 2 1.5A7 7 0 0 0 5 12c0 .4 0 .8.1 1.2l-2 1.5 2 3.5 2.4-.9a7 7 0 0 0 2 1.2L10 21h4l.5-2.5a7 7 0 0 0 2-1.2l2.4.9 2-3.5-2-1.5c0-.4.1-.8.1-1.2z"/></svg>;
    case "users": return <svg {...props}><circle cx="9" cy="8" r="3.5"/><path d="M3 20c0-3 3-5 6-5s6 2 6 5"/><circle cx="17" cy="8" r="2.5"/><path d="M16 20c0-2 2-4 5-4"/></svg>;
    case "database": return <svg {...props}><ellipse cx="12" cy="5" rx="8" ry="3"/><path d="M4 5v6c0 1.7 3.6 3 8 3s8-1.3 8-3V5M4 11v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6"/></svg>;
    case "report": return <svg {...props}><path d="M14 3H6v18h12V8z"/><path d="M14 3v5h5M9 13h6M9 17h4"/></svg>;
    default: return null;
  }
};

const Avatar = ({ name, size = 32, color }) => {
  const initial = (name || "?").charAt(0).toUpperCase();
  const colors = ["#E8682C","#3B7DD8","#5B9E3C","#9B5BC2","#D8A93B","#D24F6E"];
  const bg = color || colors[(name || "").charCodeAt(0) % colors.length];
  return (
    <div className="avatar" style={{
      width: size, height: size, borderRadius: "50%",
      background: bg, color: "#fff", display: "flex",
      alignItems: "center", justifyContent: "center",
      fontWeight: 600, fontSize: size * 0.42,
      flexShrink: 0,
    }}>{initial}</div>
  );
};

// Tiny sparkline SVG
const Sparkline = ({ data, w = 80, h = 24, color = "#E8682C", fill = true }) => {
  if (!data || data.length < 2) return null;
  const min = Math.min(...data), max = Math.max(...data);
  const range = max - min || 1;
  const pts = data.map((v, i) => [
    (i / (data.length - 1)) * w,
    h - ((v - min) / range) * h * 0.85 - h * 0.075,
  ]);
  const path = pts.map((p, i) => `${i === 0 ? "M" : "L"}${p[0].toFixed(1)} ${p[1].toFixed(1)}`).join(" ");
  const area = path + ` L${w} ${h} L0 ${h} Z`;
  return (
    <svg width={w} height={h} style={{ display: "block" }}>
      {fill && <path d={area} fill={color} opacity="0.12"/>}
      <path d={path} fill="none" stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
};

// Anatomical silhouette with gendered front+back views and clickable muscle
// regions. Pass gender ("male" | "female") + view ("front" | "back") + selected
// + onSelect. Renders detailed muscle striations on top of a body base.
const MuscleSilhouette = ({ selected, onSelect, gender = "male", view = "front", lang = "en" }) => {
  const SKIN = "#E8D6C2";
  const SKIN_SHADE = "#C9A98A";
  const STROKE = "#8C6F52";
  const HIGHLIGHT = "var(--primary, #C8501F)";
  const HIGHLIGHT_DIM = "rgba(200,80,31,0.18)";
  const HIGHLIGHT_HOVER = "rgba(200,80,31,0.4)";

  // Body silhouette path tuned per gender (M = wider shoulders, narrow hips; F = narrower shoulders, wider hips, narrower waist)
  const body = gender === "female"
    ? "M68 88 Q78 78 92 84 Q100 80 108 84 Q122 78 132 88 L138 112 L130 134 L116 130 L118 168 L120 200 L124 248 Q108 256 100 256 Q92 256 76 248 L80 200 L82 168 L84 130 L70 134 L62 112 Z"
    : "M58 88 Q70 76 86 82 Q100 78 114 82 Q130 76 142 88 L148 116 L138 142 L120 134 L122 172 L122 232 Q108 246 100 246 Q92 246 78 232 L78 172 L80 134 L62 142 L52 116 Z";

  // Muscle regions per view+gender (region id maps to muscle group id used elsewhere)
  const M = {
    male: {
      front: [
        // Pectorals
        { id: "chest", d: "M70 100 Q86 96 99 102 L99 124 Q86 128 72 122 L68 110 Z", label: "Chest L" },
        { id: "chest", d: "M101 102 Q114 96 130 100 L132 122 Q118 128 101 124 Z", label: "Chest R" },
        // Deltoids
        { id: "shoulders", d: "M58 90 Q66 84 80 86 L78 110 Q66 108 56 100 Z", label: "Delt L" },
        { id: "shoulders", d: "M142 90 Q134 84 120 86 L122 110 Q134 108 144 100 Z", label: "Delt R" },
        // Biceps
        { id: "arms", d: "M54 110 Q50 124 56 142 Q66 142 70 138 L74 116 Z" },
        { id: "arms", d: "M146 110 Q150 124 144 142 Q134 142 130 138 L126 116 Z" },
        // Forearms
        { id: "arms", d: "M54 142 L48 184 L58 188 L66 146 Z" },
        { id: "arms", d: "M146 142 L152 184 L142 188 L134 146 Z" },
        // Abs (stacked rows)
        { id: "core", d: "M88 132 L112 132 L111 144 L89 144 Z" },
        { id: "core", d: "M88 146 L112 146 L111 158 L89 158 Z" },
        { id: "core", d: "M89 160 L111 160 L110 172 L90 172 Z" },
        // Obliques
        { id: "core", d: "M78 134 L86 132 L86 168 L80 166 Z" },
        { id: "core", d: "M122 134 L114 132 L114 168 L120 166 Z" },
        // Quads
        { id: "legs", d: "M82 178 Q90 174 99 176 L99 232 Q92 234 84 232 Z" },
        { id: "legs", d: "M101 176 Q110 174 118 178 L116 232 Q108 234 101 232 Z" },
        // Calves (small bumps near bottom)
        { id: "legs", d: "M84 234 Q92 240 96 250 L92 254 L82 248 Z" },
        { id: "legs", d: "M116 234 Q108 240 104 250 L108 254 L118 248 Z" },
      ],
      back: [
        // Traps
        { id: "back", d: "M86 86 Q100 82 114 86 L112 108 Q100 112 88 108 Z" },
        // Rear delts
        { id: "shoulders", d: "M58 90 Q66 84 84 86 L82 106 Q68 108 56 100 Z" },
        { id: "shoulders", d: "M142 90 Q134 84 116 86 L118 106 Q132 108 144 100 Z" },
        // Lats (wing shape)
        { id: "back", d: "M70 110 Q82 108 96 116 L96 150 L80 148 L66 132 Z" },
        { id: "back", d: "M130 110 Q118 108 104 116 L104 150 L120 148 L134 132 Z" },
        // Lower back
        { id: "back", d: "M86 152 L114 152 L114 172 L86 172 Z" },
        // Triceps (back of arms)
        { id: "arms", d: "M54 110 Q50 124 56 142 Q66 142 70 138 L74 116 Z" },
        { id: "arms", d: "M146 110 Q150 124 144 142 Q134 142 130 138 L126 116 Z" },
        // Glutes
        { id: "legs", d: "M82 174 Q92 170 99 174 L99 198 Q90 200 82 196 Z" },
        { id: "legs", d: "M101 174 Q108 170 118 174 L118 196 Q110 200 101 198 Z" },
        // Hamstrings
        { id: "legs", d: "M82 200 Q92 200 99 202 L99 234 Q92 236 84 234 Z" },
        { id: "legs", d: "M101 202 Q108 200 118 200 L116 234 Q108 236 101 234 Z" },
        // Calves
        { id: "legs", d: "M82 236 Q92 240 96 252 L88 254 L80 244 Z" },
        { id: "legs", d: "M118 236 Q108 240 104 252 L112 254 L120 244 Z" },
      ],
    },
    female: {
      front: [
        // Pectorals (more compact)
        { id: "chest", d: "M76 102 Q88 98 99 104 L99 122 Q88 124 78 120 Z" },
        { id: "chest", d: "M101 104 Q112 98 124 102 L122 120 Q112 124 101 122 Z" },
        // Deltoids
        { id: "shoulders", d: "M68 90 Q78 84 90 86 L88 108 Q76 108 66 100 Z" },
        { id: "shoulders", d: "M132 90 Q122 84 110 86 L112 108 Q124 108 134 100 Z" },
        // Biceps
        { id: "arms", d: "M64 108 Q60 122 66 138 Q74 140 78 136 L82 114 Z" },
        { id: "arms", d: "M136 108 Q140 122 134 138 Q126 140 122 136 L118 114 Z" },
        // Forearms
        { id: "arms", d: "M62 138 L56 178 L66 182 L74 142 Z" },
        { id: "arms", d: "M138 138 L144 178 L134 182 L126 142 Z" },
        // Abs
        { id: "core", d: "M90 130 L110 130 L109 142 L91 142 Z" },
        { id: "core", d: "M90 144 L110 144 L109 156 L91 156 Z" },
        { id: "core", d: "M91 158 L109 158 L108 170 L92 170 Z" },
        // Obliques
        { id: "core", d: "M82 134 L88 132 L88 168 L84 166 Z" },
        { id: "core", d: "M118 134 L112 132 L112 168 L116 166 Z" },
        // Quads
        { id: "legs", d: "M84 178 Q92 174 99 176 L99 230 Q92 232 86 230 Z" },
        { id: "legs", d: "M101 176 Q108 174 116 178 L114 230 Q108 232 101 230 Z" },
        // Calves
        { id: "legs", d: "M86 232 Q92 240 96 250 L92 254 L84 246 Z" },
        { id: "legs", d: "M114 232 Q108 240 104 250 L108 254 L116 246 Z" },
      ],
      back: [
        { id: "back", d: "M88 86 Q100 82 112 86 L110 108 Q100 112 90 108 Z" },
        { id: "shoulders", d: "M68 90 Q78 84 88 86 L86 106 Q74 108 66 100 Z" },
        { id: "shoulders", d: "M132 90 Q122 84 112 86 L114 106 Q126 108 134 100 Z" },
        { id: "back", d: "M76 110 Q86 108 96 116 L96 150 L82 148 L72 132 Z" },
        { id: "back", d: "M124 110 Q114 108 104 116 L104 150 L118 148 L128 132 Z" },
        { id: "back", d: "M88 152 L112 152 L112 170 L88 170 Z" },
        { id: "arms", d: "M64 108 Q60 122 66 138 Q74 140 78 136 L82 114 Z" },
        { id: "arms", d: "M136 108 Q140 122 134 138 Q126 140 122 136 L118 114 Z" },
        // Glutes (rounder for female)
        { id: "legs", d: "M80 172 Q92 168 99 172 L99 200 Q90 204 80 198 Z" },
        { id: "legs", d: "M101 172 Q108 168 120 172 L120 198 Q110 204 101 200 Z" },
        { id: "legs", d: "M84 202 Q92 202 99 204 L99 232 Q92 234 86 232 Z" },
        { id: "legs", d: "M101 204 Q108 202 116 202 L114 232 Q108 234 101 232 Z" },
        { id: "legs", d: "M84 234 Q92 240 96 252 L88 254 L82 244 Z" },
        { id: "legs", d: "M116 234 Q108 240 104 252 L112 254 L118 244 Z" },
      ],
    },
  };

  const regions = M[gender][view];

  return (
    <svg viewBox="0 0 200 280" style={{ width: "100%", maxWidth: 240, display: "block" }}>
      <defs>
        <radialGradient id="bodyShade" cx="50%" cy="40%">
          <stop offset="0%" stopColor={SKIN}/>
          <stop offset="100%" stopColor={SKIN_SHADE}/>
        </radialGradient>
      </defs>
      {/* head */}
      <ellipse cx="100" cy="48" rx={gender === "female" ? 16 : 18} ry={gender === "female" ? 21 : 22}
               fill="url(#bodyShade)" stroke={STROKE} strokeWidth="1"/>
      {/* neck */}
      <rect x={gender === "female" ? 94 : 92} y="66" width={gender === "female" ? 12 : 16} height="16"
            fill="url(#bodyShade)" stroke={STROKE} strokeWidth="1"/>
      {/* body */}
      <path d={body} fill="url(#bodyShade)" stroke={STROKE} strokeWidth="1.2"/>
      {/* hands */}
      <ellipse cx={gender === "female" ? 60 : 52} cy="190" rx="6" ry="8" fill={SKIN_SHADE} stroke={STROKE} strokeWidth="0.8"/>
      <ellipse cx={gender === "female" ? 140 : 148} cy="190" rx="6" ry="8" fill={SKIN_SHADE} stroke={STROKE} strokeWidth="0.8"/>
      {/* feet */}
      <ellipse cx="88" cy="262" rx="8" ry="5" fill={SKIN_SHADE} stroke={STROKE} strokeWidth="0.8"/>
      <ellipse cx="112" cy="262" rx="8" ry="5" fill={SKIN_SHADE} stroke={STROKE} strokeWidth="0.8"/>

      {/* muscle regions */}
      {regions.map((r, i) => {
        const sel = selected === r.id;
        return (
          <path key={i} d={r.d}
                fill={sel ? HIGHLIGHT : HIGHLIGHT_DIM}
                stroke={sel ? "#8B3712" : "rgba(140,111,82,0.5)"}
                strokeWidth="0.7"
                style={{ cursor: "pointer", transition: "fill .15s" }}
                onClick={() => onSelect && onSelect(r.id)}
                onMouseEnter={(e) => !sel && (e.target.style.fill = HIGHLIGHT_HOVER)}
                onMouseLeave={(e) => !sel && (e.target.style.fill = HIGHLIGHT_DIM)}/>
        );
      })}
    </svg>
  );
};

// Date helpers
const fmtDate = (d, lang = "en") => {
  const date = typeof d === "string" ? new Date(d) : d;
  const m = I18N[lang].months[date.getMonth()];
  return `${date.getDate()} ${m.slice(0,3)} ${date.getFullYear()}`;
};
const fmtRelativeDay = (d, lang = "en") => {
  const date = typeof d === "string" ? new Date(d) : d;
  const today = new Date(2026, 4, 5);
  const diff = Math.floor((today - date) / 86400000);
  if (diff === 0) return I18N[lang].today;
  if (diff === 1) return I18N[lang].yesterday;
  if (diff < 7) return `${diff}j`;
  return fmtDate(d, lang);
};

// ExerciseThumb — circular thumbnail with optional image, play overlay, and
// initial+muscle-color fallback. Sizes: sm (28), md (40), lg (56), xl (72).
const ExerciseThumb = ({ exercise, size = 40, showPlay = true, src }) => {
  const muscleColors = {
    chest: "#C8501F", back: "#8B3712", legs: "#5C3D22", shoulders: "#A16332",
    arms: "#C9A074", core: "#6B5B45", cardio: "#3A2614",
  };
  const bg = muscleColors[exercise?.muscle] || "#5C3D22";
  const initial = (exercise?.name || "?").charAt(0).toUpperCase();
  const imgSrc = src || exercise?.thumb;
  const playSize = Math.round(size * 0.32);
  return (
    <div className="ex-thumb" style={{
      width: size, height: size, borderRadius: "50%",
      background: imgSrc ? `#1a130c center/cover no-repeat url('${imgSrc}')` : bg,
      color: "#fff", flexShrink: 0,
      display: "flex", alignItems: "center", justifyContent: "center",
      fontWeight: 700, fontSize: size * 0.42, position: "relative",
      border: "1px solid rgba(0,0,0,0.08)",
      overflow: "hidden",
    }}>
      {!imgSrc && initial}
      {showPlay && imgSrc && (
        <div style={{
          position: "absolute", inset: 0, background: "rgba(0,0,0,0.25)",
          display: "flex", alignItems: "center", justifyContent: "center",
        }}>
          <div style={{
            width: playSize, height: playSize, borderRadius: "50%",
            background: "rgba(255,255,255,0.92)",
            display: "flex", alignItems: "center", justifyContent: "center",
          }}>
            <svg width={playSize * 0.5} height={playSize * 0.5} viewBox="0 0 12 12" fill="#1A130C">
              <path d="M3 2 L10 6 L3 10 Z"/>
            </svg>
          </div>
        </div>
      )}
    </div>
  );
};

Object.assign(window, { Mascot, Icon, Avatar, ExerciseThumb, Sparkline, MuscleSilhouette, fmtDate, fmtRelativeDay });
