
import { WalletIcon } from "../../icons/3dChartIcons";
import { useEffect, useRef, useState } from "react";
import {
  useDroppedObjectsStore,
  Zones,
} from "../../../store/useDroppedObjectsStore";
import useModuleStore from "../../../store/useModuleStore";
import { determinePosition } from "./functions/determinePosition";
import { getActiveProperties } from "./functions/getActiveProperties";
import { addingFloatingWidgets } from "../../../services/realTimeVisulization/zoneData/addFloatingWidgets";
import {
  DublicateIcon,
  KebabIcon,
  DeleteIcon,
} from "../../icons/ExportCommonIcons";
import DistanceLines from "./DistanceLines"; // Import the DistanceLines component
import { deleteFloatingWidgetApi } from "../../../services/realTimeVisulization/zoneData/deleteFloatingWidget";

import TotalCardComponent from "../realTimeVis/floating/TotalCardComponent";
import WarehouseThroughputComponent from "../realTimeVis/floating/WarehouseThroughputComponent";
import FleetEfficiencyComponent from "../realTimeVis/floating/FleetEfficiencyComponent";
import { useWidgetStore } from "../../../store/useWidgetStore";
interface DraggingState {
  zone: string;
  index: number;
  initialPosition: {
    top: number | "auto";
    left: number | "auto";
    right: number | "auto";
    bottom: number | "auto";
  };
}

