'use client';

import { useMemo } from 'react';
import { CartesianGrid, Label, Scatter, ScatterChart, XAxis, YAxis, ZAxis } from 'recharts';
import type { SuperJSONResult } from 'superjson';

import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card.js';
import { ChartContainer, ChartTooltip, ChartTooltipContent, type ChartConfig } from '@/components/ui/chart.js';
import { deserialize } from '@/lib/superjson.js';

interface RegionCapacityPrice {
  region_code: string;
  avg_price: number;
  total_capacity_mw: number;
}

interface CorrelationChartProps {
  data: SuperJSONResult;
}

const REGION_COLORS: Record<string, string> = {
  PJM: 'hsl(210, 90%, 55%)',
  ERCOT: 'hsl(25, 90%, 55%)',
  CAISO: 'hsl(140, 70%, 45%)',
  NYISO: 'hsl(280, 70%, 55%)',
  ISONE: 'hsl(340, 70%, 55%)',
  MISO: 'hsl(55, 80%, 50%)',
  SPP: 'hsl(180, 60%, 45%)',
};

const chartConfig: ChartConfig = {
  correlation: {
    label: 'DC Capacity vs. Avg Price',
    color: 'hsl(210, 90%, 55%)',
  },
};

interface ScatterPoint {
  region_code: string;
  total_capacity_mw: number;
  avg_price: number;
  fill: string;
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null;
}

function getNumberProp(obj: Record<string, unknown>, key: string): number {
  const val = obj[key];
  return typeof val === 'number' ? val : 0;
}

function getScatterPayload(obj: Record<string, unknown>): ScatterPoint | null {
  const payload = obj['payload'];
  if (!isRecord(payload)) return null;
  const regionCode = typeof payload['region_code'] === 'string' ? payload['region_code'] : '';
  const fill = typeof payload['fill'] === 'string' ? payload['fill'] : 'hsl(0,0%,50%)';
  return {
    region_code: regionCode,
    total_capacity_mw: getNumberProp(payload, 'total_capacity_mw'),
    avg_price: getNumberProp(payload, 'avg_price'),
    fill,
  };
}

function CustomDot(props: unknown): React.JSX.Element {
  if (!isRecord(props)) return <g />;
  const cx = getNumberProp(props, 'cx');
  const cy = getNumberProp(props, 'cy');
  const payload = getScatterPayload(props);
  if (!payload) return <g />;

  return (
    <g>
      <circle cx={cx} cy={cy} r={8} fill={payload.fill} fillOpacity={0.7} stroke={payload.fill} strokeWidth={2} />
      <text x={cx} y={cy - 14} textAnchor="middle" fill="hsl(var(--foreground))" fontSize={11} fontWeight={600}>
        {payload.region_code}
      </text>
    </g>
  );
}

export function CorrelationChart({ data }: CorrelationChartProps) {
  const rows = useMemo(() => deserialize<RegionCapacityPrice[]>(data), [data]);

  const scatterData: ScatterPoint[] = useMemo(
    () =>
      rows
        .filter(r => r.total_capacity_mw > 0 || r.avg_price > 0)
        .map(r => ({
          region_code: r.region_code,
          total_capacity_mw: Math.round(r.total_capacity_mw),
          avg_price: Number(r.avg_price.toFixed(2)),
          fill: REGION_COLORS[r.region_code] ?? 'hsl(0, 0%, 50%)',
        })),
    [rows],
  );

  if (scatterData.length === 0) {
    return (
      <Card>
        <CardHeader>
          <CardTitle>DC Capacity vs. Electricity Price</CardTitle>
          <CardDescription>No data available for correlation analysis.</CardDescription>
        </CardHeader>
        <CardContent>
          <div className="flex h-64 items-center justify-center rounded-lg border border-dashed border-border">
            <p className="text-sm text-muted-foreground">
              No data available. Ingest price data and seed datacenters first.
            </p>
          </div>
        </CardContent>
      </Card>
    );
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle>DC Capacity vs. Electricity Price</CardTitle>
        <CardDescription>Datacenter capacity (MW) versus average electricity price per region</CardDescription>
      </CardHeader>
      <CardContent>
        <ChartContainer config={chartConfig} className="h-[350px] w-full">
          <ScatterChart margin={{ top: 20, right: 20, bottom: 20, left: 20 }}>
            <CartesianGrid strokeDasharray="3 3" className="stroke-border/30" />
            <XAxis
              type="number"
              dataKey="total_capacity_mw"
              name="DC Capacity"
              tick={{ fontSize: 11, fill: '#a1a1aa' }}
              tickLine={false}
              axisLine={false}
              tickFormatter={(v: number) => `${v} MW`}>
              <Label
                value="Total DC Capacity (MW)"
                offset={-10}
                position="insideBottom"
                style={{ fontSize: 11, fill: '#a1a1aa' }}
              />
            </XAxis>
            <YAxis
              type="number"
              dataKey="avg_price"
              name="Avg Price"
              tick={{ fontSize: 11, fill: '#a1a1aa' }}
              tickLine={false}
              axisLine={false}
              tickFormatter={(v: number) => `$${v}`}>
              <Label
                value="Avg Price ($/MWh)"
                angle={-90}
                position="insideLeft"
                style={{ fontSize: 11, fill: '#a1a1aa' }}
              />
            </YAxis>
            <ZAxis range={[200, 200]} />
            <ChartTooltip
              content={
                <ChartTooltipContent
                  formatter={(value, name) => {
                    const nameStr = String(name);
                    const valStr = String(value);
                    if (nameStr === 'DC Capacity') return [`${valStr} MW`, undefined];
                    if (nameStr === 'Avg Price') return [`$${valStr}/MWh`, undefined];
                    return [valStr, undefined];
                  }}
                />
              }
            />
            <Scatter name="Regions" data={scatterData} shape={CustomDot} />
          </ScatterChart>
        </ChartContainer>
      </CardContent>
    </Card>
  );
}
