import { memo, useState, useEffect, useRef } from "react";
import type { ReactElement } from "react";

interface ChartData {
  labels: string[];
  datasets: Array<{ label: string; data: number[]; color?: string }>;
  type?: "bar" | "line" | "pie" | "doughnut";
  title?: string;
}

function parseChartData(raw: string): ChartData | null {
  try {
    return JSON.parse(raw) as ChartData;
  } catch {
    // try to extract JSON from markdown
    const match = raw.match(/```(?:json)?\s*([\s\S]*?)```/);
    if (match) {
      try { return JSON.parse(match[1]) as ChartData; } catch { /* continue */ }
    }
    return null;
  }
}

function polarToCart(cx: number, cy: number, r: number, angle: number) {
  return { x: cx + r * Math.cos(angle), y: cy + r * Math.sin(angle) };
}

function PieChart({ data, w = 240, h = 200 }: { data: ChartData; w?: number; h?: number }) {
  const cx = w / 2 - 10, cy = h / 2;
  const r = Math.min(cx, cy) - 20;
  const COLORS = ["#4f8ef7","#7c4dff","#22c55e","#f59e0b","#ef4444","#06b6d4","#ec4899","#a3e635"];

  const all = data.datasets.flatMap(d => d.data);
  const total = all.reduce((a, b) => a + b, 0);
  if (total === 0) return null;

  const slices: ReactElement[] = [];
  let startAngle = -Math.PI / 2;

  all.forEach((val, i) => {
    const angle = (val / total) * 2 * Math.PI;
    const end = startAngle + angle;
    const mid = startAngle + angle / 2;
    const p1 = polarToCart(cx, cy, r, startAngle);
    const p2 = polarToCart(cx, cy, r, end);
    const largeArc = angle > Math.PI ? 1 : 0;
    const color = COLORS[i % COLORS.length];

    slices.push(
      <path key={i}
        d={`M ${cx} ${cy} L ${p1.x} ${p1.y} A ${r} ${r} 0 ${largeArc} 1 ${p2.x} ${p2.y} Z`}
        fill={color} stroke="#0d0d18" strokeWidth={2}
        style={{ transition: "opacity 0.12s" }}
      />,
      val / total > 0.05 ? (
        <text key={`l${i}`}
          x={polarToCart(cx, cy, r * 0.65, mid).x}
          y={polarToCart(cx, cy, r * 0.65, mid).y}
          textAnchor="middle" dominantBaseline="middle"
          fill="#fff" fontSize={9} fontWeight="600">
          {Math.round((val / total) * 100)}%
        </text>
      ) : <></>,
    );
    startAngle = end;
  });

  const labels = data.labels || all.map((_, i) => `Item ${i+1}`);

  return (
    <svg width={w} height={h}>
      {slices}
      {labels.slice(0, 6).map((l, i) => (
        <g key={i} transform={`translate(${w - 70}, ${20 + i * 18})`}>
          <rect width={10} height={10} rx={2} fill={COLORS[i % COLORS.length]} />
          <text x={14} y={9} fill="#9090a8" fontSize={9}>{l.slice(0, 10)}</text>
        </g>
      ))}
    </svg>
  );
}

