import { memo, useMemo } from "react";
import { Area, CartesianGrid, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";

import type { TrendPoint } from "../../shared/api";

interface IncidentDotProps {
  cx?: number | string;
  cy?: number | string;
  payload?: TrendPoint;
}

interface TrendChartProps {
  data: TrendPoint[];
}

export const TrendChart = memo(function TrendChart({ data }: TrendChartProps) {
  const chartData = useMemo(
    () =>
      data.map((point) => ({
        ...point,
        durationRange:
          point.minDurationMs !== null && point.maxDurationMs !== null
            ? [point.minDurationMs, point.maxDurationMs]
            : null,
        label: formatBucketLabel(point.bucketStart),
      })),
    [data],
  );

  if (data.length === 0) {
    return <div className="trend-empty">暂无趋势数据</div>;
  }

  return (
    <div className="trend-chart">
      <ResponsiveContainer height={240} width="100%">
        <LineChart data={chartData}>
          <CartesianGrid stroke="var(--td-border-level-2-color)" strokeDasharray="3 3" />
          <XAxis dataKey="label" stroke="var(--td-text-color-secondary)" tick={{ fontSize: 12 }} />
          <YAxis
            label={{ fontSize: 11, position: "insideTopRight", value: "ms" }}
            stroke="var(--td-text-color-secondary)"
            tick={{ fontSize: 12 }}
            yAxisId="duration"
          />
          <Tooltip
            formatter={(value: unknown, name: unknown) => {
              const nameStr = String(name);
              if (nameStr === "durationRange" && Array.isArray(value)) {
                return [`${Math.round(Number(value[0]))}ms - ${Math.round(Number(value[1]))}ms`, "延迟范围"];
              }
              const num = Number(value);
              if (nameStr === "avgDurationMs") return [`${Math.round(num)}ms`, "平均耗时"];
              return [String(value), nameStr];
            }}
          />
          <Area
            dataKey="durationRange"
            fill="var(--td-brand-color-light)"
            fillOpacity={0.2}
            name="durationRange"
            stroke="var(--td-brand-color-light)"
            type="monotone"
            yAxisId="duration"
          />
          <Line
            dataKey="avgDurationMs"
            dot={renderIncidentDot}
            name="avgDurationMs"
            stroke="var(--td-brand-color)"
            strokeWidth={2}
            type="monotone"
            yAxisId="duration"
          />
        </LineChart>
      </ResponsiveContainer>
    </div>
  );
});

function formatBucketLabel(bucketStart: string): string {
  return new Date(bucketStart).toLocaleTimeString("zh-CN", { hour: "2-digit", hour12: false, minute: "2-digit" });
}

function renderIncidentDot(props: IncidentDotProps) {
  const { cx, cy, payload } = props;
  if (!payload || payload.availability >= 100 || payload.avgDurationMs === null) return <></>;

  return (
    <circle
      cx={Number(cx)}
      cy={Number(cy)}
      fill="var(--td-error-color)"
      r={4}
      stroke="var(--td-bg-color-container)"
      strokeWidth={2}
    />
  );
}
