import { create } from "zustand";
import { useSocketStore } from "../builder/store";
import useChartStore from "./useChartStore";
import { getUserData } from "../../functions/getUserData";

type DroppedObject = {
  className: string;
  id: string;
  position: {
    top: number | "auto";
    left: number | "auto";
    right: number | "auto";
    bottom: number | "auto";
  };
  value?: number;
  per?: string;
  header?: string;
  Data: {};
};

type Zone = {
  zoneName: string;
  zoneUuid: string;
  objects: DroppedObject[];
};

type DroppedObjectsState = {
  zones: Record<string, Zone>;
  setZone: (zoneName: string, zoneUuid: string) => void;
  addObject: (zoneName: string, newObject: DroppedObject) => void;
  updateObjectPosition: (
    zoneName: string,
    index: number,
    newPosition: {
      top: number | "auto";
      left: number | "auto";
      right: number | "auto";
      bottom: number | "auto";
    }
  ) => void;
  deleteObject: (zoneName: string, id: string) => void; // Add this line
  duplicateObject: (
    zoneName: string,
    index: number,
    projectId?: string,
    versionId?: string
  ) => void; // Add this line
};

export const useDroppedObjectsStore = create<DroppedObjectsState>((set) => ({
  zones: {},

  setZone: (zoneName: string, zoneUuid: string) =>
    set((state) => ({
      zones: {
        [zoneName]: state.zones[zoneName] || {
          zoneName,
          zoneUuid,
          objects: [],
        }, // Keep existing zone if it exists
      },
    })),

  addObject: (zoneName: string, newObject: DroppedObject) =>
    set((state) => ({
      zones: {
        ...state.zones,
        [zoneName]: {
          ...state.zones[zoneName],
          objects: [...state.zones[zoneName].objects, newObject], // Append new object
        },
      },
    })),

  updateObjectPosition: (zoneName, index, newPosition) =>
    set((state) => {
      const zone = state.zones[zoneName];
      if (!zone) return state;
      return {
        zones: {
          [zoneName]: {
            ...zone,
            objects: zone.objects.map((obj, i) =>
              i === index ? { ...obj, position: newPosition } : obj
            ),
          },
        },
      };
    }),

  deleteObject: (zoneName: string, id: string) =>
    set((state) => {
      const zone = state.zones[zoneName];

      if (!zone) return state;
      return {
        zones: {
          [zoneName]: {
            ...zone,
            objects: zone.objects.filter((obj) => obj.id !== id), // Remove object at the given index
          },
        },
      };
    }),

  duplicateObject: async (
    zoneName: string,
    index: number,
    projectId?: string,
    versionId?: string
  ) => {
    const state = useDroppedObjectsStore.getState(); // Get the current state
    const zone = state.zones[zoneName];
    let socketState = useSocketStore.getState();
    let iotData = useChartStore.getState();
    let visualizationSocket = socketState.visualizationSocket;
    let iotMeasurements = iotData.flotingMeasurements;
    let iotDuration = iotData.flotingDuration;
    let iotHeader = iotData.header;

    if (!zone) return;

    const originalObject = zone.objects[index];
    if (!originalObject) return;
    const { userId, organization, email } = getUserData();

    // Create a shallow copy of the object with a unique ID and slightly adjusted position
    const duplicatedObject: DroppedObject = {
      ...originalObject,
      Data: {
        measurements: iotMeasurements,
        duration: iotDuration,
      },
      header: iotHeader,
      id: `${originalObject.id}-copy-${Date.now()}`, // Unique ID
      position: {
        ...originalObject.position,
        top:
          typeof originalObject.position.top === "number"
            ? originalObject.position.top + 20 // Offset vertically
            : originalObject.position.top,
        left:
          typeof originalObject.position.left === "number"
            ? originalObject.position.left + 20 // Offset horizontally
            : originalObject.position.left,
      },
    };
    // console.log("duplicated object", duplicatedObject);

    let duplicateFloatingWidget = {
      organization,
      widget: duplicatedObject,
      zoneUuid: zone.zoneUuid,
      index: index,
      versionId,
      projectId,
      userId,
    };

    if (visualizationSocket) {
      visualizationSocket.emit(
        "v1:viz-float:addDuplicate",
        duplicateFloatingWidget
      );
    }
    useDroppedObjectsStore.setState((state) => ({
      zones: {
        ...state.zones,
        [zoneName]: {
          ...state.zones[zoneName],
          objects: [...state.zones[zoneName].objects, duplicatedObject], // Append duplicated object
        },
      },
    }));

    // Make async API call outside of Zustand set function
    // let response = await addingFloatingWidgets(
    //   zone.zoneUuid,
    //   organization,
    //   duplicatedObject
    // );

    // if (response.message === "FloatWidget created successfully") {
    // Update the state inside `set`

    // }
  },
}));

export interface DroppedObjects {
  header: string;
  id: string;
  Data: {};
  value: string | number; // ✅ Allows both numbers and formatted strings
  per: string;
  className: string;
  position: { top: number; left: number; right: number; bottom: number }; // ✅ Ensures position is a tuple
}

export interface Zones {
  zoneName: string;
  zoneUuid: string;
  objects: DroppedObject[];
}

export const use3DWidget = create<any>((set: any) => ({
  widgets3D: [],
  setWidgets3D: (x: any) => set({ widgets3D: x }),
}));

export const useFloatingWidget = create<any>((set: any) => ({
  floatingWidget: [],
  setFloatingWidget: (x: any) => set({ floatingWidget: x }),
}));
