// Live usage trend for one workload, fetched from usage-series on expand.
// Two side-by-side charts — CPU and mem — each plotting the per-pod max
// (dashed), avg (solid), and min (dotted) at every per-step sample over the
// selected window preset: absolute mode (generic groups) in cores/GiB,
// ratio mode (vmcluster) as the VM process-metric utilization percentage.
// The chart degrades in place — the table stays usable whatever the
// dataplane does.

import { useState } from "react";
import {
  CartesianGrid,
  Legend,
  Line,
  LineChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from "recharts";
import { fetchWorkloadUsage } from "@/lib/api-client";
import type { UsagePoint } from "@/lib/api-types";
import { DEFAULT_TREND_WINDOW, type TrendWindowKey } from "@/engine/trend-window";
import { useLiveSeries } from "@/lib/use-live-series";
import {
  CHART_GRID_STROKE,
  CHART_MIN_TICK_GAP,
  CHART_SERIES,
  numTick,
  ratioTick,
  ratioValue,
  utc8Tick,
} from "@/lib/chart";
import { Button } from "@/components/ui/Button";
import { TrendWindowBar } from "@/components/regions/TrendWindowSelect";

/** Pure transform: engine points → chart rows with UTC+8 tick labels. */
export function usageChartData(points: UsagePoint[]): Array<{
  tick: string;
  minCpu: number;
  avgCpu: number;
  maxCpu: number;
  minMem: number;
  avgMem: number;
  maxMem: number;
}> {
  return points.map((p) => ({
    tick: utc8Tick(p.t),
    minCpu: p.minCpu,
    avgCpu: p.avgCpu,
    maxCpu: p.maxCpu,
    minMem: p.minMem,
    avgMem: p.avgMem,
    maxMem: p.maxMem,
  }));
}

/** Legend labels for the three per-pod aggregate series. */
const SERIES_LABELS: Record<string, string> = {
  min: "min across pods",
  avg: "avg across pods",
  max: "max across pods",
};

/** One metric's chart: avg solid, max dashed, min dotted, same series color. */
function TrendPane(props: {
  title: string;
  data: Array<{ tick: string; min: number; avg: number; max: number }>;
  color: string;
  format: (v: number) => string;
  percent: boolean;
}) {
  const { title, data, color, format, percent } = props;
  return (
    <div>
      <div className="mb-1 text-xs font-medium text-text-secondary">{title}</div>
      <div className="h-48">
        <ResponsiveContainer width="100%" height="100%">
          <LineChart data={data} margin={{ top: 4, right: 8, bottom: 0, left: 0 }}>
            <CartesianGrid strokeDasharray="3 3" stroke={CHART_GRID_STROKE} />
            <XAxis dataKey="tick" tick={{ fontSize: 10 }} minTickGap={CHART_MIN_TICK_GAP} />
            <YAxis
              tick={{ fontSize: 10 }}
              tickFormatter={(v) => (percent ? ratioTick(Number(v)) : numTick(Number(v)))}
              width={44}
              domain={percent ? [0, "auto"] : ["auto", "auto"]}
            />
            <Tooltip formatter={(value, key) => [format(Number(value)), String(key)]} />
            <Legend formatter={(v) => SERIES_LABELS[v] ?? v} />
            <Line type="monotone" dataKey="avg" stroke={color} strokeWidth={2} dot={false} />
            <Line type="monotone" dataKey="max" stroke={color} strokeWidth={1.5} strokeDasharray="5 3" dot={false} />
            <Line type="monotone" dataKey="min" stroke={color} strokeWidth={1.5} strokeDasharray="2 4" dot={false} />
          </LineChart>
        </ResponsiveContainer>
      </div>
    </div>
  );
}

export function WorkloadTrendChart(props: {
  regionKey: string;
  ns: string;
  kind: string;
  name: string;
}) {
  const { regionKey, ns, kind, name } = props;
  const [window, setWindow] = useState<TrendWindowKey>(DEFAULT_TREND_WINDOW);
  const { series, error, retry } = useLiveSeries(
    () => fetchWorkloadUsage(regionKey, { ns, kind, name }, window),
    [regionKey, ns, kind, name, window],
  );

  const selector = <TrendWindowBar value={window} onChange={setWindow} />;

  if (error !== null) {
    return (
      <div className="mt-2">
        {selector}
        <div className="flex items-center gap-3 text-xs text-text-muted">
          <span className="text-danger">usage trend unavailable: {error}</span>
          <Button variant="secondary" size="xs" onClick={retry}>
            retry
          </Button>
        </div>
      </div>
    );
  }
  if (series === null) {
    return (
      <div className="mt-2">
        {selector}
        <div className="py-4 text-center text-xs text-text-muted">loading usage trend…</div>
      </div>
    );
  }
  const data = usageChartData(series.points);
  if (data.length < 2) {
    return (
      <div className="mt-2">
        {selector}
        <div className="py-4 text-center text-xs text-text-muted">
          Need at least two samples for a trend.
        </div>
      </div>
    );
  }

  const cpuRows = data.map(({ tick, minCpu, avgCpu, maxCpu }) => ({ tick, min: minCpu, avg: avgCpu, max: maxCpu }));
  const memRows = data.map(({ tick, minMem, avgMem, maxMem }) => ({ tick, min: minMem, avg: avgMem, max: maxMem }));
  const digits = series.mode === "ratio" ? 1 : 2;
  const cpuFormat = (v: number): string =>
    series.mode === "ratio" ? ratioValue(v) : `${v.toFixed(digits)} cores`;
  const memFormat = (v: number): string =>
    series.mode === "ratio" ? ratioValue(v) : `${v.toFixed(digits)} GiB`;
  const cpuTitle = `CPU${series.mode === "ratio" ? " util (VM process)" : " (cores per pod)"}`;
  const memTitle = `Mem${series.mode === "ratio" ? " util (VM process)" : " (GiB per pod)"}`;

  return (
    <div className="mt-2">
      {selector}
      <div className="grid gap-4 md:grid-cols-2">
        <TrendPane title={cpuTitle} data={cpuRows} color={CHART_SERIES.usageCpu} format={cpuFormat} percent={series.mode === "ratio"} />
        <TrendPane title={memTitle} data={memRows} color={CHART_SERIES.usageMem} format={memFormat} percent={series.mode === "ratio"} />
      </div>
    </div>
  );
}
