import React, { useEffect, useRef, useState } from "react";
import {
  AsileIcon,
  CommentIcon,
  CursorIcon,
  DeleteIcon,
  FloorIcon,
  FreeMoveIcon,
  MeasureToolIcon,
  PenIcon,
  PlayIcon,
  SaveTemplateIcon,
  WallIcon,
  ZoneIcon,
} from "../icons/ExportToolsIcons";
import { ArrowIcon, TickIcon } from "../icons/ExportCommonIcons";
import useModuleStore, { useThreeDStore } from "../../store/useModuleStore";
import { handleSaveTemplate } from "../../modules/visualization/functions/handleSaveTemplate";
import { usePlayButtonStore } from "../../store/usePlayButtonStore";
import useTemplateStore from "../../store/useTemplateStore";
import { useSelectedZoneStore } from "../../store/visualization/useZoneStore";
import {
  useActiveTool,
  useAddAction,
  useSelectedWallItem,
  useSocketStore,
  useToggleView,
  useToolMode,
  useActiveSubTool,
  useShortcutStore,
} from "../../store/builder/store";
import { useToggleStore } from "../../store/useUIToggleStore";
import {
  use3DWidget,
  useFloatingWidget,
} from "../../store/visualization/useDroppedObjectsStore";
import { useParams } from "react-router-dom";
import { useVersionContext } from "../../modules/builder/version/versionContext";
import { MoveIcon, RotateIcon } from "../icons/ShortcutIcons";

// Utility component
const ToolButton = ({
  toolKey,
  toolId,
  icon: Icon,
  active,
  onClick,
  tooltip,
}: any) => (
  <button
    key={toolKey} // used in rendering list
    id={toolId}
    className={`tool-button ${active ? "active" : ""}`}
    onClick={onClick}
  >
    <div className="tooltip">{tooltip}</div>
    <div className="tool" id={toolId}>
      <Icon isActive={active} />
    </div>
  </button>
);

