'use client';

import { useMemo, useState } from 'react';
import { Area, AreaChart, CartesianGrid, Line, LineChart, XAxis, YAxis } from 'recharts';
import type { SuperJSONResult } from 'superjson';

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

import type { GeopoliticalEventRow, OilPriceRow } from '@/actions/conflict.js';

interface OilChartProps {
  oilData: SuperJSONResult;
  events?: SuperJSONResult;
}

interface PivotedRow {
  timestamp: number;
  label: string;
  wti_crude?: number;
  brent_crude?: number;
  spread?: number;
}

const chartConfig: ChartConfig = {
  brent_crude: { label: 'Brent Crude', color: 'hsl(0, 70%, 55%)' },
  wti_crude: { label: 'WTI Crude', color: 'hsl(210, 80%, 55%)' },
  spread: { label: 'WTI-Brent Spread', color: 'hsl(45, 80%, 55%)' },
};

export function OilChart({ oilData, events }: OilChartProps) {
  const [showSpread, setShowSpread] = useState(false);
  const rows = useMemo(() => deserialize<OilPriceRow[]>(oilData), [oilData]);
  const eventRows = useMemo(() => (events ? deserialize<GeopoliticalEventRow[]>(events) : []), [events]);

  const pivoted = useMemo(() => {
    const byDay = new Map<string, PivotedRow>();

    for (const row of rows) {
      const dayKey = row.timestamp.toISOString().slice(0, 10);
      if (!byDay.has(dayKey)) {
        byDay.set(dayKey, {
          timestamp: row.timestamp.getTime(),
          label: row.timestamp.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }),
        });
      }
      const pivot = byDay.get(dayKey)!;
      if (row.commodity === 'wti_crude') pivot.wti_crude = row.price;
      if (row.commodity === 'brent_crude') pivot.brent_crude = row.price;
    }

    const result = Array.from(byDay.values()).sort((a, b) => a.timestamp - b.timestamp);

    // Calculate spread
    for (const row of result) {
      if (row.brent_crude !== undefined && row.wti_crude !== undefined) {
        row.spread = row.brent_crude - row.wti_crude;
      }
    }

    return result;
  }, [rows]);

  // Find event timestamps within data range for annotation markers
  const eventMarkers = useMemo(() => {
    if (pivoted.length === 0 || eventRows.length === 0) return [];
    const minTs = pivoted[0]!.timestamp;
    const maxTs = pivoted[pivoted.length - 1]!.timestamp;
    return eventRows.filter(e => {
      const ts = e.timestamp.getTime();
      return ts >= minTs && ts <= maxTs && (e.severity === 'critical' || e.severity === 'high');
    });
  }, [pivoted, eventRows]);

  if (pivoted.length === 0) {
    return (
      <Card>
        <CardHeader>
          <CardTitle>Oil Prices</CardTitle>
          <CardDescription>No oil price data available yet.</CardDescription>
        </CardHeader>
      </Card>
    );
  }

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center justify-between">
          <div>
            <CardTitle>Oil Prices</CardTitle>
            <CardDescription>WTI & Brent crude with geopolitical event annotations</CardDescription>
          </div>
          <button
            onClick={() => setShowSpread(prev => !prev)}
            className={cn(
              'rounded-full border px-3 py-1 text-xs font-medium transition-colors',
              showSpread
                ? 'border-yellow-500/30 bg-yellow-500/10 text-yellow-300'
                : 'border-border text-muted-foreground',
            )}>
            Show Spread
          </button>
        </div>
      </CardHeader>
      <CardContent>
        <ChartContainer config={chartConfig} className="h-[40vh] max-h-100 min-h-60 w-full">
          {showSpread ? (
            <AreaChart data={pivoted} margin={{ top: 10, right: 30, left: 10, bottom: 0 }}>
              <CartesianGrid strokeDasharray="3 3" className="stroke-border/30" />
              <XAxis
                dataKey="label"
                tick={{ fontSize: 11, fill: 'var(--color-muted-foreground)' }}
                tickLine={false}
                axisLine={false}
                interval="preserveStartEnd"
              />
              <YAxis
                tick={{ fontSize: 11, fill: 'var(--color-muted-foreground)' }}
                tickLine={false}
                axisLine={false}
                tickFormatter={(v: number) => `$${v}`}
              />
              <ChartTooltip
                content={<ChartTooltipContent formatter={value => [`$${Number(value).toFixed(2)}`, undefined]} />}
              />
              <ChartLegend content={<ChartLegendContent />} />
              <Area
                type="monotone"
                dataKey="spread"
                fill="var(--color-spread)"
                fillOpacity={0.3}
                stroke="var(--color-spread)"
                strokeWidth={2}
              />
            </AreaChart>
          ) : (
            <LineChart data={pivoted} margin={{ top: 10, right: 30, left: 10, bottom: 0 }}>
              <CartesianGrid strokeDasharray="3 3" className="stroke-border/30" />
              <XAxis
                dataKey="label"
                tick={{ fontSize: 11, fill: 'var(--color-muted-foreground)' }}
                tickLine={false}
                axisLine={false}
                interval="preserveStartEnd"
              />
              <YAxis
                tick={{ fontSize: 11, fill: 'var(--color-muted-foreground)' }}
                tickLine={false}
                axisLine={false}
                tickFormatter={(v: number) => `$${v}`}
              />
              <ChartTooltip
                content={<ChartTooltipContent formatter={value => [`$${Number(value).toFixed(2)}/bbl`, undefined]} />}
              />
              <ChartLegend content={<ChartLegendContent />} />
              <Line
                type="monotone"
                dataKey="brent_crude"
                stroke="var(--color-brent_crude)"
                strokeWidth={2}
                dot={false}
                connectNulls
              />
              <Line
                type="monotone"
                dataKey="wti_crude"
                stroke="var(--color-wti_crude)"
                strokeWidth={2}
                dot={false}
                connectNulls
              />
            </LineChart>
          )}
        </ChartContainer>

        {/* Event annotations below chart */}
        {eventMarkers.length > 0 && (
          <div className="mt-3 flex flex-wrap gap-1.5">
            {eventMarkers.map(e => {
              const catColor = getCategoryColor(e.category);
              return (
                <span
                  key={e.id}
                  className="inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[10px] font-medium"
                  style={{
                    borderColor: `${catColor}40`,
                    backgroundColor: `${catColor}15`,
                    color: catColor,
                  }}
                  title={e.description}>
                  <span className="h-1.5 w-1.5 rounded-full" style={{ backgroundColor: catColor }} />
                  {e.timestamp.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}: {e.title}
                </span>
              );
            })}
          </div>
        )}
      </CardContent>
    </Card>
  );
}
