import { Circle, Line, Path, Svg } from '@react-pdf/renderer';

import { SvgLabel } from '../svg-primitives';
import { PDF_TOKENS } from '../tokens';

export interface LineDatum {
  label: string;
  value: number;
}

export interface LineChartProps {
  data: LineDatum[];
  width?: number;
  height?: number;
  color?: string;
  yLabel?: string;
  /** Render circle markers at each point (default true). */
  markers?: boolean;
  /** Optional fixed y-axis max - used when value-space should not auto-zoom. */
  yMax?: number;
}

const MARGIN_LEFT = 44;
const MARGIN_RIGHT = 12;
const MARGIN_TOP = 18;
const MARGIN_BOTTOM = 32;

export function LineChart({
  data,
  width = 480,
  height = 200,
  color = PDF_TOKENS.colors.accentBlue,
  yLabel,
  markers = true,
  yMax,
}: LineChartProps) {
  if (data.length === 0) {
    return (
      <Svg width={width} height={height}>
        <SvgLabel
          x={width / 2}
          y={height / 2}
          textAnchor="middle"
          fontSize={9}
          fill={PDF_TOKENS.colors.textMuted}
        >
          No data
        </SvgLabel>
      </Svg>
    );
  }
  const max = yMax ?? Math.max(...data.map((d) => d.value));
  const chartW = width - MARGIN_LEFT - MARGIN_RIGHT;
  const chartH = height - MARGIN_TOP - MARGIN_BOTTOM;
  const stepX = data.length > 1 ? chartW / (data.length - 1) : 0;
  const yTicks = 4;
  const points = data.map((d, i) => {
    const x = MARGIN_LEFT + i * stepX;
    const y = MARGIN_TOP + chartH - (max === 0 ? 0 : (d.value / max) * chartH);
    return { x, y, d };
  });
  const path = points.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x} ${p.y}`).join(' ');
  return (
    <Svg width={width} height={height}>
      {/* gridlines + y-axis ticks */}
      {Array.from({ length: yTicks + 1 }, (_, i) => {
        const v = (max / yTicks) * (yTicks - i);
        const y = MARGIN_TOP + (chartH / yTicks) * i;
        return (
          <Svg key={`t${i}`}>
            <Line
              x1={MARGIN_LEFT}
              y1={y}
              x2={width - MARGIN_RIGHT}
              y2={y}
              strokeWidth={0.5}
              stroke={PDF_TOKENS.colors.border}
            />
            <SvgLabel
              x={MARGIN_LEFT - 6}
              y={y + 3}
              textAnchor="end"
              fontSize={7}
              fill={PDF_TOKENS.colors.textMuted}
            >
              {formatTick(v)}
            </SvgLabel>
          </Svg>
        );
      })}
      {/* axes */}
      <Line
        x1={MARGIN_LEFT}
        y1={MARGIN_TOP}
        x2={MARGIN_LEFT}
        y2={height - MARGIN_BOTTOM}
        strokeWidth={1}
        stroke={PDF_TOKENS.colors.text}
      />
      <Line
        x1={MARGIN_LEFT}
        y1={height - MARGIN_BOTTOM}
        x2={width - MARGIN_RIGHT}
        y2={height - MARGIN_BOTTOM}
        strokeWidth={1}
        stroke={PDF_TOKENS.colors.text}
      />
      {/* line */}
      <Path d={path} stroke={color} strokeWidth={1.5} fill="none" />
      {/* markers + x-axis labels */}
      {points.map((p, i) => (
        <Svg key={i}>
          {markers ? <Circle cx={p.x} cy={p.y} r={2.5} fill={color} /> : null}
          <SvgLabel
            x={p.x}
            y={height - MARGIN_BOTTOM + 14}
            textAnchor="middle"
            fontSize={7}
            fill={PDF_TOKENS.colors.textMuted}
          >
            {p.d.label}
          </SvgLabel>
        </Svg>
      ))}
      {yLabel ? (
        <SvgLabel
          x={10}
          y={MARGIN_TOP + chartH / 2}
          textAnchor="middle"
          fontSize={8}
          fill={PDF_TOKENS.colors.textMuted}
          transform={`rotate(-90 10 ${MARGIN_TOP + chartH / 2})`}
        >
          {yLabel}
        </SvgLabel>
      ) : null}
    </Svg>
  );
}

function formatTick(v: number): string {
  if (v >= 1_000_000) return `${(v / 1_000_000).toFixed(1)}M`;
  if (v >= 1_000) return `${(v / 1_000).toFixed(1)}k`;
  if (v % 1 !== 0) return v.toFixed(1);
  return v.toLocaleString();
}
