import React, { useEffect, useState, useRef } from "react";
import { usePlayButtonStore } from "../../store/usePlayButtonStore";
import Panel from "./widgets/panel/Panel";
import AddButtons from "./widgets/panel/AddButtons";
import { useSelectedZoneStore } from "../../store/visualization/useZoneStore";
import DisplayZone from "./zone/DisplayZone";
import Scene from "../scene/scene";
import useModuleStore from "../../store/useModuleStore";

import {
  useDroppedObjectsStore,
  useFloatingWidget,
} from "../../store/visualization/useDroppedObjectsStore";
import {
  useAsset3dWidget,
  useSocketStore,
  useWidgetSubOption,
  useZones,
} from "../../store/store";
import { getZone2dData } from "../../services/visulization/zone/getZoneData";
import { generateUniqueId } from "../../functions/generateUniqueId";
import { determinePosition } from "./functions/determinePosition";
import { addingFloatingWidgets } from "../../services/visulization/zone/addFloatingWidgets";
import SocketRealTimeViz from "./socket/realTimeVizSocket.dev";
import RenderOverlay from "../../components/templates/Overlay";
import ConfirmationPopup from "../../components/layout/confirmationPopup/ConfirmationPopup";
import DroppedObjects from "./widgets/floating/DroppedFloatingWidgets";
import EditWidgetOption from "../../components/ui/menu/EditWidgetOption";
import {
  useEditWidgetOptionsStore,
  useRightClickSelected,
  useRightSelected,
} from "../../store/visualization/useZone3DWidgetStore";
import OuterClick from "../../utils/outerClick";
import { useWidgetStore } from "../../store/useWidgetStore";
import { getActiveProperties } from "./functions/getActiveProperties";

type Side = "top" | "bottom" | "left" | "right";

type FormattedZoneData = Record<
  string,
  {
    activeSides: Side[];
    panelOrder: Side[];
    points: [];
    lockedPanels: Side[];
    zoneId: string;
    zoneViewPortTarget: number[];
    zoneViewPortPosition: number[];
    widgets: Widget[];
  }
>;
type Widget = {
  id: string;
  type: string;
  title: string;
  panel: Side;
  data: any;
};

// Define the type for HiddenPanels, where keys are zone IDs and values are arrays of hidden sides
interface HiddenPanels {
  [zoneId: string]: Side[];
}

