import { TrendingDown, TrendingUp, Minus } from "lucide-react";
import { formatCompactINR } from "@/lib/utils";

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

type Props = {
  points: PricePoint[];
  unit: string;
  title?: string;
  subtitle?: string;
};

const WIDTH = 320;
const HEIGHT = 120;
/** Fewer real observations than this is not a trend (B13). */
export const MIN_TREND_POINTS = 5;

/** 1, 2, 2.5 or 5 × 10ⁿ — the step a person would pick for this range. */
function niceStep(rough: number): number {
  if (!Number.isFinite(rough) || rough <= 0) return 1;
  const magnitude = 10 ** Math.floor(Math.log10(rough));
  const residual = rough / magnitude;
  const nice = residual <= 1 ? 1 : residual <= 2 ? 2 : residual <= 2.5 ? 2.5 : residual <= 5 ? 5 : 10;
  return nice * magnitude;
}

/**
 * Inline SVG line chart. The app has no charting dependency, so a hand-drawn
 * polyline keeps it a server component and adds no bundle weight.
 *
 * The axis scales to the data: a ₹41,600–₹43,000 series gets ₹500 gridlines,
 * not the fixed ₹5,000 steps that drew every real movement as a flat line.
 * Hidden entirely below MIN_TREND_POINTS observations.
 */
export default function PriceTrendChart({ points, unit, title = "Price Trend", subtitle }: Props) {
  if (points.length < MIN_TREND_POINTS) return null;

  const values = points.map((point) => point.value);
  const min = Math.min(...values);
  const max = Math.max(...values);

  // Four gridlines across the data's own range (or ±2% of a flat series).
  const range = max - min || Math.max(max * 0.02, 1);
  const step = niceStep(range / 4);
  const domainMin = Math.floor((min - step * 0.25) / step) * step;
  const domainMax = Math.max(Math.ceil((max + step * 0.25) / step) * step, domainMin + step);
  const span = domainMax - domainMin;

  const x = (index: number) => (index / (points.length - 1)) * WIDTH;
  const y = (value: number) => HEIGHT - ((value - domainMin) / span) * HEIGHT;

  const line = points.map((point, i) => `${x(i).toFixed(2)},${y(point.value).toFixed(2)}`).join(" ");
  const area = `0,${HEIGHT} ${line} ${WIDTH},${HEIGHT}`;

  const ticks: number[] = [];
  for (let value = domainMax; value >= domainMin - step / 2; value -= step) ticks.push(value);

  const last = points.length - 1;
  const labelIndexes = Array.from(new Set([0, Math.round(last / 4), Math.round(last / 2), Math.round((last * 3) / 4), last]));

  const first = values[0];
  const current = values[values.length - 1];
  const changePct = first ? ((current - first) / first) * 100 : 0;
  const trend = changePct > 0.5 ? "up" : changePct < -0.5 ? "down" : "stable";

  const TrendIcon = trend === "up" ? TrendingUp : trend === "down" ? TrendingDown : Minus;
  const trendTone = trend === "up" ? "text-emerald-600" : trend === "down" ? "text-[#CC1414]" : "text-gray-600";
  const trendLabel = trend === "up" ? "Rising" : trend === "down" ? "Falling" : "Stable";

  return (
    <div className="bg-white rounded-2xl border border-gray-100 shadow-sm p-5">
      <h3 className="font-bold text-gray-900 mb-1">{title}</h3>
      <p className="text-xs text-gray-400 mb-4">{subtitle ?? `₹ per ${unit}`}</p>

      <div className="flex gap-2">
        <div className="flex flex-col justify-between text-[10px] text-gray-400" style={{ height: HEIGHT }}>
          {ticks.map((tick) => (
            <span key={tick}>{formatCompactINR(tick)}</span>
          ))}
        </div>

        <div className="flex-1">
          <svg
            viewBox={`0 0 ${WIDTH} ${HEIGHT}`}
            preserveAspectRatio="none"
            className="w-full"
            style={{ height: HEIGHT }}
            role="img"
            aria-label={`${title}: ${points.length} observations`}
          >
            {ticks.map((tick) => (
              <line
                key={tick}
                x1={0}
                x2={WIDTH}
                y1={y(tick)}
                y2={y(tick)}
                stroke="#F3F4F6"
                strokeWidth={1}
                vectorEffect="non-scaling-stroke"
              />
            ))}
            <polygon points={area} fill="#CC1414" opacity={0.06} />
            <polyline
              points={line}
              fill="none"
              stroke="#CC1414"
              strokeWidth={1.5}
              strokeLinejoin="round"
              strokeLinecap="round"
              vectorEffect="non-scaling-stroke"
            />
          </svg>

          <div className="mt-1 flex justify-between text-[10px] text-gray-400">
            {labelIndexes.map((index) => (
              <span key={index}>{points[index]?.label}</span>
            ))}
          </div>
        </div>
      </div>

      <div className="mt-4 flex items-center justify-between border-t border-gray-100 pt-3">
        <span className="text-sm text-gray-500">
          Trend over {points.length} updates ({changePct >= 0 ? "+" : ""}
          {changePct.toFixed(2)}%)
        </span>
        <span className={`flex items-center gap-1 text-sm font-semibold ${trendTone}`}>
          {trendLabel}
          <TrendIcon size={15} />
        </span>
      </div>
    </div>
  );
}
