/* global React */
const { useMemo } = React;

// Sparkline SVG
function Spark({ data, color = "var(--accent)", height = 28, width = 120, fill = true }) {
  const { path, area, last } = useMemo(() => {
    if (!data || data.length === 0) return { path: "", area: "", last: 0 };
    const min = Math.min(...data);
    const max = Math.max(...data);
    const range = max - min || 1;
    const w = width, h = height;
    const stepX = w / (data.length - 1);
    const pts = data.map((v, i) => [i * stepX, h - ((v - min) / range) * (h - 4) - 2]);
    const path = "M " + pts.map(p => p[0].toFixed(1) + " " + p[1].toFixed(1)).join(" L ");
    const area = path + ` L ${w} ${h} L 0 ${h} Z`;
    return { path, area, last: pts[pts.length - 1][1] };
  }, [data, width, height]);
  const id = useMemo(() => "sg" + Math.random().toString(36).slice(2, 8), []);
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`} style={{ display: "block" }}>
      {fill && (
        <>
          <defs>
            <linearGradient id={id} x1="0" y1="0" x2="0" y2="1">
              <stop offset="0" stopColor={color} stopOpacity="0.35" />
              <stop offset="1" stopColor={color} stopOpacity="0" />
            </linearGradient>
          </defs>
          <path d={area} fill={`url(#${id})`} />
        </>
      )}
      <path d={path} fill="none" stroke={color} strokeWidth="1.5" />
      <circle cx={width} cy={last} r="2.5" fill={color} />
    </svg>
  );
}

// Equity area chart
function EquityChart({ data, height = 280 }) {
  const padding = { top: 16, right: 16, bottom: 24, left: 50 };
  const w = 800, h = height;
  const innerW = w - padding.left - padding.right;
  const innerH = h - padding.top - padding.bottom;

  const { path, area, points, yTicks, xTicks, min, max } = useMemo(() => {
    if (!data?.length) return {};
    const ys = data.map(d => d.y);
    const min = Math.min(...ys);
    const max = Math.max(...ys);
    const yRange = max - min || 1;
    const stepX = innerW / (data.length - 1);
    const pts = data.map((d, i) => [
      padding.left + i * stepX,
      padding.top + innerH - ((d.y - min) / yRange) * innerH
    ]);
    const path = "M " + pts.map(p => p[0].toFixed(1) + " " + p[1].toFixed(1)).join(" L ");
    const area = path + ` L ${padding.left + innerW} ${padding.top + innerH} L ${padding.left} ${padding.top + innerH} Z`;
    const yTicks = [0, 0.25, 0.5, 0.75, 1].map(t => ({
      y: padding.top + innerH - t * innerH,
      label: (min + t * yRange).toFixed(0)
    }));
    const xTicks = [0, 0.25, 0.5, 0.75, 1].map(t => ({
      x: padding.left + t * innerW,
      label: `D-${Math.round((1 - t) * (data.length - 1))}`
    }));
    return { path, area, points: pts, yTicks, xTicks, min, max };
  }, [data, w, h]);

  return (
    <svg viewBox={`0 0 ${w} ${h}`} width="100%" preserveAspectRatio="none" style={{ display: "block" }}>
      <defs>
        <linearGradient id="equityFill" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor="var(--accent)" stopOpacity="0.28" />
          <stop offset="1" stopColor="var(--accent)" stopOpacity="0" />
        </linearGradient>
      </defs>
      {yTicks?.map((t, i) => (
        <g key={"y" + i}>
          <line x1={padding.left} x2={padding.left + innerW} y1={t.y} y2={t.y} stroke="var(--line)" strokeDasharray="2 4" />
          <text x={padding.left - 8} y={t.y + 3} fontSize="10" fontFamily="var(--font-mono)" fill="var(--text-3)" textAnchor="end">${t.label}</text>
        </g>
      ))}
      {xTicks?.map((t, i) => (
        <text key={"x" + i} x={t.x} y={h - 8} fontSize="10" fontFamily="var(--font-mono)" fill="var(--text-3)" textAnchor="middle">{t.label}</text>
      ))}
      {area && <path d={area} fill="url(#equityFill)" />}
      {path && <path d={path} fill="none" stroke="var(--accent)" strokeWidth="1.6" />}
      {points && points.length > 0 && (
        <circle cx={points[points.length - 1][0]} cy={points[points.length - 1][1]} r="3.5" fill="var(--accent)" />
      )}
    </svg>
  );
}

