/* Shared UI primitives + chart components — FESPA prototype */

const { useState, useEffect, useMemo, useRef } = React;

/* ---------- Brand mark ---------- */
function FespaMark({ variant = "dark", size = 1 }) {
  const fg = variant === "dark" ? "#0F1822" : "#FFFFFF";
  const accent = "#D8232A"; // FESPA red touch
  return (
    <div className="fespa-mark" style={{ fontSize: `${14 * size}px` }}>
      <span className="fespa-mark__dot" style={{ background: accent }}></span>
      <span className="fespa-mark__wordmark" style={{ color: fg }}>
        FESPA<span style={{ color: accent, fontWeight: 800 }}>·</span>FRANCE
      </span>
    </div>
  );
}

/* ---------- Atoms ---------- */
function Button({ children, variant = "primary", size = "md", onClick, disabled, type = "button", icon, ...rest }) {
  return (
    <button
      type={type}
      onClick={onClick}
      disabled={disabled}
      className={`fb-btn fb-btn--${variant} fb-btn--${size}`}
      {...rest}
    >
      {icon && <span className="fb-btn__icon">{icon}</span>}
      <span>{children}</span>
    </button>
  );
}

function Chip({ children, tone = "neutral", size = "md" }) {
  return <span className={`fb-chip fb-chip--${tone} fb-chip--${size}`}>{children}</span>;
}

function Card({ children, padding = "lg", className = "", style }) {
  return <div className={`fb-card fb-card--${padding} ${className}`} style={style}>{children}</div>;
}

function Eyebrow({ children, color }) {
  return <div className="byi-eyebrow" style={color ? { color } : undefined}>{children}</div>;
}

function StatTile({ label, value, sub, tone = "navy", icon }) {
  return (
    <div className={`fb-stat fb-stat--${tone}`}>
      <div className="fb-stat__top">
        <span className="fb-stat__label">{label}</span>
        {icon && <span className="fb-stat__icon">{icon}</span>}
      </div>
      <div className="fb-stat__value">{value}</div>
      {sub && <div className="fb-stat__sub">{sub}</div>}
    </div>
  );
}

/* ---------- Charts (pure SVG) ---------- */

function DonutChart({ value, total, size = 180, stroke = 18, color = "var(--byi-orange-500)", track = "var(--byi-navy-100)", label, sublabel }) {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const pct = total > 0 ? value / total : 0;
  const offset = c * (1 - pct);
  return (
    <div className="fb-donut" style={{ width: size, height: size }}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        <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"
          strokeDasharray={c} strokeDashoffset={offset}
          transform={`rotate(-90 ${size / 2} ${size / 2})`}
          style={{ transition: "stroke-dashoffset var(--dur-slow) var(--ease-out)" }}
        />
      </svg>
      <div className="fb-donut__center">
        <div className="fb-donut__value">{label ?? `${Math.round(pct * 100)}%`}</div>
        {sublabel && <div className="fb-donut__sub">{sublabel}</div>}
      </div>
    </div>
  );
}

function HBar({ data, max, color = "var(--byi-orange-500)", showCount = true, height = 24 }) {
  const m = max ?? Math.max(...data.map(d => d.value), 1);
  return (
    <div className="fb-hbar">
      {data.map((d, i) => (
        <div className="fb-hbar__row" key={i}>
          <div className="fb-hbar__label" title={d.label}>{d.label}</div>
          <div className="fb-hbar__track" style={{ height }}>
            <div
              className="fb-hbar__fill"
              style={{ width: `${(d.value / m) * 100}%`, background: d.color || color }}
            ></div>
          </div>
          {showCount && <div className="fb-hbar__count">{d.value}</div>}
        </div>
      ))}
    </div>
  );
}

function VBar({ data, height = 200, color = "var(--byi-navy-800)", accent }) {
  const max = Math.max(...data.map(d => d.value), 1);
  return (
    <div className="fb-vbar" style={{ height }}>
      {data.map((d, i) => (
        <div className="fb-vbar__col" key={i}>
          <div className="fb-vbar__track">
            <div
              className="fb-vbar__fill"
              style={{
                height: `${(d.value / max) * 100}%`,
                background: (accent && d.highlight) ? accent : color
              }}
              title={`${d.label}: ${d.value}`}
            >
              <span className="fb-vbar__value">{d.value}</span>
            </div>
          </div>
          <div className="fb-vbar__label">{d.label}</div>
        </div>
      ))}
    </div>
  );
}

