import * as React from 'react';
import { useEffect, useRef, useState } from 'react';
import {
  calculateTrendLines,
  calculateChartStatistics,
  type ChartStatistics,
} from '../utils/chartStatistics';
import { PolynomialEquation } from './PolynomialEquation';

declare global {
  interface Window {
    Chart: any;
  }
}

interface TrackedObjectData {
  x: number;
  y: number;
  scanDate: string;
  durationFormatted: string;
}

interface TrackedObjectsChartProps {
  data: TrackedObjectData[];
  objectKind: string;
}

export const TrackedObjectsChart: React.FC<TrackedObjectsChartProps> = ({
  data,
  objectKind,
}) => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const chartRef = useRef<any>(null);
  const [statistics, setStatistics] = useState<ChartStatistics | null>(null);
  const [isInitialized, setIsInitialized] = useState(false);

  useEffect(() => {
    if (!canvasRef.current || data.length === 0 || !window.Chart) {
      return;
    }

    // Add a small delay to ensure DOM is stable
    const initTimer = setTimeout(() => {
      if (!canvasRef.current) return;

      // Calculate trend lines and statistics
      const trendLines = calculateTrendLines(data);
      const chartStatistics = calculateChartStatistics(data);
      setStatistics(chartStatistics);

      // Create trend line datasets for all polynomial fits
      const minX = Math.min(...data.map((p) => p.x));
      const maxX = Math.max(...data.map((p) => p.x));
      const numPoints = 50; // More points for smooth curve

      const trendLineDatasets = trendLines.map((trendLine) => {
        const trendLineData = [];

        for (let i = 0; i <= numPoints; i++) {
          const x = minX + (maxX - minX) * (i / numPoints);
          // Calculate y using polynomial: y = c₀ + c₁x + c₂x² + ...
          let y = 0;
          for (let j = 0; j < trendLine.coeffs.length; j++) {
            y += trendLine.coeffs[j] * Math.pow(x, j);
          }
          trendLineData.push({ x, y });
        }

        return {
          label: `${trendLine.degree === 1 ? 'Linear' : 'Quadratic'} Trend (R² = ${trendLine.rSquared.toFixed(3)})`,
          data: trendLineData,
          type: 'line',
          borderColor: trendLine.color,
          backgroundColor: trendLine.color.replace('1)', '0.1)'),
          borderWidth: 2,
          pointRadius: 2,
          pointHoverRadius: 2,
          pointBackgroundColor: 'transparent',
          pointBorderColor: 'transparent',
          pointHoverBackgroundColor: trendLine.color,
          pointHoverBorderColor: trendLine.color,
          fill: false,
          tension: 0,
        };
      });

      const ctx = canvasRef.current.getContext('2d');

      // Destroy existing chart if it exists
      if (chartRef.current) {
        chartRef.current.destroy();
      }

      chartRef.current = new window.Chart(ctx, {
        type: 'scatter',
        data: {
          datasets: [
            {
              label: `${objectKind} Added`,
              data: data,
              backgroundColor: 'rgba(59, 130, 246, 0.6)',
              borderColor: 'rgba(59, 130, 246, 1)',
              borderWidth: 1,
              pointRadius: 5,
              pointHoverRadius: 7,
            },
            ...trendLineDatasets,
          ],
        },
        options: {
          responsive: true,
          maintainAspectRatio: false,
          animation: {
            duration: 0, // Disable animations to prevent jitter
          },
          scales: {
            x: {
              title: {
                display: true,
                text: `${objectKind} Added`,
              },
              min: 0,
            },
            y: {
              title: {
                display: true,
                text: 'Days Since Last Scan',
              },
              min: 0,
            },
          },
          plugins: {
            tooltip: {
              intersect: false,
              mode: 'nearest',
              callbacks: {
                title: function (context: any) {
                  const dataPoint = context[0];
                  if (dataPoint.dataset.label?.includes('Trend')) {
                    return `Predict ${context[0].parsed.x.toFixed(0)} ${objectKind.toLowerCase()} added`;
                  }
                  return data[dataPoint.dataIndex]?.scanDate || '';
                },
                label: function (context: any) {
                  if (context.dataset.label?.includes('Trend')) {
                    return `${context.parsed.y.toFixed(1)} days`;
                  }
                  return `${context.parsed.x} ${objectKind.toLowerCase()} added`;
                },
                afterLabel: function (context: any) {
                  if (!context.dataset.label?.includes('Trend')) {
                    const dataPoint = data[context.dataIndex];
                    return `Time gap: ${dataPoint?.durationFormatted || 'N/A'}`;
                  }
                  return '';
                },
              },
            },
            legend: {
              display: true,
              position: 'top' as const,
            },
          },
        },
      });

      setIsInitialized(true);
    }, 100); // 100ms delay

    return () => {
      clearTimeout(initTimer);
      if (chartRef.current) {
        chartRef.current.destroy();
      }
    };
  }, [data, objectKind]);

  return (
    <section className="rounded-md border border-slate-300 bg-white p-2">
      <div className="h-96 w-full">
        <canvas ref={canvasRef} />
      </div>
      {statistics && (
        <div className="mt-2 space-y-2 text-center text-sm text-slate-600">
          <div className="flex justify-center gap-6">
            <div>
              <span className="font-medium">{objectKind} per day: </span>
              <span className="font-mono">
                {statistics.favsPerDay > 0
                  ? statistics.favsPerDay.toFixed(2)
                  : 'N/A'}
              </span>
            </div>
          </div>
          {statistics.trendLines.length > 0 ? (
            <div className="space-y-1">
              {statistics.trendLines.map((trendLine, index) => (
                <div key={index} className="flex justify-center gap-4 text-xs">
                  <div>
                    <span
                      className="font-medium"
                      style={{ color: trendLine.color }}
                    >
                      {trendLine.degree === 1 ? 'Linear' : 'Quadratic'} R²:
                    </span>
                    <span className="ml-1 font-mono">
                      {trendLine.rSquared.toFixed(3)}
                    </span>
                  </div>
                  <PolynomialEquation
                    coefficients={trendLine.coeffs}
                    className="font-mono text-slate-500"
                  />
                </div>
              ))}
            </div>
          ) : (
            <div className="text-xs text-slate-500">
              Need at least 2 data points for trend analysis
            </div>
          )}
        </div>
      )}
    </section>
  );
};