// Bar chart (daily P&L)
function BarChart({ data, height = 200 }) {
  const padding = { top: 12, right: 12, bottom: 24, left: 36 };
  const w = 520, h = height;
  const innerW = w - padding.left - padding.right;
  const innerH = h - padding.top - padding.bottom;
  const max = Math.max(...data.map(Math.abs)) || 1;
  const barW = innerW / data.length - 4;

  return (
    <svg viewBox={`0 0 ${w} ${h}`} width="100%" preserveAspectRatio="none" style={{ display: "block" }}>
      <line x1={padding.left} x2={padding.left + innerW} y1={padding.top + innerH / 2} y2={padding.top + innerH / 2} stroke="var(--line)" />
      {data.map((v, i) => {
        const x = padding.left + i * (barW + 4);
        const barH = (Math.abs(v) / max) * (innerH / 2);
        const y = v >= 0 ? padding.top + innerH / 2 - barH : padding.top + innerH / 2;
        return (
          <rect key={i} x={x} y={y} width={barW} height={barH} fill={v >= 0 ? "var(--green)" : "var(--red)"} opacity="0.85" rx="1" />
        );
      })}
      <text x={padding.left - 6} y={padding.top + 8} fontSize="10" fontFamily="var(--font-mono)" fill="var(--text-3)" textAnchor="end">+${max.toFixed(0)}</text>
      <text x={padding.left - 6} y={padding.top + innerH - 2} fontSize="10" fontFamily="var(--font-mono)" fill="var(--text-3)" textAnchor="end">-${max.toFixed(0)}</text>
    </svg>
  );
}

// Donut for win/loss
function Donut({ wins, losses, size = 140 }) {
  const total = wins + losses;
  const winPct = wins / total;
  const radius = size / 2 - 12;
  const circ = 2 * Math.PI * radius;
  const winLen = circ * winPct;
  return (
    <div style={{ position: "relative", width: size, height: size }}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ transform: "rotate(-90deg)" }}>
        <circle cx={size / 2} cy={size / 2} r={radius} fill="none" stroke="var(--line-2)" strokeWidth="10" />
        <circle cx={size / 2} cy={size / 2} r={radius} fill="none" stroke="var(--green)" strokeWidth="10" strokeDasharray={`${winLen} ${circ}`} strokeLinecap="round" />
      </svg>
      <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", textAlign: "center" }}>
        <div>
          <div className="mono" style={{ fontSize: 22, fontWeight: 600, color: "var(--text-0)" }}>{(winPct * 100).toFixed(1)}%</div>
          <div className="mono" style={{ fontSize: 9, letterSpacing: ".14em", color: "var(--text-2)", textTransform: "uppercase" }}>Win Rate</div>
        </div>
      </div>
    </div>
  );
}

// Heatmap
function Heatmap({ data }) {
  const days = ["Mon", "Tue", "Wed", "Thu", "Fri"];
  const colorFor = (v) => {
    if (v < 0) return `rgba(255,93,108,${Math.min(1, Math.abs(v) * 1.5)})`;
    return `rgba(0,224,255,${Math.min(1, v * 0.9)})`;
  };
  return (
    <div className="heatmap">
      <div></div>
      {Array.from({ length: 24 }).map((_, h) => (
        <div key={h} className="lbl" style={{ textAlign: "center" }}>{h % 4 === 0 ? `${h}h` : ""}</div>
      ))}
      {days.map((d) => (
        <React.Fragment key={d}>
          <div className="lbl">{d}</div>
          {Array.from({ length: 24 }).map((_, h) => {
            const cell = data.find((c) => c.day === d && c.hour === h);
            return <div key={d + h} className="cell" style={{ background: colorFor(cell?.val ?? 0) }} title={`${d} ${h}:00 — ${(cell?.val * 100).toFixed(1)}`} />;
          })}
        </React.Fragment>
      ))}
    </div>
  );
}

Object.assign(window, { Spark, EquityChart, BarChart, Donut, Heatmap });
