"use client";

import React, { useEffect, useRef } from "react";
import { useSelector } from "react-redux";
import { RootState } from "../../../../../../redux/store";
import {
  Chart as ChartJS,
  LineElement,
  PointElement,
  LinearScale,
  TimeScale,
  Title,
  Tooltip,
  Legend,
  Filler,
} from "chart.js";

import "chartjs-adapter-date-fns";
import { de } from "date-fns/locale";
import { differenceInHours, parseISO } from "date-fns";

ChartJS.register(
  LineElement,
  PointElement,
  LinearScale,
  TimeScale,
  Title,
  Tooltip,
  Legend,
  Filler
);
import { getColor } from "../../../../../../utils/colors";
import { PulseLoader } from "react-spinners";

const usePreviousData = (data: any[]) => {
  const ref = useRef<any[]>([]);
  useEffect(() => {
    ref.current = data;
  }, [data]);
  return ref.current;
};

const LoopMeasurementChart = () => {
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
  const chartInstance = useRef<ChartJS | null>(null);

  const {
    loopMeasurementCurveChartData,
    selectedMode,
    unit,
    isFullScreen,
    isLoading,
    vonDatum,
    bisDatum,
  } = useSelector((state: RootState) => state.kabelueberwachungChartSlice);

  const previousData = usePreviousData(loopMeasurementCurveChartData);

  // Vergleichsfunktion
  const isEqual = (a: any[], b: any[]): boolean => {
    if (a.length !== b.length) return false;
    for (let i = 0; i < a.length; i++) {
      if (
        a[i].t !== b[i].t ||
        a[i].i !== b[i].i ||
        a[i].m !== b[i].m ||
        a[i].g !== b[i].g ||
        a[i].a !== b[i].a
      ) {
        return false;
      }
    }
    return true;
  };

  // ⏱ Zeitspanne in Stunden berechnen
  const from = vonDatum ? parseISO(vonDatum) : null;
  const to = bisDatum ? parseISO(bisDatum) : null;
  const durationInHours = from && to ? differenceInHours(to, from) : 9999;
  const timeUnit: "hour" | "day" = durationInHours <= 48 ? "hour" : "day";

  useEffect(() => {
    import("chartjs-plugin-zoom").then((zoomPlugin) => {
      if (!ChartJS.registry.plugins.get("zoom")) {
        ChartJS.register(zoomPlugin.default);
      }

      if (!canvasRef.current) return;
      const ctx = canvasRef.current.getContext("2d");
      if (!ctx) return;

      if (isEqual(loopMeasurementCurveChartData, previousData)) {
        return; // keine echte Datenänderung → nicht neu zeichnen
      }

      if (chartInstance.current) {
        chartInstance.current.destroy();
      }

      const chartData = {
        labels: loopMeasurementCurveChartData
          .map((entry) => new Date(entry.t))
          .reverse(),
        datasets: [
          {
            label: "Messwert Minimum",
            data: loopMeasurementCurveChartData.map((e) => e.i).reverse(),
            borderColor: "lightgrey",
            backgroundColor: "rgba(211,211,211,0.5)",
            borderWidth: 2,
            pointRadius: 0,
            pointHoverRadius: 10,
            tension: 0.1,
            order: 1,
          },
          {
            label: "Messwert Maximum",
            data: loopMeasurementCurveChartData.map((e) => e.a).reverse(),
            borderColor: "lightgrey",
            backgroundColor: "rgba(211,211,211,0.5)",
            borderWidth: 2,
            pointRadius: 0,
            pointHoverRadius: 10,
            tension: 0.1,
            order: 1,
          },
          selectedMode === "DIA0"
            ? {
                label: "Messwert",
                data: loopMeasurementCurveChartData.map((e) => e.m).reverse(),
                borderColor: getColor("littwin-blue"),
                backgroundColor: "rgba(59,130,246,0.5)",
                borderWidth: 3,
                pointRadius: 0,
                pointHoverRadius: 10,
                tension: 0.1,
                order: 3,
              }
            : {
                label: "Messwert Durchschnitt",
                data: loopMeasurementCurveChartData.map((e) => e.g).reverse(),
                borderColor: getColor("littwin-blue"),
                backgroundColor: "rgba(59,130,246,0.5)",
                borderWidth: 3,
                pointRadius: 0,
                pointHoverRadius: 10,
                tension: 0.1,
                order: 3,
              },
        ],
      };

      const options = {
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          legend: { position: "top" as const },
          tooltip: {
            yAlign: "bottom" as const,
            mode: "index" as const,
            intersect: false,
          },
          zoom: {
            pan: { enabled: true, mode: "x" as const },
            zoom: {
              wheel: { enabled: true },
              pinch: { enabled: true },
              mode: "x" as const,
            },
          },
        },
        scales: {
          x: {
            type: "time" as const,
            time: {
              unit: timeUnit,
              tooltipFormat: "dd.MM.yyyy HH:mm:ss",
              displayFormats: {
                hour: "HH:mm",
                day: "dd.MM.",
              },
              locale: de,
            },
            title: { display: true, text: "Zeit" },
          },
          y: {
            title: { display: true, text: unit },
            ticks: { precision: 0 },
          },
        },
      };

      chartInstance.current = new ChartJS(ctx, {
        type: "line",
        data: chartData,
        options,
      });
    });
  }, [loopMeasurementCurveChartData, selectedMode, vonDatum, bisDatum]);

  return (
    <div style={{ width: "100%", height: isFullScreen ? "90%" : "400px" }}>
      {isLoading && (
        <div className="flex items-center justify-center h-96">
          <PulseLoader color="#3B82F6" />
        </div>
      )}
      <canvas
        ref={canvasRef}
        style={{
          width: "100%",
          height: "100%",
          display: isLoading ? "none" : "block",
        }}
      />
    </div>
  );
};

export default LoopMeasurementChart;
