import { WalletIcon } from "../../icons/3dChartIcons";
import { useEffect, useRef, useState } from "react";
import { Line } from "react-chartjs-2";
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";

const DroppedObjects: React.FC = () => {
  const zones = useDroppedObjectsStore((state) => state.zones);

  const updateObjectPosition = useDroppedObjectsStore(
    (state) => state.updateObjectPosition
  );
  const [draggingIndex, setDraggingIndex] = useState<{
    zone: string;
    index: number;
  } | null>(null);
  const [offset, setOffset] = useState<[number, number] | null>(null);
  const positionRef = useRef<[number, number] | null>(null);
  const animationRef = useRef<number | null>(null);
  const { activeModule } = useModuleStore();

  // Get the first zone and its objects
  const zoneEntries = Object.entries(zones);
  if (zoneEntries.length === 0) return null; // No zone, nothing to render
  const [zoneName, zone] = zoneEntries[0]; // Only render the first zone

  // Handle pointer down event
  function handlePointerDown(event: React.PointerEvent, index: number) {
    const obj = zone.objects[index];
    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 which properties are active for this object
    const [activeProp1, activeProp2] = getActiveProperties(obj.position);

    // Calculate the offset based on the active properties
    let offsetX = 0;
    let offsetY = 0;

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

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

    setDraggingIndex({ zone: zoneName, index });
    setOffset([offsetY, offsetX]);
  }

  // Handle pointer move event
  function 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;

    // Determine which properties are active for the dragged object
    const obj = zone.objects[draggingIndex.index];
    const [activeProp1, activeProp2] = getActiveProperties(obj.position);

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

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

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

    // Ensure the object stays within the canvas boundaries
    newX = Math.max(0, Math.min(rect.width - 50, newX));
    newY = Math.max(0, Math.min(rect.height - 50, newY));

    // Update the position reference
    positionRef.current = [newY, newX];

    // Update the object's position using requestAnimationFrame for smoother animations
    if (!animationRef.current) {
      animationRef.current = requestAnimationFrame(() => {
        if (positionRef.current) {
          updateObjectPosition(zoneName, draggingIndex.index, {
            ...obj.position,
            [activeProp1]: positionRef.current[0],
            [activeProp2]: positionRef.current[1],
          });
        }
        animationRef.current = null;
      });
    }
  }

  // Handle pointer up event
  async function handlePointerUp(event: React.MouseEvent<HTMLDivElement>) {
    try {
      if (!draggingIndex || !offset) return;

      const email = localStorage.getItem("email") || "";
      const organization = email?.split("@")[1]?.split(".")[0];
      const container = document.getElementById("real-time-vis-canvas");
      if (!container) throw new Error("Canvas container not found");

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

      // Recalculate the position using determinePosition
      const newPosition = determinePosition(rect, relativeX, relativeY);

      // Validate the dragging index and get the object
      if (!zone.objects[draggingIndex.index]) {
        throw new Error("Dragged object not found in the zone");
      }
      const obj = { ...zone.objects[draggingIndex.index], position: newPosition };
      let response = await addingFloatingWidgets(zone.zoneId, organization, obj);
      if (response.message === "Widget updated successfully") {
        updateObjectPosition(zoneName, draggingIndex.index, newPosition);
      }

      // Reset states
      setDraggingIndex(null);
      setOffset(null);

      if (animationRef.current) {
        cancelAnimationFrame(animationRef.current);
        animationRef.current = null;
      }
    } catch (error) {

    }
  }


  return (
    <div onPointerMove={handlePointerMove} onPointerUp={handlePointerUp}>
      {zone.objects.map((obj, index) => (
        <div
          key={`${zoneName}-${index}`}
          className={obj.className}
          style={{
            position: "absolute",
            top:
              typeof obj.position.top !== "string"
                ? `${obj.position.top}px`
                : "auto",
            left:
              typeof obj.position.left !== "string"
                ? `${obj.position.left}px`
                : "auto",
            right:
              typeof obj.position.right !== "string"
                ? `${obj.position.right}px`
                : "auto",
            bottom:
              typeof obj.position.bottom !== "string"
                ? `${obj.position.bottom}px`
                : "auto",
            // transition: draggingIndex?.index === index ? "none" : "transform 0.1s ease-out",
          }}
          onPointerDown={(event) => handlePointerDown(event, index)}
        >
          {obj.className === "floating total-card" ? (
            <>
              <div className="header-wrapper">
                <div className="header">{obj.header}</div>
                <div className="data-values">
                  <div className="value">{obj.value}</div>
                  <div className="per">{obj.per}</div>
                </div>
              </div>
              <div className="icon">
                <WalletIcon />
              </div>
            </>
          ) : obj.className === "warehouseThroughput floating" ? (
            <>
              <div className="header">
                <h2>Warehouse Throughput</h2>
                <p>
                  <span>(+5) more</span> in 2025
                </p>
              </div>
              <div className="lineGraph" style={{ height: "100%" }}>
                {/* <Line data={lineGraphData} options={lineGraphOptions} /> */}
              </div>
            </>
          ) : obj.className === "fleetEfficiency floating" ? (
            <>
              <h2 className="header">Fleet Efficiency</h2>
              <div className="progressContainer">
                <div className="progress">
                  <div className="barOverflow">
                    <div
                      className="bar"
                      style={{ transform: `rotate(${obj.value}deg)` }}
                    ></div>
                  </div>
                </div>
              </div>
              <div className="scaleLabels">
                <span>0%</span>
                <div className="centerText">
                  <div className="percentage">{obj.per}%</div>
                  <div className="status">Optimal</div>
                </div>
                <span>100%</span>
              </div>
            </>
          ) : null}
        </div>
      ))}
    </div>
  );
};

export default DroppedObjects;