const ChartBlock = memo(function ChartBlock({ content }: { content: string }) {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [error, _setError] = useState<string | null>(null);
  const data = parseChartData(content);

  useEffect(() => {
    if (!data || !canvasRef.current) return;
    if (data.type === "pie" || data.type === "doughnut") return;
    const canvas = canvasRef.current;
    const ctx = canvas.getContext("2d");
    if (!ctx) return;

    const COLORS = ["#4f8ef7","#7c4dff","#22c55e","#f59e0b","#ef4444","#06b6d4","#ec4899"];
    const w = canvas.width, h = canvas.height;
    const pad = { top: 20, right: 20, bottom: 35, left: 40 };
    const chartW = w - pad.left - pad.right;
    const chartH = h - pad.top - pad.bottom;

    ctx.clearRect(0, 0, w, h);

    const allVals = data.datasets.flatMap(d => d.data);
    const maxVal = Math.max(...allVals, 1);
    const minVal = Math.min(0, ...allVals);

    // Grid
    ctx.strokeStyle = "#1e1e2e";
    ctx.lineWidth = 1;
    const ySteps = 4;
    for (let i = 0; i <= ySteps; i++) {
      const y = pad.top + (i / ySteps) * chartH;
      ctx.beginPath(); ctx.moveTo(pad.left, y); ctx.lineTo(pad.left + chartW, y); ctx.stroke();
      const val = maxVal - (i / ySteps) * (maxVal - minVal);
      ctx.fillStyle = "#5a5a72"; ctx.font = "9px sans-serif"; ctx.textAlign = "right";
      ctx.fillText(val.toFixed(1), pad.left - 4, y + 3);
    }

    const barGroupW = chartW / data.labels.length;
    const barCount = data.datasets.length;
    const barW = Math.min(barGroupW * 0.7 / barCount, 40);
    const yZero = pad.top + chartH * (maxVal / (maxVal - minVal));

    data.datasets.forEach((ds, di) => {
      ctx.fillStyle = ds.color || COLORS[di % COLORS.length];
      ctx.strokeStyle = ds.color || COLORS[di % COLORS.length];
      ctx.lineWidth = 2;

      if (data.type === "line") {
        ctx.beginPath();
        ds.data.forEach((val, xi) => {
          const x = pad.left + barGroupW * (xi + 0.5);
          const y = pad.top + chartH * (1 - (val - minVal) / (maxVal - minVal));
          if (xi === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
        });
        ctx.stroke();
        ds.data.forEach((val, xi) => {
          const x = pad.left + barGroupW * (xi + 0.5);
          const y = pad.top + chartH * (1 - (val - minVal) / (maxVal - minVal));
          ctx.beginPath(); ctx.arc(x, y, 3, 0, Math.PI * 2); ctx.fill();
        });
      } else {
        ds.data.forEach((val, xi) => {
          const x = pad.left + barGroupW * xi + (barGroupW - barCount * barW) / 2 + di * barW;
          const barH = Math.abs((val / (maxVal - minVal)) * chartH);
          const y = val >= 0 ? yZero - barH : yZero;
          ctx.fillRect(x, y, barW - 2, barH);
        });
      }
    });

    // X labels
    ctx.fillStyle = "#5a5a72"; ctx.font = "9px sans-serif"; ctx.textAlign = "center";
    data.labels.forEach((l, i) => {
      const x = pad.left + barGroupW * (i + 0.5);
      ctx.fillText(l.slice(0, 10), x, pad.top + chartH + 14);
    });

  }, [data]);

  if (!data) {
    return (
      <div style={{ padding: "0.5rem 0.75rem", background: "#12121f", borderRadius: 8, border: "1px solid #222236", color: "#fca5a5", fontSize: "0.78rem" }}>
        Formato grafico non valido. Usa JSON con: labels, datasets[].data, type (bar|line|pie).
      </div>
    );
  }

  const isPie = data.type === "pie" || data.type === "doughnut";

  return (
    <div style={{ background: "#0d0d18", borderRadius: 10, border: "1px solid #1e1e2e", overflow: "hidden", marginBottom: "0.6em" }}>
      {data.title && (
        <div style={{ padding: "0.5rem 0.85rem", borderBottom: "1px solid #1e1e2e", fontSize: "0.8rem", fontWeight: 600, color: "#c0c0d0" }}>
          {data.title}
        </div>
      )}
      <div style={{ padding: "0.75rem", display: "flex", justifyContent: "center" }}>
        {isPie ? (
          <PieChart data={data} />
        ) : (
          <canvas ref={canvasRef} width={420} height={220} style={{ maxWidth: "100%" }} />
        )}
      </div>
      {error && <div style={{ padding: "0.4rem 0.85rem", color: "#fca5a5", fontSize: "0.75rem" }}>{error}</div>}
    </div>
  );
}
);
export default ChartBlock;