const Tools: React.FC = () => {
  const { activeModule } = useModuleStore();
  const { toggleThreeD, setToggleThreeD } = useThreeDStore();
  const { isPlaying, setIsPlaying } = usePlayButtonStore();
  const { showShortcuts } = useShortcutStore();

  const { activeTool, setActiveTool, setToolMode, setAddAction } =
    useStoreHooks();

  const { setActiveSubTool, activeSubTool } = useActiveSubTool();
  const { setSelectedWallItem } = useSelectedWallItem();
  const { setToggleUI } = useToggleStore();
  const { setToggleView, toggleView } = useToggleView();

  const { addTemplate, templates } = useTemplateStore();
  const { selectedZone } = useSelectedZoneStore();
  const { floatingWidget } = useFloatingWidget();
  const { widgets3D } = use3DWidget();

  const { visualizationSocket } = useSocketStore();
  const { selectedVersionStore } = useVersionContext();
  const { selectedVersion } = selectedVersionStore();
  const { projectId } = useParams();

  const dropdownRef = useRef<HTMLButtonElement>(null);
  const [openDrop, setOpenDrop] = useState(false);

  // 1. Set UI toggles on initial render
  useEffect(() => {
    setToggleUI(
      localStorage.getItem("navBarUiLeft") !== "false",
      localStorage.getItem("navBarUiRight") !== "false"
    );
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // 2. Update tool based on subtool and module
  useEffect(() => {
    setActiveTool(activeSubTool);
    setActiveSubTool(activeSubTool);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [activeModule]);

  // 3. Update tools behavior based on selected tool and view mode
  useEffect(() => {
    resetTools();
    updateToolBehavior(activeTool, toggleView);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [activeTool, toggleView]);

  // 4. Dropdown auto-close
  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (
        dropdownRef.current &&
        !dropdownRef.current.contains(e.target as Node)
      ) {
        setOpenDrop(false);
      }
    };
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  const resetTools = () => {
    setToolMode(null);
    setAddAction(null);
  };

  const updateToolBehavior = (tool: string, is2D: boolean) => {
    switch (tool) {
      case "cursor":
        is2D ? setToolMode("move") : setToolMode("cursor");
        break;
      case "draw-wall":
        is2D && setToolMode("Wall");
        break;
      case "draw-aisle":
        is2D && setToolMode("Aisle");
        break;
      case "draw-zone":
        is2D && setToolMode("Zone");
        break;
      case "draw-floor":
        is2D && setToolMode("Floor");
        break;
      case "measure":
        setToolMode("MeasurementScale");
        break;
      case "Add pillar":
        if (!is2D) setAddAction("Pillar");
        break;
      case "delete":
        is2D ? setToolMode("2D-Delete") : setToolMode("3D-Delete");
        break;
    }
  };

  const toggle2D3D = () => {
    const toggleTo2D = toggleView;
    setToggleView(!toggleTo2D);
    setToggleThreeD(toggleTo2D);
    setToggleUI(toggleTo2D, toggleTo2D);
    if (toggleTo2D) {
      setSelectedWallItem(null);
      setAddAction(null);
    }
    setActiveTool("cursor");
    setActiveSubTool("cursor");
    setToggleUI(
      localStorage.getItem("navBarUiLeft") !== "false",
      localStorage.getItem("navBarUiRight") !== "false"
    );
  };

  const renderBuilderTools = () => (
    <>
      {!toggleThreeD && (
        <div className="draw-tools">
          <ToolButton
            toolId="drawWall"
            icon={WallIcon}
            tooltip="draw wall (q)"
            active={activeTool === "draw-wall"}
            onClick={() => setActiveTool("draw-wall")}
          />
          <ToolButton
            toolId="drawZone"
            icon={ZoneIcon}
            tooltip="draw zone (e)"
            active={activeTool === "draw-zone"}
            onClick={() => setActiveTool("draw-zone")}
          />
          <ToolButton
            toolId="drawAisle"
            icon={AsileIcon}
            tooltip="draw aisle (r)"
            active={activeTool === "draw-aisle"}
            onClick={() => setActiveTool("draw-aisle")}
          />
          <ToolButton
            toolId="drawFloor"
            icon={FloorIcon}
            tooltip="draw floor (t)"
            active={activeTool === "draw-floor"}
            onClick={() => setActiveTool("draw-floor")}
          />
        </div>
      )}
      <div className="draw-tools">
        <ToolButton
          toolId="measureScale"
          icon={MeasureToolIcon}
          tooltip="measure scale (m)"
          active={activeTool === "measure"}
          onClick={() => setActiveTool("measure")}
        />
      </div>
    </>
  );

  const renderSimulationTools = () => (
    <div className="draw-tools">
      <ToolButton
        toolId="pen"
        icon={PenIcon}
        tooltip="pen"
        active={activeTool === "pen"}
        onClick={() => setActiveTool("pen")}
      />
    </div>
  );

  const renderVisualizationTools = () => (
    <div className="draw-tools">
      <ToolButton
        toolId="saveTemplate"
        icon={SaveTemplateIcon}
        tooltip="save template"
        active={false}
        onClick={() =>
          handleSaveTemplate({
            addTemplate,
            floatingWidget,
            widgets3D,
            selectedZone,
            templates,
            visualizationSocket,
            projectId,
            versionId: selectedVersion?.versionId || "",
          })
        }
      />
    </div>
  );

  const renderModeSwitcher = () => (
    <button
      id="toggle-threed-button"
      className={`toggle-threed-button${toggleThreeD ? " toggled" : ""}`}
      onClick={toggle2D3D}
    >
      <div className="tooltip">toggle view (tab)</div>
      <div className={`toggle-option${!toggleThreeD ? " active" : ""}`}>2d</div>
      <div className={`toggle-option${toggleThreeD ? " active" : ""}`}>3d</div>
    </button>
  );

  const getIconByTool = (tool: string) => {
    switch (tool) {
      case "cursor":
        return CursorIcon;
      case "free-hand":
        return FreeMoveIcon;
      case "delete":
        return DeleteIcon;
      case "move":
        return MoveIcon;
      case "rotate":
        return RotateIcon;
      default:
        return CursorIcon;
    }
  };

  const getTooltipShortcut = (tool: string) => {
    switch (tool) {
      case "cursor":
        return "v";
      case "free-hand":
        return "h";
      case "delete":
        return "x";
      default:
        return "";
    }
  };

  const getIconComponent = (option: string) => {
    switch (option) {
      case "cursor":
        return <CursorIcon isActive={false} />;
      case "free-hand":
        return <FreeMoveIcon isActive={false} />;
      case "delete":
        return <DeleteIcon isActive={false} />;
      case "move":
        return <MoveIcon />;
      case "rotate":
        return <RotateIcon />;
      default:
        return null;
    }
  };

  return (
    <div className={`tools-container ${showShortcuts ? "visible" : ""}`}>
      <div className="activeDropicon">
        {/* Tool Picker (cursor, delete, etc.) */}
        {["cursor", "free-hand", "delete"].map(
          (tool) =>
            activeSubTool === tool && (
              <ToolButton
                key={tool}
                toolId={tool}
                icon={getIconByTool(tool)}
                tooltip={`${tool} (${getTooltipShortcut(tool)})`}
                active={activeTool === tool}
                onClick={() => setActiveTool(tool)}
              />
            )
        )}
        {/* Dropdown Menu */}
        {activeModule !== "visualization" && (
          <button
            id="drop-down-button"
            title="drop-down"
            className="drop-down-option-button"
            ref={dropdownRef}
            onClick={() => setOpenDrop(!openDrop)}
          >
            <ArrowIcon />
            {openDrop && (
              <div className="drop-down-container">
                {["cursor", "free-hand", "delete"].map((option) => (
                  <button
                    key={option}
                    id={`${option}-tool`}
                    className="option-list"
                    onClick={() => {
                      setActiveTool(option);
                      setActiveSubTool(option);
                      setOpenDrop(false);
                    }}
                  >
                    <div className="active-option">
                      {activeSubTool === option && <TickIcon />}
                    </div>
                    {getIconComponent(option)}
                    <div className="option">{option}</div>
                  </button>
                ))}
              </div>
            )}
          </button>
        )}
      </div>

      {activeModule !== "visualization" && (
        <>
          <div className="split"></div>
          <div className="transform-tools">
            {["move", "rotate"].map((tool) => (
              <ToolButton
                key={tool}
                toolId={tool}
                icon={getIconByTool(tool)}
                tooltip={`${tool}`}
                active={activeTool === tool}
                onClick={() => setActiveTool(tool)}
              />
            ))}
          </div>
        </>
      )}

      <div className="split"></div>
      {activeModule === "builder" && renderBuilderTools()}
      {activeModule === "simulation" && renderSimulationTools()}
      {activeModule === "visualization" && renderVisualizationTools()}

      <div className="split"></div>
      <div className="general-options">
        <ToolButton
          toolId="comment"
          icon={CommentIcon}
          tooltip="comment"
          active={activeTool === "comment"}
          onClick={() => setActiveTool("comment")}
        />
        {toggleThreeD && (
          <ToolButton
            toolId="play"
            icon={PlayIcon}
            tooltip="play (ctrl + p)"
            active={activeTool === "play"}
            onClick={() => setIsPlaying(!isPlaying)}
          />
        )}
      </div>

      {activeModule === "builder" && (
        <>
          <div className="split"></div>
          {renderModeSwitcher()}
        </>
      )}
    </div>
  );
};

// Extracted common store logic
const useStoreHooks = () => {
  return {
    ...useActiveTool(),
    ...useToolMode(),
    ...useAddAction(),
  };
};

export default Tools;
