/* Hand-rolled SVG charts. Export to window. */
const { useState: cuseState, useMemo: cuseMemo, useRef: cuseRef, useEffect: cuseEffect } = React;

const CHART_COLORS = ["#008A3D", "#0E7C8C", "#7C3AED", "#C8102E", "#C2410C", "#B45309", "#1E5BA8", "#6D28D9", "#DB2777", "#475569"];

/* ---------- BarChart (horizontal) ---------- */
function BarChartH({ data, valueKey = "value", labelKey = "label", maxBars = 12, onClick, height, colorBy, formatValue }) {
  const items = data.slice(0, maxBars);
  const max = Math.max(1, ...items.map(d => d[valueKey]));
  const rowH = 26;
  const labelW = 180;
  const padding = 14;
  const totalH = height || (items.length * rowH + padding * 2);
  const [hover, setHover] = cuseState(null);
  const containerRef = cuseRef(null);

  return (
    <div style={{ position: "relative", width: "100%" }} ref={containerRef}>
      <svg width="100%" height={totalH} viewBox={`0 0 600 ${totalH}`} preserveAspectRatio="none" style={{ display: "block" }}>
        {items.map((d, i) => {
          const y = padding + i * rowH;
          const barMax = 600 - labelW - 70;
          const w = (d[valueKey] / max) * barMax;
          const color = colorBy ? colorBy(d, i) : CHART_COLORS[i % CHART_COLORS.length];
          const fmt = formatValue ? formatValue(d[valueKey]) : window.DATA.fmtNum(d[valueKey]);
          return (
            <g key={d[labelKey] + i}
               onMouseEnter={() => setHover({ ...d, x: labelW + w + 4, y: y + rowH / 2 })}
               onMouseLeave={() => setHover(null)}
               onClick={() => onClick && onClick(d)}
               style={{ cursor: onClick ? "pointer" : "default" }}>
              <text x={labelW - 8} y={y + rowH / 2 + 4} textAnchor="end" fontSize="12" fill="#334155" fontWeight="500">
                {d[labelKey].length > 28 ? d[labelKey].slice(0, 27) + "…" : d[labelKey]}
              </text>
              <rect x={labelW} y={y + 4} width={barMax} height={rowH - 10} fill="#F1F5F9" rx="2" />
              <rect x={labelW} y={y + 4} width={Math.max(1, w)} height={rowH - 10} fill={color} rx="2" />
              <text x={labelW + w + 6} y={y + rowH / 2 + 4} fontSize="11.5" fill="#334155" fontWeight="600" style={{ fontVariantNumeric: "tabular-nums" }}>
                {fmt}
              </text>
              <rect x="0" y={y} width="600" height={rowH} fill="transparent" />
            </g>
          );
        })}
      </svg>
    </div>
  );
}

