/* ============================================================
   ensō rse — Quizz onboarding · composants partagés
   Requires React (global). Exports to window.
   ============================================================ */
const { useState, useEffect, useRef, useMemo } = React;

/* ---------- Icônes (style Lucide, monoligne) ---------- */
const ICONS = {
  "arrow-right": "M5 12h14M13 5l7 7-7 7",
  "arrow-left": "M19 12H5M11 19l-7-7 7-7",
  "chevron-right": "M9 6l6 6-6 6",
  "chevron-down": "M6 9l6 6 6-6",
  "chevron-left": "M15 6l-6 6 6 6",
  check: "M20 6L9 17l-5-5",
  x: "M18 6L6 18M6 6l12 12",
  "check-circle": "M9 12l2 2 4-4|M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z",
  "x-circle": "M15 9l-6 6M9 9l6 6|M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z",
  handshake: "M11 17l2 2a1 1 0 0 0 3-3M2 12l5-5 4 4M14 11l3 3M18 8l3 3-5 5M3 12l4 4a1 1 0 0 0 3-3",
  "life-buoy": "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Z|M9 12a3 3 0 1 0 6 0 3 3 0 0 0-6 0Z|M4.9 4.9l4.2 4.2M14.9 14.9l4.2 4.2M14.9 9.1l4.2-4.2M9.1 14.9l-4.2 4.2",
  megaphone: "M3 11l14-6v14L3 13v-2zM3 11H2a1 1 0 0 0-1 1v0a1 1 0 0 0 1 1h1M7 12v6a1 1 0 0 0 1 1h1",
  boxes: "M3 7l9-4 9 4-9 4-9-4zM3 7v10l9 4 9-4V7M12 11v10",
  sparkles: "M12 3l1.8 4.7L18.5 9.5 13.8 11.3 12 16l-1.8-4.7L5.5 9.5l4.7-1.8L12 3zM19 14l.8 2.2L22 17l-2.2.8L19 20l-.8-2.2L16 17l2.2-.8L19 14z",
  refresh: "M3 12a9 9 0 0 1 15-6.7L21 8M21 3v5h-5M21 12a9 9 0 0 1-15 6.7L3 16M3 21v-5h5",
  user: "M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8ZM4 21v-1a6 6 0 0 1 6-6h4a6 6 0 0 1 6 6v1",
  users: "M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8ZM2 21v-1a6 6 0 0 1 6-6h2a6 6 0 0 1 6 6v1M16 3.5a4 4 0 0 1 0 7.5M22 21v-1a6 6 0 0 0-4-5.6",
  "list-checks": "M11 6h10M11 12h10M11 18h10M3 6l1.5 1.5L7 5M3 13l1.5 1.5L7 11M4 18.5h.01",
  "trending-up": "M3 17l6-6 4 4 8-8M21 7v5h-5",
  lightbulb: "M9 18h6M10 22h4M12 2a7 7 0 0 0-4 12.7c.6.5 1 1.2 1 2V18h6v-1.3c0-.8.4-1.5 1-2A7 7 0 0 0 12 2Z",
  target: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18ZM12 16a4 4 0 1 0 0-8 4 4 0 0 0 0 8ZM12 13a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z",
  leaf: "M11 20A7 7 0 0 1 4 13c0-5 4-9 16-9 0 10-5 15-9 16zM4 21c2-6 6-9 11-10",
  shield: "M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6l8-3z",
  gauge: "M12 14l4-4M12 21a9 9 0 1 1 0-18 9 9 0 0 1 0 18ZM7 14a5 5 0 0 1 10 0",
  "alert-triangle": "M12 3l9.5 16.5a1 1 0 0 1-.9 1.5H3.4a1 1 0 0 1-.9-1.5L12 3zM12 9v5M12 18h.01",
  eye: "M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7ZM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z",
  settings: "M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM19.4 15a1.6 1.6 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.6 1.6 0 0 0-2.7 1.1V21a2 2 0 1 1-4 0v-.1A1.6 1.6 0 0 0 7 19.4l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1A1.6 1.6 0 0 0 3 12.6H3a2 2 0 1 1 0-4h.1A1.6 1.6 0 0 0 4.6 6l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1A1.6 1.6 0 0 0 10 3.6V3a2 2 0 1 1 4 0v.1a1.6 1.6 0 0 0 2.7 1.1l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.6 1.6 0 0 0 1.1 2.7H21a2 2 0 1 1 0 4h-.1a1.6 1.6 0 0 0-1.5 1.4Z",
  clock: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18ZM12 7v5l3 2",
  award: "M12 15a6 6 0 1 0 0-12 6 6 0 0 0 0 12ZM8.2 13.9L7 22l5-3 5 3-1.2-8.1",
  "graduation-cap": "M22 9L12 5 2 9l10 4 10-4zM6 11v5c0 1 2.7 3 6 3s6-2 6-3v-5",
  flag: "M4 21V4M4 4s1.5-1 5-1 5 2 8.5 2c2 0 3.5-.6 3.5-.6V14s-1.5.6-3.5.6C14 14.6 12.5 13 9 13s-5 1-5 1",
  download: "M12 3v12M7 10l5 5 5-5M4 21h16",
  briefcase: "M3 8h18v11a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V8zM8 8V6a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M3 13h18",
  compass: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18ZM16 8l-2 6-6 2 2-6 6-2z",
  "message-circle": "M21 11.5a8.5 8.5 0 0 1-12.3 7.6L3 21l1.9-5.7A8.5 8.5 0 1 1 21 11.5z",
  plus: "M12 5v14M5 12h14",
  send: "M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z",
  circle: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Z",
  home: "M3 11l9-8 9 8M5 9.5V20a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V9.5"
};
function Icon({ name, size = 20, stroke = 1.9, color = "currentColor", style }) {
  const d = ICONS[name] || ICONS["circle"] || "";
  const parts = d.split("|");
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color}
    strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"
    style={{ display: "block", flex: "none", ...style }} aria-hidden="true">
      {parts.map((p, i) => <path key={i} d={p} />)}
    </svg>);

}