const RealTimeVisulization: React.FC = () => {
  const [hiddenPanels, setHiddenPanels] = React.useState<HiddenPanels>({});
  const containerRef = useRef<HTMLDivElement>(null);
  const { isPlaying } = usePlayButtonStore();
  const { activeModule } = useModuleStore();
  const [droppedObjects, setDroppedObjects] = useState<any[]>([]);
  const [zonesData, setZonesData] = useState<FormattedZoneData>({});
  const { selectedZone, setSelectedZone } = useSelectedZoneStore();

  const { rightSelect, setRightSelect } = useRightSelected();
  const { editWidgetOptions, setEditWidgetOptions } =
    useEditWidgetOptionsStore();
  const { rightClickSelected, setRightClickSelected } = useRightClickSelected();
  const [openConfirmationPopup, setOpenConfirmationPopup] = useState(false);

  // const [floatingWidgets, setFloatingWidgets] = useState<Record<string, { zoneName: string; zoneId: string; objects: any[] }>>({});
  const { floatingWidget, setFloatingWidget } = useFloatingWidget();
  const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
  const { widgetSubOption, setWidgetSubOption } = useWidgetSubOption();
  const { visualizationSocket } = useSocketStore();
  const { setSelectedChartId } = useWidgetStore();

  OuterClick({
    contextClassName: [
      "chart-container",
      "floating",
      "sidebar-right-wrapper",
      "card",
      "dropdown-menu",
      "dropdown-options",
    ],
    setMenuVisible: () => setSelectedChartId(null),
  });

  useEffect(() => {
    async function GetZoneData() {
      const email = localStorage.getItem("email") || "";
      const organization = email?.split("@")[1]?.split(".")[0];
      try {
        const response = await getZone2dData(organization);
        // console.log('response: ', response);

        if (!Array.isArray(response)) {
          return;
        }
        const formattedData = response.reduce<FormattedZoneData>(
          (acc, zone) => {
            acc[zone.zoneName] = {
              activeSides: [],
              panelOrder: [],
              lockedPanels: [],
              points: zone.points,
              zoneId: zone.zoneId,
              zoneViewPortTarget: zone.viewPortCenter,
              zoneViewPortPosition: zone.viewPortposition,
              widgets: [],
            };
            return acc;
          },
          {}
        );
        setZonesData(formattedData);
      } catch (error) { }
    }

    GetZoneData();
  }, [activeModule]); // Removed `zones` from dependencies

  useEffect(() => {
    setZonesData((prev) => {
      if (!selectedZone) return prev;
      return {
        ...prev,
        [selectedZone.zoneName]: {
          ...prev[selectedZone.zoneName], // Keep existing properties
          activeSides: selectedZone.activeSides || [],
          panelOrder: selectedZone.panelOrder || [],
          lockedPanels: selectedZone.lockedPanels || [],
          points: selectedZone.points || [],
          zoneId: selectedZone.zoneId || "",
          zoneViewPortTarget: selectedZone.zoneViewPortTarget || [],
          zoneViewPortPosition: selectedZone.zoneViewPortPosition || [],
          widgets: selectedZone.widgets || [],
        },
      };
    });
  }, [selectedZone]);

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

  const handleDrop = async (event: React.DragEvent<HTMLDivElement>) => {
    event.preventDefault();
    try {
      const email = localStorage.getItem("email") || "";
      const organization = email?.split("@")[1]?.split(".")[0];

      const data = event.dataTransfer.getData("text/plain");
      if (widgetSubOption === "3D") return;
      if (!data || selectedZone.zoneName === "") return;

      const droppedData = JSON.parse(data);
      const canvasElement = document.getElementById("real-time-vis-canvas");
      if (!canvasElement) throw new Error("Canvas element not found");

      const rect = canvasElement.getBoundingClientRect();
      const relativeX = event.clientX - rect.left;
      const relativeY = event.clientY - rect.top;

      // Widget dimensions
      const widgetWidth = droppedData.width || 125;
      const widgetHeight = droppedData.height || 100;

      // Center the widget at cursor
      const centerOffsetX = widgetWidth / 2;
      const centerOffsetY = widgetHeight / 2;

      const adjustedX = relativeX - centerOffsetX;
      const adjustedY = relativeY - centerOffsetY;

      const finalPosition = determinePosition(rect, adjustedX, adjustedY);
      const [activeProp1, activeProp2] = getActiveProperties(finalPosition);

      let finalY = 0;
      let finalX = 0;

      if (activeProp1 === "top") {
        finalY = adjustedY;
      } else {
        finalY = rect.height - (adjustedY + widgetHeight);
      }

      if (activeProp2 === "left") {
        finalX = adjustedX;
      } else {
        finalX = rect.width - (adjustedX + widgetWidth);
      }

      // Clamp to boundaries
      finalX = Math.max(0, Math.min(rect.width - widgetWidth, finalX));
      finalY = Math.max(0, Math.min(rect.height - widgetHeight, finalY));

      const boundedPosition = {
        ...finalPosition,
        [activeProp1]: finalY,
        [activeProp2]: finalX,
        [activeProp1 === "top" ? "bottom" : "top"]: "auto",
        [activeProp2 === "left" ? "right" : "left"]: "auto",
      };

      const newObject = {
        ...droppedData,
        id: generateUniqueId(),
        position: boundedPosition,
      };

      const existingZone =
        useDroppedObjectsStore.getState().zones[selectedZone.zoneName];
      if (!existingZone) {
        useDroppedObjectsStore
          .getState()
          .setZone(selectedZone.zoneName, selectedZone.zoneId);
      }

      const addFloatingWidget = {
        organization,
        widget: newObject,
        zoneId: selectedZone.zoneId,
      };

      if (visualizationSocket) {
        visualizationSocket.emit("v2:viz-float:add", addFloatingWidget);
      }

      useDroppedObjectsStore
        .getState()
        .addObject(selectedZone.zoneName, newObject);

      const droppedObjectsStore = useDroppedObjectsStore.getState();
      const currentZone = droppedObjectsStore.zones[selectedZone.zoneName];

      if (currentZone && currentZone.zoneId === selectedZone.zoneId) {
        console.log(
          `Objects for Zone ${selectedZone.zoneId}:`,
          currentZone.objects
        );
        setFloatingWidget(currentZone.objects);
      } else {
        console.warn("Zone not found or zoneId mismatch");
      }
    } catch (error) {
      console.error("Error in handleDrop:", error);
    }
  };

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      const editWidgetOptions = document.querySelector(
        ".editWidgetOptions-wrapper"
      );
      if (
        editWidgetOptions &&
        !editWidgetOptions.contains(event.target as Node)
      ) {
        setRightClickSelected(null);
        setRightSelect(null);
      }
    };

    document.addEventListener("mousedown", handleClickOutside);
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [setRightClickSelected]);

  const [canvasDimensions, setCanvasDimensions] = useState({
    width: 0,
    height: 0,
  });
  useEffect(() => {
    const canvas = document.getElementById("real-time-vis-canvas");
    if (!canvas) return;

    const updateCanvasDimensions = () => {
      const rect = canvas.getBoundingClientRect();
      setCanvasDimensions({
        width: rect.width,
        height: rect.height,
      });
    };

    updateCanvasDimensions();
    const resizeObserver = new ResizeObserver(updateCanvasDimensions);
    resizeObserver.observe(canvas);

    return () => resizeObserver.unobserve(canvas);
  }, []);

  return (
    <>
      <style>
        {`
    :root {
      --realTimeViz-container-width: ${canvasDimensions.width}px;

      --realTimeViz-container-height: ${canvasDimensions.height}px;
      
    }
  `}
      </style>
      <div
        ref={containerRef}
        id="real-time-vis-canvas"
        className={`realTime-viz canvas ${isPlaying ? "playingFlase" : ""}`}
        style={{
          height: isPlaying || activeModule !== "visualization" ? "100vh" : "",
          width: isPlaying || activeModule !== "visualization" ? "100vw" : "",
          left: isPlaying || activeModule !== "visualization" ? "0%" : "",
        }}
      >
        <div className="realTime-viz-wrapper">
          {openConfirmationPopup && (
            <RenderOverlay>
              <ConfirmationPopup
                message={"Are you sure want to delete?"}
                onConfirm={() => console.log("Confirmed")}
                onCancel={() => setOpenConfirmationPopup(false)}
              />
            </RenderOverlay>
          )}
          <div
            className="scene-container"
            style={{
              height: "100%",
              width: "100%",
              borderRadius:
                isPlaying || activeModule !== "visualization" ? "" : "6px",
            }}
            onDrop={(event) => handleDrop(event)}
            onDragOver={(event) => event.preventDefault()}
          >
            <Scene />
          </div>
          {activeModule === "visualization" && selectedZone.zoneName !== "" && (
            <DroppedObjects />
          )}
          {activeModule === "visualization" && <SocketRealTimeViz />}

          {activeModule === "visualization" &&
            editWidgetOptions &&
            rightClickSelected && (
              <EditWidgetOption
                options={[
                  "Duplicate",
                  "Vertical Move",
                  "Horizontal Move",
                  "RotateX",
                  "RotateY",
                  "Delete",
                ]}
                onClick={(e) => {
                  setRightSelect(e);
                  setEditWidgetOptions(false);
                }}
              />
            )}

          {activeModule === "visualization" && (
            <>
              <DisplayZone
                zonesData={zonesData}
                selectedZone={selectedZone}
                setSelectedZone={setSelectedZone}
                hiddenPanels={hiddenPanels}
                setHiddenPanels={setHiddenPanels}
              />

              {!isPlaying && selectedZone?.zoneName !== "" && (
                <AddButtons
                  hiddenPanels={hiddenPanels}
                  setHiddenPanels={setHiddenPanels}
                  selectedZone={selectedZone}
                  setSelectedZone={setSelectedZone}
                />
              )}

              <Panel
                selectedZone={selectedZone}
                setSelectedZone={setSelectedZone}
                hiddenPanels={hiddenPanels}
                setZonesData={setZonesData}
              />
            </>
          )}
        </div>
      </div>
    </>
  );
};

export default RealTimeVisulization;
