'use client';

import 'uplot/dist/uPlot.min.css';
import { useState, useEffect } from 'react';
import uPlot from 'uplot';

import { CardShell } from './CardShell';
import {
  makeYScale,
  makeAnnotationHooks,
  makeSignalsSeries,
  makeSignalsAxes,
  CURSOR_NO_DRAG,
} from './plotHelpers';
import { buildSeriesData } from './seriesData';
import { usePlot } from './usePlot';

import type { ColorMap } from '@/lib/colors';
import type { AlertConfig, ChartConfig, SessionBoundary, SignalRow, TimeMode } from '@/lib/types';

import { getColorMap } from '@/lib/colors';
import { useApp } from '@/lib/context';
import { resolveName } from '@/lib/localization';

interface Props {
  config: ChartConfig;
  rows: SignalRow[];
  sessions: SessionBoundary[];
  alerts: AlertConfig[];
  timeMode: TimeMode;
  onEdit: () => void;
  onDelete: () => void;
}

export default function SignalsChart({
  config,
  rows,
  sessions,
  alerts,
  timeMode,
  onEdit,
  onDelete,
}: Props) {
  const { localeMap } = useApp();
  const locale = typeof navigator !== 'undefined' ? navigator.language : 'de-DE';
  const [colorMap, setColorMap] = useState<ColorMap>(new Map());
  useEffect(() => {
    getColorMap().then(setColorMap);
  }, []);

  const { containerRef, legendRef } = usePlot(
    (el, w, h, lRef) => {
      const data = buildSeriesData(rows, config.signal_type, timeMode, config.series_limit);
      if (!data) return null;

      const { keys, allXs, data: seriesData } = data;
      const sessionXs = sessions.map((s) =>
        timeMode === 'tick' ? s.game_tick : new Date(s.real_time).getTime() / 1000,
      );
      const alertThresholds = alerts
        .filter((a) => config.signal_type === 'both' || config.signal_type === a.signal_type)
        .map((a) => a.threshold);

      return new uPlot(
        {
          width: w,
          height: h,
          cursor: CURSOR_NO_DRAG,
          legend: {
            mount: (_u, legendEl) => {
              if (lRef.current) lRef.current.appendChild(legendEl);
            },
          },
          series: makeSignalsSeries(keys, timeMode, (key) => resolveName(key, localeMap), colorMap),
          axes: makeSignalsAxes(timeMode, locale),
          scales: {
            x: { time: false },
            y: makeYScale(config.y_min ?? null, config.y_max ?? null, config.y_scale),
          },
          hooks: makeAnnotationHooks(sessionXs, alertThresholds),
        },
        [allXs, ...seriesData],
        el,
      );
    },
    [
      rows,
      sessions,
      alerts,
      config.signal_type,
      config.y_min,
      config.y_max,
      config.y_scale,
      timeMode,
      localeMap,
    ],
  );

  return (
    <CardShell
      title={config.title}
      onEdit={onEdit}
      onDelete={onDelete}
      empty={rows.length === 0}
      legendContainerRef={legendRef}
    >
      <div ref={containerRef as React.RefObject<HTMLDivElement>} className="w-full h-full" />
    </CardShell>
  );
}