interface DraggingState {
  zone: string;
  index: number;
  initialPosition: {
    top: number | "auto";
    left: number | "auto";
    right: number | "auto";
    bottom: number | "auto";
  };
}
const DroppedObjects: React.FC = () => {
  const zones = useDroppedObjectsStore((state) => state.zones);
  const [openKebabId, setOpenKebabId] = useState<string | null>(null);
  const updateObjectPosition = useDroppedObjectsStore(
    (state) => state.updateObjectPosition
  );
  const deleteObject = useDroppedObjectsStore((state) => state.deleteObject);

  const duplicateObject = useDroppedObjectsStore((state) => state.duplicateObject);
  const [draggingIndex, setDraggingIndex] = useState<DraggingState | null>(
    null
  );
  const [offset, setOffset] = useState<[number, number] | null>(null);
  const { setSelectedChartId } = useWidgetStore();
  const [activeEdges, setActiveEdges] = useState<{
    vertical: "top" | "bottom";
    horizontal: "left" | "right";
  } | null>(null); // State to track active edges for distance lines
  const [currentPosition, setCurrentPosition] = useState<{
    top: number | "auto";
    left: number | "auto";
    right: number | "auto";
    bottom: number | "auto";
  } | null>(null); // State to track the current position during drag
  const animationRef = useRef<number | null>(null);
  const { activeModule } = useModuleStore();
  const kebabRef = useRef<HTMLDivElement>(null);


  // Clean up animation frame on unmount
  useEffect(() => {
    return () => {
      if (animationRef.current) {
        cancelAnimationFrame(animationRef.current);
      }
    };
  }, []);
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (kebabRef.current && !kebabRef.current.contains(event.target as Node)) {
        setOpenKebabId(null);
      }
    };

    // Add event listener when component mounts
    document.addEventListener("mousedown", handleClickOutside);

    // Clean up event listener when component unmounts
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, []);

  const zoneEntries = Object.entries(zones);
  if (zoneEntries.length === 0) return null;
  const [zoneName, zone] = zoneEntries[0];

  function handleDuplicate(zoneName: string, index: number) {
    setOpenKebabId(null)
    duplicateObject(zoneName, index); // Call the duplicateObject method from the store
  }

  async function handleDelete(zoneName: string, id: string, index: number) {
    try {
      const email = localStorage.getItem("email") || "";
      const organization = email?.split("@")[1]?.split(".")[0];

      let res = await deleteFloatingWidgetApi(id, organization);
      console.log('res: ', res);

      if (res.message === "FloatingWidget deleted successfully") {
        deleteObject(zoneName, id, index); // Call the deleteObject method from the store
      }
    } catch (error) {
      console.error("Error deleting floating widget:", error);
    }
  }


  const handlePointerDown = (event: React.PointerEvent, index: number) => {
    if ((event.target as HTMLElement).closest(".kebab-options") || (event.target as HTMLElement).closest(".kebab")) {
      return; // Prevent dragging when clicking on the kebab menu or its options
    }
    const obj = zone.objects[index];
    const element = event.currentTarget as HTMLElement;
    element.setPointerCapture(event.pointerId);
    const container = document.getElementById("real-time-vis-canvas");
    if (!container) return;

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

    // Determine active properties for the initial position
    const [activeProp1, activeProp2] = getActiveProperties(obj.position);

    // Set active edges for distance lines
    const vertical = activeProp1 === "top" ? "top" : "bottom";
    const horizontal = activeProp2 === "left" ? "left" : "right";
    setActiveEdges({ vertical, horizontal });

    // Store the initial position strategy and active edges
    setDraggingIndex({
      zone: zoneName,
      index,
      initialPosition: { ...obj.position },
    });

    // Calculate offset from mouse to object edges
    let offsetX = 0;
    let offsetY = 0;

    if (activeProp1 === "top") {
      offsetY = relativeY - (obj.position.top as number);
    } else {
      offsetY = rect.height - relativeY - (obj.position.bottom as number);
    }

    if (activeProp2 === "left") {
      offsetX = relativeX - (obj.position.left as number);
    } else {
      offsetX = rect.width - relativeX - (obj.position.right as number);
    }

    setOffset([offsetY, offsetX]);
  };

  const handlePointerMove = (event: React.PointerEvent) => {
    if (!draggingIndex || !offset) return;

    const container = document.getElementById("real-time-vis-canvas");
    if (!container) return;

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

    // Dynamically determine the current position strategy
    const newPositionStrategy = determinePosition(rect, relativeX, relativeY);
    const [activeProp1, activeProp2] = getActiveProperties(newPositionStrategy);

    // Update active edges for distance lines
    const vertical = activeProp1 === "top" ? "top" : "bottom";
    const horizontal = activeProp2 === "left" ? "left" : "right";
    setActiveEdges({ vertical, horizontal });

    // Calculate new position based on the active properties
    let newY = 0;
    let newX = 0;

    if (activeProp1 === "top") {
      newY = relativeY - offset[0];
    } else {
      newY = rect.height - (relativeY + offset[0]);
    }

    if (activeProp2 === "left") {
      newX = relativeX - offset[1];
    } else {
      newX = rect.width - (relativeX + offset[1]);
    }

    // Apply boundaries
    newX = Math.max(0, Math.min(rect.width - 50, newX));
    newY = Math.max(0, Math.min(rect.height - 50, newY));

    // Create new position object
    const newPosition = {
      ...newPositionStrategy,
      [activeProp1]: newY,
      [activeProp2]: newX,
      // Clear opposite properties
      [activeProp1 === "top" ? "bottom" : "top"]: "auto",
      [activeProp2 === "left" ? "right" : "left"]: "auto",
    };

    // Update the current position state for DistanceLines
    setCurrentPosition(newPosition);
    // Update position immediately without animation frame
    updateObjectPosition(zoneName, draggingIndex.index, newPosition);

    // if (!animationRef.current) {
    //   animationRef.current = requestAnimationFrame(() => {
    //     updateObjectPosition(zoneName, draggingIndex.index, newPosition);
    //     animationRef.current = null;
    //   });
    // }
  };

  const handlePointerUp = async (event: React.PointerEvent<HTMLDivElement>) => {
    try {
      if (!draggingIndex || !offset) return;

      const container = document.getElementById("real-time-vis-canvas");
      if (!container) return;

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

      // Only now determine the final position strategy
      const finalPosition = determinePosition(rect, relativeX, relativeY);
      const [activeProp1, activeProp2] = getActiveProperties(finalPosition);

      // Calculate final position using the new strategy
      let finalY = 0;
      let finalX = 0;

      if (activeProp1 === "top") {
        finalY = relativeY - offset[0];
      } else {
        finalY = rect.height - (relativeY + offset[0]);
      }

      if (activeProp2 === "left") {
        finalX = relativeX - offset[1];
      } else {
        finalX = rect.width - (relativeX + offset[1]);
      }

      // Apply boundaries
      finalX = Math.max(0, Math.min(rect.width - 50, finalX));
      finalY = Math.max(0, Math.min(rect.height - 50, finalY));

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

      // Save to backend
      const email = localStorage.getItem("email") || "";
      const organization = email?.split("@")[1]?.split(".")[0];
      const response = await addingFloatingWidgets(zone.zoneId, organization, {
        ...zone.objects[draggingIndex.index],
        position: boundedPosition,
      });
      console.log('response: ', response);

      if (response.message === "Widget updated successfully") {
        updateObjectPosition(zoneName, draggingIndex.index, boundedPosition);
      }

      // // Clean up
      // setDraggingIndex(null);
      // setOffset(null);
      // setActiveEdges(null); // Clear active edges
      // setCurrentPosition(null); // Reset current position
      // if (animationRef.current) {
      //   cancelAnimationFrame(animationRef.current);
      //   animationRef.current = null;
      // }
    } catch (error) {
      console.error("Error in handlePointerUp:", error);
    } finally {
      // Clean up regardless of success or failure
      setDraggingIndex(null);
      setOffset(null);
      setActiveEdges(null);
      setCurrentPosition(null);

      // Cancel any pending animation frame
      if (animationRef.current) {
        cancelAnimationFrame(animationRef.current);
        animationRef.current = null;
      }
    }
  };

  const handleKebabClick = (id: string, event: React.MouseEvent) => {
    event.stopPropagation();
    setOpenKebabId((prevId) => (prevId === id ? null : id));
  };

  return (
    <div
      onPointerMove={handlePointerMove}
      onPointerUp={handlePointerUp}
      className="floating-wrapper"
    >
      {zone.objects.map((obj, index) => (
        <div
          key={`${zoneName}-${index}`}
          className={obj.className}
          style={{
            position: "absolute",
            top:
              typeof obj.position.top === "number"
                ? `${obj.position.top}px`
                : "auto",
            left:
              typeof obj.position.left === "number"
                ? `${obj.position.left}px`
                : "auto",
            right:
              typeof obj.position.right === "number"
                ? `${obj.position.right}px`
                : "auto",
            bottom:
              typeof obj.position.bottom === "number"
                ? `${obj.position.bottom}px`
                : "auto",
          }}
          onPointerDown={(event) => handlePointerDown(event, index)}
          onClick={() => {
            setSelectedChartId(obj)
          }}
        >
          {obj.className === "floating total-card" ? (
            <>
              <TotalCardComponent object={obj} />
            </>
          ) : obj.className === "warehouseThroughput floating" ? (
            <>
              <WarehouseThroughputComponent />
            </>
          ) : obj.className === "fleetEfficiency floating" ? (
            <>
              <FleetEfficiencyComponent object={obj} />
            </>
          ) : null}

          <div
            className="icon kebab"
            ref={kebabRef}
            onClick={(event) => {
              event.stopPropagation();
              handleKebabClick(obj.id, event)
            }}
          >
            <KebabIcon />
          </div>
          {openKebabId === obj.id && (
            <div className="kebab-options" ref={kebabRef}>
              <div className="dublicate btn" onClick={(event) => {
                event.stopPropagation();
                handleDuplicate(zoneName, index); // Call the duplicate handler
              }}>
                <div className="icon">
                  <DublicateIcon />
                </div>
                <div className="label">Duplicate</div>
              </div>
              <div className="edit btn" onClick={(event) => {
                event.stopPropagation();
                handleDelete(zoneName, obj.id, index); // Call the delete handler
              }}>
                <div className="icon">
                  <DeleteIcon />
                </div>
                <div className="label">Delete</div>
              </div>
            </div>
          )}

        </div>
      ))}

      {/* Render DistanceLines component during drag */}
      {draggingIndex !== null &&
        activeEdges !== null &&
        currentPosition !== null && (
          <DistanceLines
            obj={{
              position: {
                top:
                  currentPosition.top !== "auto"
                    ? currentPosition.top
                    : undefined,
                bottom:
                  currentPosition.bottom !== "auto"
                    ? currentPosition.bottom
                    : undefined,
                left:
                  currentPosition.left !== "auto"
                    ? currentPosition.left
                    : undefined,
                right:
                  currentPosition.right !== "auto"
                    ? currentPosition.right
                    : undefined,
              },
            }}
            activeEdges={activeEdges}
          />
        )}
    </div>
  );
};

export default DroppedObjects;