/* ---------- DonutChart ---------- */
function DonutChart({ data, size = 180, valueKey = "value", labelKey = "label", colorKey, centerLabel, centerValue }) {
  const total = data.reduce((s, d) => s + d[valueKey], 0);
  const cx = size / 2, cy = size / 2;
  const r = size / 2 - 8;
  const inner = r - 22;
  let angle = -Math.PI / 2;
  const [hover, setHover] = cuseState(null);

  function arcPath(a0, a1) {
    const x0 = cx + r * Math.cos(a0), y0 = cy + r * Math.sin(a0);
    const x1 = cx + r * Math.cos(a1), y1 = cy + r * Math.sin(a1);
    const xi1 = cx + inner * Math.cos(a1), yi1 = cy + inner * Math.sin(a1);
    const xi0 = cx + inner * Math.cos(a0), yi0 = cy + inner * Math.sin(a0);
    const large = a1 - a0 > Math.PI ? 1 : 0;
    return `M ${x0} ${y0} A ${r} ${r} 0 ${large} 1 ${x1} ${y1} L ${xi1} ${yi1} A ${inner} ${inner} 0 ${large} 0 ${xi0} ${yi0} Z`;
  }

  return (
    <div style={{ display: "flex", alignItems: "center", gap: 18 }}>
      <div style={{ position: "relative", width: size, height: size, flex: "0 0 auto" }}>
        <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
          {data.map((d, i) => {
            const frac = d[valueKey] / total;
            const a0 = angle;
            const a1 = angle + frac * Math.PI * 2;
            angle = a1;
            const color = colorKey ? d[colorKey] : CHART_COLORS[i % CHART_COLORS.length];
            const isHover = hover && hover.label === d[labelKey];
            return (
              <path
                key={d[labelKey]}
                d={arcPath(a0, a1)}
                fill={color}
                opacity={hover && !isHover ? 0.55 : 1}
                onMouseEnter={() => setHover({ label: d[labelKey], value: d[valueKey], pct: frac })}
                onMouseLeave={() => setHover(null)}
                style={{ transition: "opacity 100ms", cursor: "pointer" }}
              />
            );
          })}
        </svg>
        <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", pointerEvents: "none" }}>
          {hover ? (
            <>
              <div style={{ fontSize: 11, color: "#64748B", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.04em" }}>{hover.label}</div>
              <div style={{ fontSize: 22, fontWeight: 700, color: "#0F172A", letterSpacing: "-0.02em" }}>{(hover.pct * 100).toFixed(1)}%</div>
              <div style={{ fontSize: 11.5, color: "#64748B" }}>{window.DATA.fmtNum(hover.value)}</div>
            </>
          ) : (
            <>
              <div style={{ fontSize: 11, color: "#64748B", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.04em" }}>{centerLabel || "Totale"}</div>
              <div style={{ fontSize: 22, fontWeight: 700, color: "#0F172A", letterSpacing: "-0.02em" }}>{centerValue || window.DATA.fmtNum(total)}</div>
            </>
          )}
        </div>
      </div>
      <div className="legend" style={{ flexDirection: "column", gap: 8 }}>
        {data.map((d, i) => {
          const color = colorKey ? d[colorKey] : CHART_COLORS[i % CHART_COLORS.length];
          const pct = ((d[valueKey] / total) * 100).toFixed(1);
          return (
            <div key={d[labelKey]} style={{ display: "flex", alignItems: "center", gap: 10, fontSize: 12 }}>
              <span className="legend__dot" style={{ background: color, marginRight: 0 }} />
              <span style={{ minWidth: 110, color: "#334155" }}>{d[labelKey]}</span>
              <span style={{ color: "#0F172A", fontWeight: 600, fontVariantNumeric: "tabular-nums" }}>{window.DATA.fmtNum(d[valueKey])}</span>
              <span style={{ color: "#94A3B8", fontSize: 11 }}>{pct}%</span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ---------- LineChart (multi-series with stacked area option) ---------- */
function LineChart({ series, xLabels, height = 240, yLabel }) {
  const w = 760;
  const h = height;
  const padL = 44, padR = 16, padT = 12, padB = 28;
  const innerW = w - padL - padR;
  const innerH = h - padT - padB;
  const maxV = Math.max(1, ...series.flatMap(s => s.data));
  const yTicks = 5;
  const [hoverX, setHoverX] = cuseState(null);
  const svgRef = cuseRef(null);

  const xStep = innerW / Math.max(1, xLabels.length - 1);

  function path(data) {
    return data.map((v, i) => {
      const x = padL + i * xStep;
      const y = padT + innerH - (v / maxV) * innerH;
      return (i === 0 ? "M" : "L") + x + "," + y;
    }).join(" ");
  }
  function areaPath(data) {
    let p = "M" + padL + "," + (padT + innerH) + " ";
    data.forEach((v, i) => {
      const x = padL + i * xStep;
      const y = padT + innerH - (v / maxV) * innerH;
      p += "L" + x + "," + y + " ";
    });
    p += "L" + (padL + (data.length - 1) * xStep) + "," + (padT + innerH) + " Z";
    return p;
  }

  function onMove(e) {
    const rect = svgRef.current.getBoundingClientRect();
    const scaleX = w / rect.width;
    const mx = (e.clientX - rect.left) * scaleX;
    const idx = Math.round((mx - padL) / xStep);
    if (idx >= 0 && idx < xLabels.length) setHoverX(idx);
    else setHoverX(null);
  }

  return (
    <div style={{ position: "relative", width: "100%" }}>
      <svg
        ref={svgRef}
        width="100%" height={h} viewBox={`0 0 ${w} ${h}`}
        preserveAspectRatio="none"
        style={{ display: "block" }}
        onMouseMove={onMove}
        onMouseLeave={() => setHoverX(null)}
      >
        {/* grid */}
        {Array.from({ length: yTicks + 1 }, (_, i) => {
          const y = padT + (innerH / yTicks) * i;
          const v = maxV - (maxV / yTicks) * i;
          return (
            <g key={i}>
              <line x1={padL} y1={y} x2={w - padR} y2={y} stroke="#E3E8EF" strokeWidth="1" />
              <text x={padL - 8} y={y + 3} fontSize="10" fill="#94A3B8" textAnchor="end">{Math.round(v)}</text>
            </g>
          );
        })}
        {/* x labels */}
        {xLabels.map((l, i) => {
          if (xLabels.length > 14 && i % 2 !== 0 && i !== xLabels.length - 1) return null;
          const x = padL + i * xStep;
          return <text key={i} x={x} y={h - 8} fontSize="10" fill="#94A3B8" textAnchor="middle">{l}</text>;
        })}
        {/* areas */}
        {series.map((s, i) => (
          <path key={"a-" + s.label} d={areaPath(s.data)} fill={s.color || CHART_COLORS[i]} opacity="0.10" />
        ))}
        {/* lines */}
        {series.map((s, i) => (
          <path key={"l-" + s.label} d={path(s.data)} stroke={s.color || CHART_COLORS[i]} strokeWidth="2" fill="none" />
        ))}
        {/* hover line + points */}
        {hoverX != null && (
          <g>
            <line
              x1={padL + hoverX * xStep} y1={padT}
              x2={padL + hoverX * xStep} y2={padT + innerH}
              stroke="#CBD5E1" strokeWidth="1" strokeDasharray="3,3"
            />
            {series.map((s, i) => {
              const v = s.data[hoverX];
              const y = padT + innerH - (v / maxV) * innerH;
              return <circle key={i} cx={padL + hoverX * xStep} cy={y} r="3.5" fill="white" stroke={s.color || CHART_COLORS[i]} strokeWidth="2" />;
            })}
          </g>
        )}
      </svg>
      {hoverX != null && (
        <div className="tooltip" style={{ left: `calc(${(padL + hoverX * xStep) / w * 100}% - 60px)`, top: 10 }}>
          <div style={{ fontSize: 10.5, color: "rgba(255,255,255,0.6)", marginBottom: 4 }}>{xLabels[hoverX]}</div>
          {series.map((s, i) => (
            <div className="tooltip__row" key={i}>
              <span style={{ width: 8, height: 8, borderRadius: 2, background: s.color || CHART_COLORS[i], display: "inline-block" }} />
              <span style={{ color: "rgba(255,255,255,0.85)" }}>{s.label}</span>
              <strong style={{ marginLeft: 6 }}>{s.data[hoverX]}</strong>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

/* ---------- Heatmap (weekday x hour, or weekday x DRG) ---------- */
function Heatmap({ rows, cols, matrix, formatValue, onCellClick, cellH = 22 }) {
  const w = 760;
  const labelW = 110;
  const padT = 30, padR = 10;
  const innerW = w - labelW - padR;
  const cellW = innerW / cols.length;
  const h = padT + rows.length * cellH + 20;
  const max = Math.max(1, ...matrix.flat());
  const [hover, setHover] = cuseState(null);

  return (
    <div style={{ position: "relative" }}>
      <svg width="100%" height={h} viewBox={`0 0 ${w} ${h}`} style={{ display: "block" }} preserveAspectRatio="xMidYMid meet">
        {cols.map((c, i) => (
          <text key={i} x={labelW + i * cellW + cellW / 2} y={padT - 8} fontSize="10.5" fill="#64748B" textAnchor="middle" fontWeight="500">{c}</text>
        ))}
        {rows.map((r, ri) => (
          <text key={ri} x={labelW - 8} y={padT + ri * cellH + cellH / 2 + 4} fontSize="11.5" fill="#334155" textAnchor="end" fontWeight="500">{r}</text>
        ))}
        {rows.map((r, ri) => (
          matrix[ri].map((v, ci) => {
            const alpha = 0.15 + 0.85 * (v / max);
            return (
              <rect
                key={ri + "-" + ci}
                className="heatmap-cell"
                x={labelW + ci * cellW + 1}
                y={padT + ri * cellH + 1}
                width={cellW - 2}
                height={cellH - 2}
                fill="#008A3D"
                fillOpacity={alpha}
                rx="2"
                onMouseEnter={() => setHover({ row: r, col: cols[ci], value: v, x: labelW + ci * cellW + cellW / 2, y: padT + ri * cellH })}
                onMouseLeave={() => setHover(null)}
                onClick={() => onCellClick && onCellClick({ row: r, col: cols[ci], value: v, ri, ci })}
              />
            );
          })
        ))}
      </svg>
      {hover && (
        <div className="tooltip" style={{ left: `calc(${hover.x / w * 100}% - 70px)`, top: hover.y - 4 }}>
          <div><strong>{hover.row}</strong> · {hover.col}</div>
          <div style={{ color: "rgba(255,255,255,0.7)" }}>{formatValue ? formatValue(hover.value) : hover.value}</div>
        </div>
      )}
    </div>
  );
}

/* ---------- Sparkline ---------- */
function Sparkline({ data, width = 80, height = 24, color = "#008A3D" }) {
  const max = Math.max(1, ...data);
  const min = Math.min(...data);
  const range = max - min || 1;
  const step = width / (data.length - 1);
  const points = data.map((v, i) => [i * step, height - ((v - min) / range) * (height - 4) - 2]);
  const d = points.map(([x, y], i) => (i === 0 ? "M" : "L") + x.toFixed(1) + "," + y.toFixed(1)).join(" ");
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
      <path d={d} stroke={color} strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

Object.assign(window, { BarChartH, DonutChart, LineChart, Heatmap, Sparkline, CHART_COLORS });
