import React, { useEffect, useMemo, useState } from "react";
import { Line } from "react-chartjs-2";
import io from "socket.io-client";

import axios from "axios";
import { useThemeStore } from "../../../../../store/useThemeStore";
import useChartStore from "../../../../../store/visualization/useChartStore";
import { useWidgetStore } from "../../../../../store/useWidgetStore";

interface ChartComponentProps {
  id: string;
  type: any;
  title: string;
  fontFamily?: string;
  fontSize?: string;
  fontWeight?: "Light" | "Regular" | "Bold";
}

const LineGraphComponent = ({
  id,
  type,
  title,
  fontFamily,
  fontSize,
  fontWeight = "Regular",
}: ChartComponentProps) => {
  const { themeColor } = useThemeStore();
  const {
    measurements: chartMeasurements,
    duration: chartDuration,
    name: widgetName,
  } = useChartStore();
  const [measurements, setmeasurements] = useState<any>({});
  const [duration, setDuration] = useState("1h");
  const [name, setName] = useState("Widget");
  const [chartData, setChartData] = useState<{
    labels: string[];
    datasets: any[];
  }>({
    labels: [],
    datasets: [],
  });
  const { selectedChartId } = useWidgetStore();

  const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
  const email = localStorage.getItem("email") || "";
  const organization = email?.split("@")[1]?.split(".")[0];
  const defaultData = {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [
      {
        label: "Dataset",
        data: [12, 19, 3, 5, 2, 3],
        backgroundColor: ["#6f42c1"],
        borderColor: "#b392f0",
        borderWidth: 1,
      },
    ],
  };

  useEffect(() => {}, []);

  // Memoize Theme Colors
  const buttonActionColor = useMemo(
    () => themeColor[0] || "#5c87df",
    [themeColor]
  );
  const buttonAbortColor = useMemo(
    () => themeColor[1] || "#ffffff",
    [themeColor]
  );

  // Memoize Font Styling
  const chartFontWeightMap = useMemo(
    () => ({
      Light: "lighter" as const,
      Regular: "normal" as const,
      Bold: "bold" as const,
    }),
    []
  );

  const fontSizeValue = useMemo(
    () => (fontSize ? parseInt(fontSize) : 12),
    [fontSize]
  );
  const fontWeightValue = useMemo(
    () => chartFontWeightMap[fontWeight],
    [fontWeight, chartFontWeightMap]
  );

  const chartFontStyle = useMemo(
    () => ({
      family: fontFamily || "Arial",
      size: fontSizeValue,
      weight: fontWeightValue,
    }),
    [fontFamily, fontSizeValue, fontWeightValue]
  );

  // Memoize Chart Options
  const options = useMemo(
    () => ({
      responsive: true,
      maintainAspectRatio: false,
      plugins: {
        title: {
          display: true,
          text: name,
          font: chartFontStyle,
        },
        legend: {
          display: false,
        },
      },
      scales: {
        x: {
          ticks: {
            display: true, // This hides the x-axis labels
          },
        },
      },
    }),
    [title, chartFontStyle, name]
  );

  // useEffect(() => {console.log(measurements);
  // },[measurements])

  useEffect(() => {
    if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0)
      return;

    const socket = io(`http://${iotApiUrl}`);

    const inputData = {
      measurements,
      duration,
      interval: 1000,
    };

    const startStream = () => {
      socket.emit("lineInput", inputData);
    };

    socket.on("connect", startStream);

    socket.on("lineOutput", (response) => {
      const responseData = response.data;

      // Extract timestamps and values
      const labels = responseData.time;
      const datasets = Object.keys(measurements).map((key) => {
        const measurement = measurements[key];
        const datasetKey = `${measurement.name}.${measurement.fields}`;
        return {
          label: datasetKey,
          data: responseData[datasetKey]?.values ?? [],
          backgroundColor: "#6f42c1",
          borderColor: "#b392f0",
          borderWidth: 1,
        };
      });

      setChartData({ labels, datasets });
    });

    return () => {
      socket.off("lineOutput");
      socket.emit("stop_stream"); // Stop streaming when component unmounts
      socket.disconnect();
    };
  }, [measurements, duration, iotApiUrl]);

  const fetchSavedInputes = async () => {
    if (id !== "") {
      try {
        const response = await axios.get(
          `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${id}/${organization}`
        );
        if (response.status === 200) {
          setmeasurements(response.data.Data.measurements);
          setDuration(response.data.Data.duration);
          setName(response.data.widgetName);
        } else {
          console.log("Unexpected response:", response);
        }
      } catch (error) {
        console.error("There was an error!", error);
      }
    }
  };

  useEffect(() => {
    fetchSavedInputes();
  }, []);

  useEffect(() => {
    if (selectedChartId?.id === id) {
      fetchSavedInputes();
    }
  }, [chartMeasurements, chartDuration, widgetName]);

  return (
    <Line
      data={Object.keys(measurements).length > 0 ? chartData : defaultData}
      options={options}
    />
  );
};

export default LineGraphComponent;