function Sparkline({ data, width = 320, height = 80, color = "var(--byi-orange-500)" }) {
  const max = Math.max(...data, 1);
  const step = data.length > 1 ? width / (data.length - 1) : width;
  const points = data.map((v, i) => `${i * step},${height - (v / max) * height * 0.85 - 4}`);
  const path = `M ${points.join(" L ")}`;
  const area = `${path} L ${width},${height} L 0,${height} Z`;
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`} className="fb-spark">
      <defs>
        <linearGradient id="sparkFill" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.25" />
          <stop offset="100%" stopColor={color} stopOpacity="0" />
        </linearGradient>
      </defs>
      <path d={area} fill="url(#sparkFill)" />
      <path d={path} fill="none" stroke={color} strokeWidth="2.5" strokeLinejoin="round" strokeLinecap="round" />
      {points.map((p, i) => {
        const [x, y] = p.split(",").map(Number);
        return <circle key={i} cx={x} cy={y} r={i === points.length - 1 ? 4 : 2.5} fill={color} />;
      })}
    </svg>
  );
}

function StackedBar({ segments, height = 14 }) {
  const total = segments.reduce((s, x) => s + x.value, 0);
  return (
    <div className="fb-stack" style={{ height }}>
      {segments.map((seg, i) => (
        <div
          key={i}
          className="fb-stack__seg"
          style={{ width: `${(seg.value / total) * 100}%`, background: seg.color }}
          title={`${seg.label}: ${seg.value}`}
        ></div>
      ))}
    </div>
  );
}

function Legend({ items }) {
  return (
    <div className="fb-legend">
      {items.map((it, i) => (
        <div className="fb-legend__item" key={i}>
          <span className="fb-legend__dot" style={{ background: it.color }}></span>
          <span className="fb-legend__label">{it.label}</span>
          <span className="fb-legend__value">{it.value}</span>
        </div>
      ))}
    </div>
  );
}

/* ---------- Aggregations ---------- */
function aggregate(respondents) {
  const count = (arr, key) => {
    const m = new Map();
    arr.forEach(r => {
      const v = r[key];
      if (Array.isArray(v)) v.forEach(x => m.set(x, (m.get(x) || 0) + 1));
      else if (v != null) m.set(v, (m.get(v) || 0) + 1);
    });
    return [...m.entries()].map(([label, value]) => ({ label, value })).sort((a, b) => b.value - a.value);
  };

  const skillHist = Array.from({ length: 10 }, (_, i) => ({
    label: String(i + 1),
    value: respondents.filter(r => r.skill === i + 1).length
  }));

  const avgSkill = respondents.reduce((s, r) => s + r.skill, 0) / Math.max(respondents.length, 1);

  // 21 days
  const dayCounts = Array.from({ length: 21 }, () => 0);
  respondents.forEach(r => {
    const days = Math.floor((new Date(2026, 4, 23) - r.submittedAt) / (1000 * 60 * 60 * 24));
    const idx = 20 - Math.max(0, Math.min(20, days));
    dayCounts[idx] += 1;
  });

  return {
    usage: count(respondents, "usage"),
    tools: count(respondents, "tools"),
    domains: count(respondents, "domains"),
    benefits: count(respondents, "benefits"),
    satisfaction: count(respondents.filter(r => r.satisfaction), "satisfaction"),
    policy: count(respondents, "policy"),
    training: count(respondents, "trainingInterests"),
    budget: count(respondents, "budget"),
    timeline: count(respondents, "timeline"),
    format: count(respondents, "format"),
    sizes: count(respondents, "sizeLabel"),
    regions: count(respondents, "region"),
    skillHist,
    avgSkill,
    dayCounts
  };
}

/* expose */
Object.assign(window, {
  FespaMark, Button, Chip, Card, Eyebrow, StatTile,
  DonutChart, HBar, VBar, Sparkline, StackedBar, Legend,
  aggregate
});
