// Live utilization chart for one node, fetched from node-usage-series on
// row expand. Two side-by-side single-line panes — CPU and mem as a % of
// the node's allocatable (dashed reference at 100%) at every per-step
// sample over the selected window preset. The chart degrades in place —
// the table stays usable whatever the dataplane does.

import { useState } from "react";
import {
  CartesianGrid,
  Line,
  LineChart,
  ReferenceLine,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from "recharts";
import { fetchNodeUsage } from "@/lib/api-client";
import type { NodeUsagePoint } 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,
  ratioTick,
  ratioValue,
  utc8Tick,
} from "@/lib/chart";
import { Button } from "@/components/ui/Button";
import { TrendWindowBar } from "@/components/regions/TrendWindowSelect";

/** Pure transform: engine points → chart rows as fractions of allocatable. */
export function nodeUsageChartData(
  points: NodeUsagePoint[],
  allocatableCpu: number,
  allocatableMemGib: number,
): Array<{ tick: string; cpu: number; mem: number }> {
  return points.map((p) => ({
    tick: utc8Tick(p.t),
    cpu: allocatableCpu > 0 ? p.cpuCores / allocatableCpu : 0,
    mem: allocatableMemGib > 0 ? p.memGiB / allocatableMemGib : 0,
  }));
}

/** One axis's chart: a single utilization line with a 100% reference. */
function UsagePane(props: {
  title: string;
  data: Array<{ tick: string; cpu: number; mem: number }>;
  dataKey: "cpu" | "mem";
  color: string;
}) {
  const { title, data, dataKey, color } = 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) => ratioTick(Number(v))}
              width={44}
              domain={[0, "auto"]}
            />
            <Tooltip formatter={(value) => ratioValue(Number(value))} />
            <ReferenceLine y={1} stroke={color} strokeDasharray="4 4" />
            <Line type="monotone" dataKey={dataKey} stroke={color} strokeWidth={2} dot={false} />
          </LineChart>
        </ResponsiveContainer>
      </div>
    </div>
  );
}

export function NodeUsageChart(props: {
  regionKey: string;
  node: string;
  allocatableCpu: number;
  allocatableMemGib: number;
}) {
  const { regionKey, node, allocatableCpu, allocatableMemGib } = props;
  const [window, setWindow] = useState<TrendWindowKey>(DEFAULT_TREND_WINDOW);
  const { series, error, retry } = useLiveSeries(
    () => fetchNodeUsage(regionKey, node, window),
    [regionKey, node, window],
  );

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

  if (allocatableCpu <= 0 || allocatableMemGib <= 0) {
    return (
      <div className="mt-2">
        {selector}
        <div className="py-4 text-center text-xs text-text-muted">
          No allocatable recorded for this node.
        </div>
      </div>
    );
  }
  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 node usage…</div>
      </div>
    );
  }
  const data = nodeUsageChartData(series.points, allocatableCpu, allocatableMemGib);
  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>
    );
  }

  return (
    <div className="mt-2">
      {selector}
      <div className="grid gap-4 md:grid-cols-2">
        <UsagePane title="CPU (% of allocatable)" data={data} dataKey="cpu" color={CHART_SERIES.usageCpu} />
        <UsagePane title="Mem (% of allocatable)" data={data} dataKey="mem" color={CHART_SERIES.usageMem} />
      </div>
    </div>
  );
}
