/* eslint-disable @typescript-eslint/no-explicit-any */
import { FC, memo, useState } from "react";
import { useDrag } from "react-dnd";
import { useDispatch, useSelector, useStore } from "react-redux";
import { ComponentItemProps } from "@/page/App/components/componentPanel/interface";
import { getIsIMPAKTEditMode } from "@/redux/config/configSelector";
import { endDragMultiNodes, startDragMultiNodes } from "@/utils/drag/drag";
import {
  generateWidgetLayoutInfo,
  newGenerateComponentNode,
} from "@/utils/generators/generateComponentNode";
import { DropResultInfo } from "../dotPanel/components/Canvas/interface";
import { DEFAULT_BODY_COLUMNS_NUMBER } from "../dotPanel/constant/canvas";
import { sendShadowMessageHandler } from "../dotPanel/utils/sendBinaryMessage";
import {
  DRAG_EFFECT,
  DragInfo,
} from "../scaleSquare/components/DragContainer/interface";
import {
  addComponentContainerStyle,
  addComponentStyle,
  iconStyle,
  itemContainerStyle,
  nameStyle,
} from "./style";
import { useTheme } from "@mui/material";
import { componentsActions } from "@/redux/currentApp/components/componentsSlice";
import { configActions } from "@/redux/config/configSlice";
import { DisplayNameGenerator } from "@/utils/generators/generateDisplayName";

export const ComponentItem: FC<ComponentItemProps> = memo(
  (props: ComponentItemProps) => {
    const theme = useTheme();
    const [isOver, setIsOver] = useState(false);
    const { widgetName, widgetType, icon, displayName } = props;
    const isEditMode = useSelector(getIsIMPAKTEditMode);
    const storeState = useStore();
    const dispatch = useDispatch();
    const handleAddComponent = () => {
        const realDisplayName = DisplayNameGenerator.generateDisplayName(
          widgetType,
          displayName,
        )
      const newComponentNode = newGenerateComponentNode(
        widgetType,
        realDisplayName,
        "bodySection1-bodySectionContainer1",
        [],
        1
      );
      dispatch(
        componentsActions.addComponentReducer([{ ...newComponentNode }])
      );
      dispatch(configActions.updateSelectedComponent([realDisplayName]));
    };
    const [, dragRef] = useDrag<DragInfo, DropResultInfo, any>(
      () => ({
        type: "components",
        canDrag: () => {
          return isEditMode;
        },
        collect: (monitor) => {
          return {
            isDragging: monitor.isDragging(),
          };
        },
        end: (draggedItem, monitor) => {
          const dropResultInfo = monitor.getDropResult();
          const { draggedComponents } = draggedItem;
          sendShadowMessageHandler(-1, "", [], 0, 0, 0, 0, 0, 0, 0, 0);
          endDragMultiNodes(
            draggedComponents,
            !!dropResultInfo?.isDropOnCanvas,
            true,
            storeState
          );
        },
        item: () => {
          const widgetLayoutInfo = generateWidgetLayoutInfo(
            widgetType,
            displayName
          );
          if (!widgetLayoutInfo) {
            return {
              draggedComponents: [],
              dragEffect: DRAG_EFFECT.ADD,
              draggedDisplayName: "",
              unitWWhenDragged: 0,
              columnNumberWhenDragged: DEFAULT_BODY_COLUMNS_NUMBER,
            };
          }
          startDragMultiNodes([widgetLayoutInfo],storeState);
          return {
            draggedComponents: [widgetLayoutInfo],
            dragEffect: DRAG_EFFECT.ADD,
            draggedDisplayName: widgetLayoutInfo.displayName,
            unitWWhenDragged: 0,
            columnNumberWhenDragged: DEFAULT_BODY_COLUMNS_NUMBER,
          };
        },
      }),
      [isEditMode]
    );

    return (
      <>
        <div
          css={itemContainerStyle}
          onMouseOver={() => setIsOver(true)}
          onMouseLeave={() => setIsOver(false)}
        >
          <span ref={dragRef} css={iconStyle(theme)}>
            {icon}
          </span>
          <span css={nameStyle(theme)}>{widgetName}</span>
          <div
            css={addComponentContainerStyle(theme, isOver)}
            onClick={handleAddComponent}
          >
            {
              isOver &&
                // <span onClick={handleAddComponent} css={addComponentStyle(theme)}>
                "+"
              // </span>
            }
          </div>
        </div>
      </>
    );
  }
);

ComponentItem.displayName = "ComponentItem";
