import { useEffect } from "react";
import { useSocketStore } from "../../../store/store";
import { useSelectedZoneStore } from "../../../store/visualization/useZoneStore";
import { useDroppedObjectsStore } from "../../../store/visualization/useDroppedObjectsStore";
import { useZoneWidgetStore } from "../../../store/visualization/useZone3DWidgetStore";
import useTemplateStore from "../../../store/useTemplateStore";

type WidgetData = {
  id: string;
  type: string;
  position: [number, number, number];
  rotation?: [number, number, number];
  tempPosition?: [number, number, number];
};

export default function SocketRealTimeViz() {
  const { visualizationSocket } = useSocketStore();
  const { setSelectedZone } = useSelectedZoneStore();
  const deleteObject = useDroppedObjectsStore((state) => state.deleteObject);
  const updateObjectPosition = useDroppedObjectsStore(
    (state) => state.updateObjectPosition
  );
  const { addWidget } = useZoneWidgetStore();
  const { removeTemplate } = useTemplateStore();
  const { setTemplates } = useTemplateStore();
  const {
    zoneWidgetData,
    setZoneWidgetData,
    updateWidgetPosition,
    updateWidgetRotation,
  } = useZoneWidgetStore();

  useEffect(() => {
    if (visualizationSocket) {
      //add panel response
      visualizationSocket.on("viz-panel:response:updates", (addPanel: any) => {
        if (addPanel.success) {
          let addPanelData = addPanel.data.data;
          setSelectedZone(addPanelData);
        }
      });
      //delete panel response
      visualizationSocket.on(
        "viz-panel:response:delete",
        (deletePanel: any) => {
          if (deletePanel.success) {
            let deletePanelData = deletePanel.data.data;
            setSelectedZone(deletePanelData);
          }
        }
      );
      //clear Panel response
      visualizationSocket.on("viz-panel:response:clear", (clearPanel: any) => {
        if (
          clearPanel.success &&
          clearPanel.message === "PanelWidgets cleared successfully"
        ) {
          let clearPanelData = clearPanel.data.data;
          setSelectedZone(clearPanelData);
        }
      });
      //lock Panel response
      visualizationSocket.on("viz-panel:response:locked", (lockPanel: any) => {
        if (
          lockPanel.success &&
          lockPanel.message === "locked panel updated successfully"
        ) {
          let lockPanelData = lockPanel.data.data;
          setSelectedZone(lockPanelData);
        }
      });
      // add 2dWidget response
      visualizationSocket.on(
        "viz-widget:response:updates",
        (add2dWidget: any) => {
          if (add2dWidget.success && add2dWidget.data) {
            setSelectedZone((prev) => {
              const isWidgetAlreadyAdded = prev.widgets.some(
                (widget) => widget.id === add2dWidget.data.widgetData.id
              );
              if (isWidgetAlreadyAdded) return prev; // Prevent duplicate addition
              return {
                ...prev,
                zoneId: add2dWidget.data.zoneId,
                zoneName: add2dWidget.data.zoneName,
                widgets: [...prev.widgets, add2dWidget.data.widgetData], // Append new widget
              };
            });
          }
        }
      );
      //delete 2D Widget response
      visualizationSocket.on(
        "viz-widget:response:delete",
        (deleteWidget: any) => {
          if (deleteWidget?.success && deleteWidget.data) {
            setSelectedZone((prevZone: any) => ({
              ...prevZone,
              zoneId: deleteWidget.data.zoneId,
              zoneName: deleteWidget.data.zoneName,
              widgets: deleteWidget.data.widgetDeleteDatas, // Replace with new widget list
            }));
          }
        }
      );
      //add Floating Widget response
      visualizationSocket.on(
        "viz-float:response:updates",
        (addFloatingWidget: any) => {
          if (addFloatingWidget.success) {
            if (
              addFloatingWidget.success &&
              addFloatingWidget.message === "FloatWidget created successfully"
            ) {
              const state = useDroppedObjectsStore.getState();
              const zone = state.zones[addFloatingWidget.data.zoneName];
              if (!zone) {
                state.setZone(
                  addFloatingWidget.data.zoneName,
                  addFloatingWidget.data.zoneId
                );
              }
              const existingObjects = zone ? zone.objects : [];
              const newWidget = addFloatingWidget.data.widget;
              // ✅ Check if the widget ID already exists before adding
              const isAlreadyAdded = existingObjects.some(
                (obj) => obj.id === newWidget.id
              );
              if (isAlreadyAdded) {
                return; // Don't add the widget if it already exists
              }
              // Add widget only if it doesn't exist
              state.addObject(addFloatingWidget.data.zoneName, newWidget);
            }
            if (addFloatingWidget.message === "Widget updated successfully") {
              updateObjectPosition(
                addFloatingWidget.data.zoneName,
                addFloatingWidget.data.index,
                addFloatingWidget.data.position
              );
            }
          }
        }
      );
      //duplicate Floating Widget response
      visualizationSocket.on(
        "viz-float:response:addDuplicate",
        (duplicateFloatingWidget: any) => {
          if (
            duplicateFloatingWidget.success &&
            duplicateFloatingWidget.message ===
              "duplicate FloatWidget created successfully"
          ) {
            useDroppedObjectsStore.setState((state) => {
              const zone = state.zones[duplicateFloatingWidget.data.zoneName];
              if (!zone) return state; // Zone doesn't exist, return state as is
              const existingObjects = zone.objects;
              const newWidget = duplicateFloatingWidget.data.widget;
              // ✅ Check if the object with the same ID already exists
              const isAlreadyAdded = existingObjects.some(
                (obj) => obj.id === newWidget.id
              );
              if (isAlreadyAdded) {
                return state; // Don't update state if it's already there
              }
              return {
                zones: {
                  ...state.zones,
                  [duplicateFloatingWidget.data.zoneName]: {
                    ...zone,
                    objects: [...existingObjects, newWidget], // Append only if it's not a duplicate
                  },
                },
              };
            });
          }
        }
      );
      //delete Floating Widget response
      visualizationSocket.on(
        "viz-float:response:delete",
        (deleteFloatingWidget: any) => {
          if (deleteFloatingWidget.success) {
            deleteObject(
              deleteFloatingWidget.data.zoneName,
              deleteFloatingWidget.data.floatWidgetID
            );
          }
        }
      );
      //add 3D Widget response
      visualizationSocket.on(
        "viz-widget3D:response:updates",
        (add3DWidget: any) => {
          if (add3DWidget.success) {
            if (add3DWidget.message === "Widget created successfully") {
              addWidget(add3DWidget.data.zoneId, add3DWidget.data.widget);
            }
          }
        }
      );
      //delete 3D Widget response
      visualizationSocket.on(
        "viz-widget3D:response:delete",
        (delete3DWidget: any) => {
          // "3DWidget delete unsuccessfull"
          if (
            delete3DWidget.success &&
            delete3DWidget.message === "3DWidget delete successfull"
          ) {
            const activeZoneWidgets =
              zoneWidgetData[delete3DWidget.data.zoneId] || [];
            setZoneWidgetData(
              delete3DWidget.data.zoneId,
              activeZoneWidgets.filter(
                (w: WidgetData) => w.id !== delete3DWidget.data.id
              )
            );
          }
        }
      );
      //update3D widget response
      visualizationSocket.on(
        "viz-widget3D:response:modifyPositionRotation",
        (update3DWidget: any) => {
          if (
            update3DWidget.success &&
            update3DWidget.message === "widget update successfully"
          ) {
            updateWidgetPosition(
              update3DWidget.data.zoneId,
              update3DWidget.data.widget.id,
              update3DWidget.data.widget.position
            );
            updateWidgetRotation(
              update3DWidget.data.zoneId,
              update3DWidget.data.widget.id,
              update3DWidget.data.widget.rotation
            );
          }
        }
      );
      // add Template response
      visualizationSocket.on(
        "viz-template:response:add",
        (addingTemplate: any) => {
          if (addingTemplate.success) {
            if (addingTemplate.message === "Template saved successfully") {
              setTemplates(addingTemplate.data);
            }
          }
        }
      );
      //load Template response
      visualizationSocket.on(
        "viz-template:response:addTemplateZone",
        (loadTemplate: any) => {
          if (loadTemplate.success) {
            if (loadTemplate.message === "Template placed in Zone") {
              let template = loadTemplate.data.template;
              setSelectedZone({
                panelOrder: template.panelOrder,
                activeSides: Array.from(new Set(template.panelOrder)), // No merging with previous `activeSides`
                widgets: template.widgets,
              });
              useDroppedObjectsStore
                .getState()
                .setZone(template.zoneName, template.zoneId);

              if (Array.isArray(template.floatingWidget)) {
                template.floatingWidget.forEach((val: any) => {
                  useDroppedObjectsStore
                    .getState()
                    .addObject(template.zoneName, val);
                });
              }
            }
          }
        }
      );
      //delete Template response
      visualizationSocket.on(
        "viz-template:response:delete",
        (deleteTemplate: any) => {
          if (deleteTemplate.success) {
            if (deleteTemplate.message === "Template deleted successfully") {
              removeTemplate(deleteTemplate.data);
            }
          }
        }
      );
    }
  }, [visualizationSocket]);

  return <></>;
}
