import { formatUSD, asDollars } from '@/lib/money';

const W = 720;
const H = 300;
const PAD = { left: 68, right: 24, top: 20, bottom: 56 };
const CW = W - PAD.left - PAD.right;
const CH = H - PAD.top - PAD.bottom;

interface TrackPoint {
  month: number;
  balance: number;
}

interface ChartPoint {
  x: number;
  y: number;
  month: number;
  balance: number;
}

function money(v: number | string | null | undefined): string {
  const n = Number(v) || 0;
  if (n >= 1000) return `$${(n / 1000).toFixed(0)}k`;
  return `$${n.toFixed(0)}`;
}

function fullMoney(v: number): string {
  return formatUSD(asDollars(v));
}

function buildPoints(track: TrackPoint[], startBalance: number, maxMonths: number): ChartPoint[] {
  const all = [{ month: 0, balance: startBalance }, ...track];
  return all.map(({ month, balance }) => ({
    x: PAD.left + (month / maxMonths) * CW,
    y: PAD.top + CH - (balance / startBalance) * CH,
    month,
    balance,
  }));
}

function toLine(pts: { x: number; y: number }[]): string {
  return pts.map((p) => `${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(' ');
}

interface PayoffChartProps {
  minTrack?: TrackPoint[];
  simTrack?: TrackPoint[];
  startBalance?: number;
}

export default function PayoffChart({
  minTrack = [],
  simTrack = [],
  startBalance = 1,
}: PayoffChartProps) {
  const maxMonths = Math.max(minTrack.length, simTrack.length, 12);
  const bal = Math.max(startBalance, 1);

  const minPts = buildPoints(minTrack, bal, maxMonths);
  const simPts = buildPoints(simTrack, bal, maxMonths);

  const xStep = maxMonths <= 24 ? 6 : maxMonths <= 60 ? 12 : 24;
  const xLabels: number[] = [];
  for (let m = xStep; m <= maxMonths; m += xStep) {
    xLabels.push(m);
  }

  const yTicks = [0, 0.25, 0.5, 0.75, 1];

  return (
    <div className="w-full overflow-hidden rounded-xl border border-border/60 bg-background/60">
      <svg
        viewBox={`0 0 ${W} ${H}`}
        role="img"
        aria-label="Loan payoff chart"
        className="h-auto w-full"
      >
        {/* Grid + Y axis */}
        {yTicks.map((tick) => {
          const y = PAD.top + CH - tick * CH;
          return (
            <g key={tick}>
              <line
                x1={PAD.left}
                x2={PAD.left + CW}
                y1={y}
                y2={y}
                stroke="currentColor"
                opacity="0.08"
                strokeWidth="1"
              />
              <text
                x={PAD.left - 6}
                y={y + 4}
                fontSize="11"
                fill="currentColor"
                opacity="0.5"
                textAnchor="end"
              >
                {money(bal * tick)}
              </text>
            </g>
          );
        })}

        {/* X axis labels */}
        {xLabels.map((m) => {
          const x = PAD.left + (m / maxMonths) * CW;
          return (
            <text
              key={m}
              x={x}
              y={H - 38}
              fontSize="11"
              fill="currentColor"
              opacity="0.5"
              textAnchor="middle"
            >
              {m}mo
            </text>
          );
        })}

        {/* X axis baseline */}
        <line
          x1={PAD.left}
          x2={PAD.left + CW}
          y1={PAD.top + CH}
          y2={PAD.top + CH}
          stroke="currentColor"
          opacity="0.12"
          strokeWidth="1"
        />

        {/* Min-only track (slate dashed) */}
        {minPts.length > 1 && (
          <polyline
            points={toLine(minPts)}
            fill="none"
            stroke="#94a3b8"
            strokeWidth="1.5"
            strokeDasharray="6,4"
            strokeLinecap="round"
            strokeLinejoin="round"
          />
        )}

        {/* Simulation track (amber solid, prominent) */}
        {simPts.length > 1 && (
          <>
            <polyline
              points={toLine(simPts)}
              fill="none"
              stroke="#f59e0b"
              strokeWidth="3"
              strokeLinecap="round"
              strokeLinejoin="round"
            />
            {/* Endpoint dot */}
            {(() => {
              const last = simPts[simPts.length - 1]!;
              return <circle cx={last.x} cy={last.y} r="4" fill="#f59e0b" />;
            })()}
          </>
        )}

        {/* Tooltips at 6-month intervals on sim track */}
        {simPts
          .filter((p) => p.month > 0 && p.month % 6 === 0)
          .map((p) => (
            <circle key={p.month} cx={p.x} cy={p.y} r="3" fill="#f59e0b" opacity="0.7">
              <title>{`Month ${p.month}: ${fullMoney(p.balance)} remaining`}</title>
            </circle>
          ))}

        {/* Legend */}
        <g
          transform={`translate(${PAD.left}, ${H - 22})`}
          fontSize="11"
          fill="currentColor"
          opacity="0.7"
        >
          {minPts.length > 1 && (
            <>
              <line
                x1="0"
                x2="16"
                y1="0"
                y2="0"
                stroke="#94a3b8"
                strokeWidth="1.5"
                strokeDasharray="4,3"
              />
              <text x="20" y="4">
                Min only
              </text>
            </>
          )}
          <line
            x1={minPts.length > 1 ? 80 : 0}
            x2={minPts.length > 1 ? 96 : 16}
            y1="0"
            y2="0"
            stroke="#f59e0b"
            strokeWidth="2.5"
          />
          <text x={minPts.length > 1 ? 100 : 20} y="4">
            Your plan
          </text>
        </g>
      </svg>
    </div>
  );
}