/* ---------- Logo & marque ---------- */
function _res(id, fallback) { return (window.__resources && window.__resources[id]) || fallback; }
function Logo({ height = 30, variant = "color" }) {
  const src = variant === "white" ? _res("logoWhite", "assets/logo-enso-blanc.png") : _res("logoColor", "assets/logo-enso.png");
  return <img src={src} alt="ensō rse" style={{ height, width: "auto", display: "block" }} />;
}
function EnsoMark({ size = 28, variant = "color" }) {
  return <img src={_res("ensoMark", "assets/enso-mark.png")} alt="" style={{ height: size, width: "auto", display: "block" }} />;
}
// ensō-style open ring (decorative / level badge)
function EnsoRing({ size = 120, stroke = 9, color = "var(--color-env-500)", track = "var(--color-neutral-100)", pct = 100 }) {
  const r = (size - stroke) / 2,c = size / 2,circ = 2 * Math.PI * r;
  const gap = 0.13; // open at top-right
  const visible = circ * (1 - gap);
  const dash = visible * (pct / 100);
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ display: "block", transform: "rotate(-58deg)" }}>
      <circle cx={c} cy={c} r={r} fill="none" stroke={track} strokeWidth={stroke}
      strokeLinecap="round" strokeDasharray={`${visible} ${circ - visible}`} />
      <circle cx={c} cy={c} r={r} fill="none" stroke={color} strokeWidth={stroke}
      strokeLinecap="round" strokeDasharray={`${dash} ${circ - dash}`}
      style={{ transition: "stroke-dasharray .9s var(--ease-out)" }} />
    </svg>);

}

/* ---------- Boutons ---------- */
function Btn({ variant = "primary", size = "md", icon, iconRight, children, onClick, disabled, type = "button", full, style }) {
  const [hover, setHover] = useState(false);
  const pads = size === "lg" ? "15px 28px" : size === "sm" ? "8px 16px" : "12px 22px";
  const fs = size === "lg" ? "var(--fs-md)" : size === "sm" ? "var(--fs-sm)" : "var(--fs-base)";
  const base = {
    display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 9,
    fontFamily: "var(--font-body)", fontWeight: 600, fontSize: fs, padding: pads,
    borderRadius: "var(--r-pill)", border: "1px solid transparent", lineHeight: 1.1,
    transition: "background .16s var(--ease-out), box-shadow .16s, transform .08s, color .16s",
    width: full ? "100%" : "auto", whiteSpace: "nowrap",
    opacity: disabled ? .45 : 1, pointerEvents: disabled ? "none" : "auto"
  };
  const skins = {
    primary: { background: hover ? "var(--accent-600)" : "var(--accent-500)", color: "#fff",
      boxShadow: hover ? "var(--shadow-md)" : "var(--shadow-sm)" },
    secondary: { background: hover ? "var(--accent-100)" : "transparent", color: "var(--accent-700)",
      border: "1px solid var(--border-strong)" },
    ghost: { background: hover ? "var(--color-neutral-50)" : "transparent", color: "var(--fg-default)" },
    dark: { background: hover ? "#000" : "var(--bg-inverse)", color: "#fff" },
    danger: { background: hover ? "#b42318" : "var(--danger-500)", color: "#fff" }
  };
  return (
    <button type={type} onClick={onClick} disabled={disabled}
    onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
    style={{ ...base, ...skins[variant], ...style }}>
      {icon && <Icon name={icon} size={size === "sm" ? 17 : 19} />}
      {children}
      {iconRight && <Icon name={iconRight} size={size === "sm" ? 17 : 19} />}
    </button>);

}

