// ConvierteAudit — Componentes compartidos (íconos SVG, gauge, barras, badges)

/* ---- Íconos estilo Lucide (stroke 1.5, currentColor) ---- */
const ICON_PATHS = {
  message:  <><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></>,
  cursor:   <><path d="m9 9 5 12 1.8-5.2L21 14z"/><path d="M7.2 2.2 8 5.1"/><path d="m5.1 8-2.9-.8"/><path d="M14 4.1 12 6"/><path d="m6 12-1.9 2"/></>,
  shield:   <><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/></>,
  form:     <><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M7 8h10"/><path d="M7 12h6"/><path d="m15.5 14 1.5 1.5 3-3"/></>,
  gauge:    <><path d="m12 14 4-4"/><path d="M3.34 19a10 10 0 1 1 17.32 0"/></>,
  mobile:   <><rect width="14" height="20" x="5" y="2" rx="2.5"/><path d="M12 18h.01"/></>,
  search:   <><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></>,
  layers:   <><path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z"/><path d="m6.08 9.5-3.49 1.59a1 1 0 0 0 0 1.83l8.59 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83L17.92 9.5"/></>,
  // UI
  lock:     <><rect width="18" height="11" x="3" y="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></>,
  check:    <><path d="M20 6 9 17l-5-5"/></>,
  arrow:    <><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></>,
  download: <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="M7 10l5 5 5-5"/><path d="M12 15V3"/></>,
  bolt:     <><path d="M13 2 3 14h9l-1 8 10-12h-9z"/></>,
  desktop:  <><rect width="20" height="14" x="2" y="3" rx="2"/><path d="M8 21h8"/><path d="M12 17v4"/></>,
  spark:    <><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M18.4 5.6l-2.1 2.1M7.7 16.3l-2.1 2.1"/></>,
  trending: <><path d="M16 7h6v6"/><path d="m22 7-8.5 8.5-5-5L2 17"/></>,
  declining:<><path d="M16 17h6v-6"/><path d="m22 17-8.5-8.5-5 5L2 7"/></>,
  link:     <><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></>,
  globe:    <><circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/></>,
  key:      <><path d="m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4"/><path d="m21 2-9.6 9.6"/><circle cx="7.5" cy="15.5" r="5.5"/></>,
  network:  <><rect x="9" y="2" width="6" height="6" rx="1"/><rect x="2" y="16" width="6" height="6" rx="1"/><rect x="16" y="16" width="6" height="6" rx="1"/><path d="M12 8v4M12 12H5v4M12 12h7v4"/></>,
  alert:    <><path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/><path d="M12 9v4"/><path d="M12 17h.01"/></>,
};

function Icon({ name, size = 24, stroke = 1.5, className, style, ...rest }) {
  return (
    <svg className={className} width={size} height={size} viewBox="0 0 24 24"
      fill="none" stroke="currentColor" strokeWidth={stroke}
      strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"
      style={style} {...rest}>
      {ICON_PATHS[name] || null}
    </svg>
  );
}

/* ---- Mapa tono → color (puntaje / severidad) ---- */
const TONE = {
  danger:  { color: "var(--danger-500)",  fg: "var(--danger-700)",  bg: "var(--danger-100)"  },
  warning: { color: "var(--warning-500)", fg: "var(--warning-700)", bg: "var(--warning-100)" },
  info:    { color: "var(--blue-700)",    fg: "var(--blue-700)",    bg: "var(--blue-100)"    },
  success: { color: "var(--success-500)", fg: "var(--success-700)", bg: "var(--success-100)" },
};
const SEV_TONE = { alta: "danger", media: "warning", baja: "info" };
const SEV_LABEL = { alta: "Alta", media: "Media", baja: "Baja" };

/* ---- Gauge de anillo (0–100) con conteo animado ---- */
function RingGauge({ score, tone, label, animate = true, size = 200 }) {
  const [shown, setShown] = React.useState(animate ? 0 : score);
  const reduce = React.useRef(typeof window !== "undefined" &&
    window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches).current;

  React.useEffect(() => {
    if (!animate || reduce) { setShown(score); return; }
    let raf, start;
    const dur = 1100;
    const step = (t) => {
      if (!start) start = t;
      const p = Math.min(1, (t - start) / dur);
      const eased = 1 - Math.pow(1 - p, 3);
      setShown(Math.round(score * eased));
      if (p < 1) raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    // Garantía: si rAF no avanza (tab en segundo plano, entornos sin rAF),
    // aterriza siempre en el valor real.
    const fallback = setTimeout(() => setShown(score), dur + 120);
    return () => { cancelAnimationFrame(raf); clearTimeout(fallback); };
  }, [score, animate, reduce]);

  const stroke = 14;
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const pct = shown / 100;
  const color = TONE[tone].color;

  return (
    <div className="gauge" role="img"
      aria-label={`Puntaje general de conversión: ${score} de 100. Nivel: ${label}.`}
      style={{ width: size, height: size }}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} aria-hidden="true">
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--navy-100)" strokeWidth={stroke} />
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth={stroke}
          strokeLinecap="round" strokeDasharray={c}
          strokeDashoffset={c * (1 - pct)}
          transform={`rotate(-90 ${size/2} ${size/2})`}
          style={{ transition: reduce ? "none" : "stroke-dashoffset 90ms linear" }} />
      </svg>
      <div className="gauge-center">
        <div className="gauge-num" style={{ color: "var(--navy-900)" }}>{shown}</div>
        <div className="gauge-of">de 100</div>
        <span className="band-pill" style={{ background: TONE[tone].bg, color: TONE[tone].fg }}>{label}</span>
      </div>
    </div>
  );
}

/* ---- Barra de progreso de categoría ---- */
function CatBar({ score, tone, animate = true, delay = 0 }) {
  const [w, setW] = React.useState(animate ? 0 : score);
  const reduce = React.useRef(typeof window !== "undefined" &&
    window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches).current;
  React.useEffect(() => {
    if (!animate || reduce) { setW(score); return; }
    const t = setTimeout(() => setW(score), 80 + delay);
    return () => clearTimeout(t);
  }, [score, animate, reduce, delay]);
  return (
    <div className="catbar-track" role="progressbar" aria-valuenow={score} aria-valuemin={0} aria-valuemax={100}>
      <div className="catbar-fill" style={{ width: w + "%", background: TONE[tone].color }} />
    </div>
  );
}

function SeverityBadge({ severity }) {
  const tone = SEV_TONE[severity];
  return (
    <span className="sev-badge" style={{ background: TONE[tone].bg, color: TONE[tone].fg }}>
      <span className="sev-dot" style={{ background: TONE[tone].color }} />
      {SEV_LABEL[severity]}
    </span>
  );
}

Object.assign(window, { Icon, RingGauge, CatBar, SeverityBadge, TONE, SEV_TONE, SEV_LABEL });
