import React, { useEffect, useMemo, useRef, useState } from "react";
import { DraggableWidget } from "./draggableWidget";
import { useWidgetStore } from "../../store/store";

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

interface PanelProps {
  selectedZone: {
    zoneName: string; // Add zoneName property
    activeSides: Side[];
    panelOrder: Side[];
    lockedPanels: Side[];
    widgets: {
      id: string;
      type: string;
      title: string;
      panel: Side;
      data: any;
    }[];
  };
  setSelectedZone: React.Dispatch<
    React.SetStateAction<{
      zoneName: string; // Ensure zoneName is included in the state type
      activeSides: Side[];
      panelOrder: Side[];
      lockedPanels: Side[];
      widgets: {
        id: string;
        type: string;
        title: string;
        panel: Side;
        data: any;
      }[];
    }>
  >;
}

const generateUniqueId = () =>
  `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;

const Panel: React.FC<PanelProps> = ({ selectedZone, setSelectedZone }) => {
  const panelRefs = useRef<{ [side in Side]?: HTMLDivElement }>({});
  const [panelDimensions, setPanelDimensions] = useState<{
    [side in Side]?: { width: number; height: number };
  }>({});

  const getPanelStyle = useMemo(
    () => (side: Side) => {
      const currentIndex = selectedZone.panelOrder.indexOf(side);
      const previousPanels = selectedZone.panelOrder.slice(0, currentIndex);
      const leftActive = previousPanels.includes("left");
      const rightActive = previousPanels.includes("right");
      const topActive = previousPanels.includes("top");
      const bottomActive = previousPanels.includes("bottom");

      switch (side) {
        case "top":
        case "bottom":
          return {
            width: `calc(100% - ${
              (leftActive ? 204 : 0) + (rightActive ? 204 : 0)
            }px)`,
            left: leftActive ? "204px" : "0",
            right: rightActive ? "204px" : "0",
            [side]: "0",
            height: "200px",
          };
        case "left":
        case "right":
          return {
            height: `calc(100% - ${
              (topActive ? 204 : 0) + (bottomActive ? 204 : 0)
            }px)`,
            top: topActive ? "204px" : "0",
            bottom: bottomActive ? "204px" : "0",
            [side]: "0",
            width: "200px",
          };
        default:
          return {};
      }
    },
    [selectedZone.panelOrder]
  );

  const handleDrop = (e: React.DragEvent, panel: Side) => {
    e.preventDefault();
    const { draggedAsset } = useWidgetStore.getState();
    if (draggedAsset) {
      if (selectedZone.lockedPanels.includes(panel)) return;

      const currentWidgetsInPanel = selectedZone.widgets.filter(
        (w) => w.panel === panel
      ).length;

      const dimensions = panelDimensions[panel];
      const CHART_WIDTH = 200; // Width of each chart for top/bottom panels
      const CHART_HEIGHT = 200; // Height of each chart for left/right panels
      let maxCharts = 0;

      if (dimensions) {
        if (panel === "top" || panel === "bottom") {
          maxCharts = Math.floor(dimensions.width / CHART_WIDTH); // Use width for top/bottom
        } else {
          maxCharts = Math.floor(dimensions.height / CHART_HEIGHT); // Use height for left/right
        }
      } else {
        maxCharts = panel === "top" || panel === "bottom" ? 5 : 3; // Default values
      }

      if (currentWidgetsInPanel >= maxCharts) {
        return;
      }

      const updatedZone = {
        ...selectedZone,
        widgets: [
          ...selectedZone.widgets,
          {
            ...draggedAsset,
            id: generateUniqueId(),
            panel,
          },
        ],
      };

      // Update the selectedZone state
      setSelectedZone(updatedZone);
    }
  };

  useEffect(() => {
    const observers: ResizeObserver[] = [];
    const currentPanelRefs = panelRefs.current;

    selectedZone.activeSides.forEach((side) => {
      const element = currentPanelRefs[side];
      if (element) {
        const observer = new ResizeObserver((entries) => {
          for (const entry of entries) {
            const { width, height } = entry.contentRect;
            setPanelDimensions((prev) => ({
              ...prev,
              [side]: { width, height },
            }));
          }
        });
        observer.observe(element);
        observers.push(observer);
      }
    });

    return () => {
      observers.forEach((observer) => observer.disconnect());
    };
  }, [selectedZone.activeSides]);

  return (
    <>
      {selectedZone.activeSides.map((side) => (
        <div
          key={side}
          className={`panel ${side}-panel absolute`}
          style={getPanelStyle(side)} // Pass `side` to `getPanelStyle`
          onDrop={(e) => handleDrop(e, side)}
          onDragOver={(e) => e.preventDefault()}
          ref={(el) => {
            if (el) {
              panelRefs.current[side] = el;
            } else {
              delete panelRefs.current[side];
            }
          }}
        >
          <div
            className="panel-content"
            style={{
              pointerEvents: selectedZone.lockedPanels.includes(side)
                ? "none"
                : "auto",
              opacity: selectedZone.lockedPanels.includes(side) ? "0.8" : "1",
            }}
          >
            {selectedZone.widgets
              .filter((w) => w.panel === side)
              .map((widget) => (
                <DraggableWidget widget={widget} key={widget.id} />
              ))}
          </div>
        </div>
      ))}
    </>
  );
};

export default Panel;