/* ---------- Atomes ---------- */
function Eyebrow({ children, color }) {
  return <div className="eyebrow" style={{ ...{ color: color || "var(--fg-brand)" }, color: "rgb(0, 175, 143)" }}>{children}</div>;
}
function Pill({ children, tone = "neutral", style }) {
  const tones = {
    neutral: { bg: "var(--color-neutral-50)", fg: "var(--color-neutral-600)", bd: "var(--border-strong)" },
    env: { bg: "var(--color-env-100)", fg: "var(--color-env-700)", bd: "var(--color-env-200)" },
    soc: { bg: "var(--color-soc-100)", fg: "var(--color-soc-700)", bd: "var(--color-soc-200)" },
    gov: { bg: "var(--color-gov-100)", fg: "var(--color-gov-700)", bd: "var(--color-gov-200)" },
    danger: { bg: "var(--danger-bg)", fg: "var(--danger-fg)", bd: "#f6c8c4" },
    dark: { bg: "var(--bg-inverse)", fg: "#fff", bd: "transparent" }
  };
  const t = tones[tone] || tones.neutral;
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 6, padding: "5px 12px",
      borderRadius: "var(--r-pill)", background: t.bg, color: t.fg, border: `1px solid ${t.bd}`,
      fontSize: "var(--fs-xs)", fontWeight: 600, letterSpacing: ".01em", ...style }}>{children}</span>);

}
function Card({ children, style, pad = 24, hover, onClick }) {
  const [h, setH] = useState(false);
  return (
    <div onClick={onClick} onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
    style={{ background: "var(--bg-surface)", border: "1px solid var(--border-default)",
      borderRadius: "var(--r-lg)", padding: pad, cursor: onClick ? "pointer" : "default",
      boxShadow: hover && h ? "var(--shadow-md)" : "var(--shadow-xs)",
      transition: "box-shadow .2s var(--ease-out), border-color .2s", ...style }}>
      {children}
    </div>);

}

const PILLAR_COLOR = { env: "var(--color-env-500)", soc: "var(--color-soc-500)", gov: "var(--color-gov-500)" };
const PILLAR_700 = { env: "var(--color-env-700)", soc: "var(--color-soc-700)", gov: "var(--color-gov-700)" };

/* ---------- Sélecteur de certitude ---------- */
function CertaintySelector({ value, onChange }) {
  const opts = [
  { k: "sure", label: "Sûr·e de moi", icon: "check-circle" },
  { k: "mid", label: "Mitigé·e", icon: "circle" },
  { k: "guess", label: "Au hasard", icon: "target" }];

  return (
    <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
      {opts.map((o) => {
        const on = value === o.k;
        return (
          <button key={o.k} type="button" onClick={() => onChange(o.k)}
          style={{ display: "inline-flex", alignItems: "center", gap: 7, padding: "8px 14px",
            borderRadius: "var(--r-pill)", fontFamily: "var(--font-body)", fontWeight: 600, fontSize: "var(--fs-sm)",
            border: on ? "1px solid var(--accent-500)" : "1px solid var(--border-strong)",
            background: on ? "var(--accent-100)" : "var(--bg-surface)",
            color: on ? "var(--accent-700)" : "var(--fg-muted)",
            transition: "all .14s var(--ease-out)" }}>
            <Icon name={o.icon === "circle" ? "eye" : o.icon} size={16} />
            {o.label}
          </button>);

      })}
    </div>);

}

