"use client";

import React from "react";
import { BRAND_600 } from "@/lib/theme";

export type TrendDatum = { label: string; value: number };

// Dependency-free single-series area/line chart, following the same
// hand-rolled-SVG approach as reports/charts/HorizontalBarChart.tsx. A
// single continuous series over time calls for a line/area (dataviz skill
// form heuristic), so this uses one brand-consistent color rather than the
// bar chart's multi-category palette.
const WIDTH = 600;
const HEIGHT = 220;
const PADDING_LEFT = 48; // room for y-axis value labels
const PADDING_RIGHT = 8;
const PADDING_TOP = 12;
const PADDING_BOTTOM = 24;
const GRIDLINES = 4;

const defaultAxisFormatter = (v: number) => new Intl.NumberFormat(undefined, { notation: "compact", maximumFractionDigits: 1 }).format(v);

export function AreaTrendChart({
  data,
  valueFormatter,
  axisFormatter,
}: {
  data: TrendDatum[];
  /** Formats the headline "Latest" value — full precision is fine here. */
  valueFormatter?: (v: number) => string;
  /** Formats the y-axis gridline labels — should stay compact (little horizontal room). Defaults to a compact number (e.g. "1.5k"). */
  axisFormatter?: (v: number) => string;
}) {
  const fmt = valueFormatter || ((v: number) => String(v));
  const axisFmt = axisFormatter || defaultAxisFormatter;

  if (data.length === 0) {
    return <div className="text-xs text-gray-400">No data to chart.</div>;
  }

  const max = Math.max(1, ...data.map(d => d.value));
  const min = Math.min(0, ...data.map(d => d.value));
  const range = max - min || 1;
  const plotWidth = WIDTH - PADDING_LEFT - PADDING_RIGHT;
  const plotHeight = HEIGHT - PADDING_TOP - PADDING_BOTTOM;
  const baseline = PADDING_TOP + plotHeight;

  const points = data.map((d, i) => {
    const x = data.length === 1 ? PADDING_LEFT + plotWidth / 2 : PADDING_LEFT + (i / (data.length - 1)) * plotWidth;
    const y = PADDING_TOP + plotHeight - ((d.value - min) / range) * plotHeight;
    return { x, y, value: d.value };
  });

  const linePath = points.map((p, i) => (i === 0 ? `M ${p.x} ${p.y}` : `L ${p.x} ${p.y}`)).join(" ");
  const areaPath = `${linePath} L ${points[points.length - 1].x} ${baseline} L ${points[0].x} ${baseline} Z`;

  // Horizontal gridlines from 0 up to the max, evenly spaced, with a value label on each.
  const gridlines = Array.from({ length: GRIDLINES + 1 }, (_, i) => {
    const value = min + (range * i) / GRIDLINES;
    const y = PADDING_TOP + plotHeight - (i / GRIDLINES) * plotHeight;
    return { y, value };
  });

  // Show at most ~6 x-axis labels so long series don't crowd the axis.
  const labelStep = Math.max(1, Math.ceil(data.length / 6));
  const visibleLabels = data.filter((_, i) => i % labelStep === 0 || i === data.length - 1);
  const latest = data[data.length - 1];

  return (
    <div>
      <div className="flex items-center justify-between mb-1">
        <span className="text-xs text-gray-500">Latest</span>
        <span className="text-sm font-semibold text-gray-900">{fmt(latest.value)}</span>
      </div>
      <svg viewBox={`0 0 ${WIDTH} ${HEIGHT}`} className="w-full h-auto" role="img" aria-label="Trend chart">
        <defs>
          <linearGradient id="areaTrendFill" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={BRAND_600} stopOpacity="0.25" />
            <stop offset="100%" stopColor={BRAND_600} stopOpacity="0" />
          </linearGradient>
        </defs>
        {gridlines.map((g, i) => (
          <g key={i}>
            <line x1={PADDING_LEFT} y1={g.y} x2={WIDTH - PADDING_RIGHT} y2={g.y} stroke="#F3F4F6" strokeWidth={1} />
            <text x={PADDING_LEFT - 6} y={g.y} textAnchor="end" dominantBaseline="middle" className="fill-gray-400" fontSize={10}>
              {axisFmt(g.value)}
            </text>
          </g>
        ))}
        <path d={areaPath} fill="url(#areaTrendFill)" stroke="none" />
        <path d={linePath} fill="none" stroke={BRAND_600} strokeWidth={2} strokeLinejoin="round" strokeLinecap="round" />
        {points.map((p, i) => (
          <circle key={i} cx={p.x} cy={p.y} r={data.length === 1 ? 4 : 3} fill="#fff" stroke={BRAND_600} strokeWidth={2} />
        ))}
      </svg>
      <div className="flex justify-between mt-1 ml-12 text-[10px] text-gray-400">
        {visibleLabels.map((d, i) => (
          <span key={d.label + i}>{d.label}</span>
        ))}
      </div>
    </div>
  );
}
