import { useEffect, useRef } from "react";
import type { PCOStyle } from "./types";
import { PCO_THEME_DEFAULTS } from "./pcoTheme";

type PortraitSpiderChartProps = {
  labels: string[];
  scores: number[];
  width?: number;
  height?: number;
  colors?: PCOStyle;
};

function wrapLabel(
  ctx: CanvasRenderingContext2D,
  text: string,
  x: number,
  y: number,
  maxWidth: number
) {
  const words = text.split(" ");
  const lines: string[] = [""];
  words.forEach((w) => {
    const test = `${lines[lines.length - 1]} ${w}`.trim();
    if (ctx.measureText(test).width > maxWidth) lines.push(w);
    else lines[lines.length - 1] = test;
  });
  lines.forEach((line, i) => {
    ctx.fillText(line, x, y + (i - (lines.length - 1) / 2) * 12);
  });
}

export function PortraitSpiderChart({
  labels,
  scores,
  width = 340,
  height = 340,
  colors,
}: PortraitSpiderChartProps) {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const d = PCO_THEME_DEFAULTS;

  const gridColor = colors?.chartGridColor?.trim() || colors?.themeLine?.trim() || d.line;
  const axisColor = colors?.chartAxisColor?.trim() || "#e1eaf0";
  const labelColor = colors?.chartLabelColor?.trim() || colors?.themeNavy?.trim() || d.navy;
  const fillColor = colors?.chartFillColor?.trim() || "rgba(13, 124, 134, 0.22)";
  const strokeColor = colors?.chartStrokeColor?.trim() || colors?.themeTeal?.trim() || d.teal;
  const pointColor = colors?.chartPointColor?.trim() || colors?.themeGold?.trim() || d.gold;

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

    const W = width;
    const H = height;
    const cx = W / 2;
    const cy = H / 2;
    const R = 118;
    const n = labels.length;

    ctx.clearRect(0, 0, W, H);
    ctx.font = "11px Inter, Arial, sans-serif";
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";

    for (let ring = 1; ring <= 5; ring++) {
      ctx.beginPath();
      for (let i = 0; i < n; i++) {
        const a = -Math.PI / 2 + (2 * Math.PI * i) / n;
        const r = (R * ring) / 5;
        const x = cx + r * Math.cos(a);
        const y = cy + r * Math.sin(a);
        if (i === 0) ctx.moveTo(x, y);
        else ctx.lineTo(x, y);
      }
      ctx.closePath();
      ctx.strokeStyle = gridColor;
      ctx.stroke();
    }

    for (let i = 0; i < n; i++) {
      const a = -Math.PI / 2 + (2 * Math.PI * i) / n;
      const x = cx + R * Math.cos(a);
      const y = cy + R * Math.sin(a);
      ctx.beginPath();
      ctx.moveTo(cx, cy);
      ctx.lineTo(x, y);
      ctx.strokeStyle = axisColor;
      ctx.stroke();
      const lx = cx + (R + 34) * Math.cos(a);
      const ly = cy + (R + 34) * Math.sin(a);
      ctx.fillStyle = labelColor;
      wrapLabel(ctx, labels[i] ?? "", lx, ly, 72);
    }

    const values = labels.map((_, i) => scores[i] ?? 70);
    ctx.beginPath();
    values.forEach((v, i) => {
      const a = -Math.PI / 2 + (2 * Math.PI * i) / n;
      const r = R * (v / 100);
      const x = cx + r * Math.cos(a);
      const y = cy + r * Math.sin(a);
      if (i === 0) ctx.moveTo(x, y);
      else ctx.lineTo(x, y);
    });
    ctx.closePath();
    ctx.fillStyle = fillColor;
    ctx.fill();
    ctx.strokeStyle = strokeColor;
    ctx.lineWidth = 3;
    ctx.stroke();
    ctx.lineWidth = 1;

    values.forEach((v, i) => {
      const a = -Math.PI / 2 + (2 * Math.PI * i) / n;
      const r = R * (v / 100);
      const x = cx + r * Math.cos(a);
      const y = cy + r * Math.sin(a);
      ctx.beginPath();
      ctx.arc(x, y, 4, 0, Math.PI * 2);
      ctx.fillStyle = pointColor;
      ctx.fill();
    });
  }, [labels, scores, width, height, gridColor, axisColor, labelColor, fillColor, strokeColor, pointColor]);

  return (
    <canvas
      ref={canvasRef}
      width={width}
      height={height}
      className="max-w-full h-auto"
      aria-label="Portrait of the Learner spider chart"
    />
  );
}