/* ---------- Radar ESG (hexagone) ---------- */
function Radar({ size = 360, series = [], labels = true, domains }) {
  const DOMS = domains || window.QD.DOMAINS;
  const n = DOMS.length,cx = size / 2,cy = size / 2,R = size / 2 - (labels ? 64 : 18);
  const angle = (i) => -Math.PI / 2 + i * 2 * Math.PI / n;
  const pt = (i, r) => [cx + Math.cos(angle(i)) * r, cy + Math.sin(angle(i)) * r];
  const ringPoly = (f) => DOMS.map((_, i) => pt(i, R * f).join(",")).join(" ");
  const rings = [0.25, 0.5, 0.75, 1];
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ display: "block", overflow: "visible" }}>
      {rings.map((f, i) =>
      <polygon key={i} points={ringPoly(f)} fill={i === rings.length - 1 ? "var(--color-neutral-25)" : "none"}
      stroke="var(--border-strong)" strokeWidth="1" />
      )}
      {DOMS.map((_, i) => {const [x, y] = pt(i, R);return <line key={i} x1={cx} y1={cy} x2={x} y2={y} stroke="var(--border-strong)" strokeWidth="1" />;})}
      {series.map((s, si) => {
        const poly = DOMS.map((d, i) => pt(i, R * ((s.values[d.id] ?? 0) / 100)).join(",")).join(" ");
        return (
          <g key={si}>
            <polygon points={poly} fill={s.fill || "rgba(0,175,143,.15)"} stroke={s.color || "var(--color-env-500)"}
            strokeWidth="2.5" strokeLinejoin="round"
            style={{ transition: "all .7s var(--ease-out)" }} />
            {s.dots !== false && DOMS.map((d, i) => {const [x, y] = pt(i, R * ((s.values[d.id] ?? 0) / 100));return <circle key={i} cx={x} cy={y} r="3.5" fill={s.color || "var(--color-env-500)"} />;})}
          </g>);

      })}
      {labels && DOMS.map((d, i) => {
        const [x, y] = pt(i, R + 30);
        const anchor = Math.abs(x - cx) < 12 ? "middle" : x > cx ? "start" : "end";
        return (
          <g key={i}>
            <text x={x} y={y} textAnchor={anchor} dominantBaseline="middle"
            fontFamily="var(--font-body)" fontWeight="700" fontSize="12.5"
            fill={PILLAR_700[d.pillar]}>{d.short}</text>
          </g>);

      })}
    </svg>);

}

/* ---------- Barres par domaine ---------- */
function DomainBars({ scores, compare }) {
  const DOMS = window.QD.DOMAINS;
  return (
    <div style={{ display: "grid", gap: 14 }}>
      {DOMS.map((d) => {
        const v = scores[d.id];const c2 = compare ? compare[d.id] : null;
        const col = PILLAR_COLOR[d.pillar];
        return (
          <div key={d.id}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 6 }}>
              <span style={{ fontWeight: 600, fontSize: "var(--fs-sm)" }}>{d.label}</span>
              <span style={{ fontWeight: 700, fontSize: "var(--fs-sm)", color: v == null ? "var(--fg-subtle)" : col }}>
                {v == null ? "—" : v + "%"}
                {c2 != null && v != null &&
                <span style={{ color: v - c2 >= 0 ? "var(--color-env-600)" : "var(--danger-500)", fontSize: "var(--fs-xs)", marginLeft: 6 }}>
                    {v - c2 >= 0 ? "▲" : "▼"} {Math.abs(v - c2)}
                  </span>
                }
              </span>
            </div>
            <div style={{ height: 9, borderRadius: 999, background: "var(--color-neutral-100)", position: "relative", overflow: "hidden" }}>
              {c2 != null && <div style={{ position: "absolute", left: 0, top: 0, bottom: 0, width: c2 + "%", background: "var(--color-neutral-200)", borderRadius: 999 }} />}
              <div style={{ position: "absolute", left: 0, top: 0, bottom: 0, width: (v || 0) + "%", background: col, borderRadius: 999, transition: "width .8s var(--ease-out)" }} />
            </div>
          </div>);

      })}
    </div>);

}

/* ---------- Badge de niveau (anneau ensō) ---------- */
function LevelBadge({ score, size = 150, showText = true }) {
  const lvl = window.QD.levelFor(score);
  return (
    <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }}>
      <div style={{ position: "relative", width: size, height: size }}>
        <EnsoRing size={size} stroke={size > 120 ? 10 : 8} color={lvl.color} pct={score} />
        <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center" }}>
          <div style={{ fontFamily: "var(--font-display)", fontWeight: 800, fontSize: size * 0.3, lineHeight: 1, color: lvl.color }}>{score}<span style={{ fontSize: size * 0.13 }}>%</span></div>
        </div>
      </div>
      {showText && <div style={{ textAlign: "center" }}>
        <div style={{ fontFamily: "var(--font-display)", fontWeight: 700, fontSize: "var(--fs-xl)", color: lvl.color }}>{lvl.label}</div>
        <div className="muted" style={{ fontSize: "var(--fs-sm)", fontStyle: "italic" }}>{lvl.tag}</div>
      </div>}
    </div>);

}

Object.assign(window, {
  Icon, Logo, EnsoMark, EnsoRing, Btn, Eyebrow, Pill, Card,
  CertaintySelector, Radar, DomainBars, LevelBadge, PILLAR_COLOR, PILLAR_700
});