/* eslint-disable @typescript-eslint/no-explicit-any */
// import 'react-native-get-random-values';
// import { v4 as uuidv4 } from 'uuid';

import { FC, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useDrop } from "react-dnd";
// import { useTranslation } from "react-i18next"
import { useDispatch, useSelector } from "react-redux";
import { useScroll } from "react-use";
import useMeasure from "react-use-measure";
import { getIsIMPAKTEditMode, isShowDot } from "@/redux/config/configSelector";
import { getContainerListDisplayNameMappedChildrenNodeDisplayName } from "@/redux/currentApp/components/componentsSelector";
import { componentsActions } from "@/redux/currentApp/components/componentsSlice";
import {
  getComponentMap,
  // getComponentMap,
  getIsDragging,
  getIsResizing,
} from "@/redux/currentApp/executionTree/executionSelector";
import { newGenerateComponentNode } from "@/utils/generators/generateComponentNode";
import { ContainerEmptyState } from "@/widgetLibrary/ContainerWidget/emptyState";
import {
  DropCollectedProps,
  DropResultInfo,
  RenderComponentCanvasContainerProps,
} from "./interface";
import {
  applyComponentCanvasStyle,
  componentCanvasContainerStyle,
  // containerShapeStyle,
  dropZoneStyle,
  outerComponentCanvasContainerStyle,
  selectoSelectionStyle,
} from "./style";
import {
  DEFAULT_BODY_COLUMNS_NUMBER,
  SAFE_ROWS,
  SCROLL_CONTAINER_PADDING,
  UNIT_HEIGHT,
} from "../../constant/canvas";
import { getPaddingShape } from "../../utils/styleutils/padding";
import {
  DRAG_EFFECT,
  DragInfo,
} from "../../../scaleSquare/components/DragContainer/interface";
import { sendMousePositionHandler } from "../../utils/sendBinaryMessage";
import {
  removeScrollBarContainerControllerByDisplayName,
  setScrollBarContainerController,
} from "../../context/scrollBarContext";
import { useMousePositionAsync } from "../../hooks/useMousePostionAsync";
import { MousePreview } from "../MousePreview";
import ComponentParser from "../ComponentParser/index";
import { useTheme } from "@mui/material";
export const RenderComponentCanvasContainer: FC<
  RenderComponentCanvasContainerProps
> = (props) => {
  const {
    columnNumber = DEFAULT_BODY_COLUMNS_NUMBER,
    isRootCanvas,
    displayName,
    containerPadding,
    safeRowNumber = SAFE_ROWS,
    background,
    shadowSize = "none",
    isGridCanvas = false,
  } = props;

  const containerListMapChildName = useSelector(
    getContainerListDisplayNameMappedChildrenNodeDisplayName
  );
 const theme = useTheme()
  const scrollContainerRef = useRef<HTMLDivElement | null>(null);
  const firstDragRef = useRef(true);
  const dragStartScrollTop = useRef(0);
  const { y: scrollContainerScrollTop } = useScroll(scrollContainerRef);
  const [canvasRef, bounds] = useMeasure();
  const innerCanvasRef = useRef<HTMLDivElement | null>(null);
  // const { t } = useTranslation()
  const paddings = getPaddingShape(containerPadding);
  const fixedBounds = {
    top: bounds.top + paddings.paddingTop + SCROLL_CONTAINER_PADDING,
    left: bounds.left + paddings.paddingLeft + SCROLL_CONTAINER_PADDING,
    width:
      bounds.width -
      (paddings.paddingLeft +
        paddings.paddingRight +
        SCROLL_CONTAINER_PADDING * 2),
    height:
      bounds.height -
      (paddings.paddingTop +
        paddings.paddingBottom +
        SCROLL_CONTAINER_PADDING * 2),
  };

  const canShowDot = useSelector(isShowDot);
  const unitWidth = fixedBounds.width / columnNumber;
  const dispatch = useDispatch();
  const isDraggingGlobal = useSelector(getIsDragging);
  const isResizingGlobal = useSelector(getIsResizing);
  const componentMap = useSelector(getComponentMap);
  // const isLikeProductMode = useSelector(getIsLikeProductMode)
  const isEditMode = useSelector(getIsIMPAKTEditMode);
  const currentLayoutInfo = componentMap[displayName];
  const [collectedProps, dropRef] = useDrop<
    DragInfo,
    DropResultInfo,
    DropCollectedProps
  >(
    () => ({
      accept: ["components"],
      canDrop: () => {
        return isEditMode;
      },
      drop: (dropItem, monitor) => {
        const didDrop = monitor.didDrop();
        if (
          !monitor.isOver({
            shallow: true,
          }) &&
          didDrop
        ) {
          return {
            isDropOnCanvas: !!monitor.getDropResult()?.isDropOnCanvas,
          };
        }
        const { draggedComponents, dragEffect } = dropItem;

        const hasTable = draggedComponents.some(
          (components) => components.widgetType === "TABLE_WIDGET"
        );
        const isListChildrenCanvas = Object.values(
          containerListMapChildName
        ).some((childDisplayNames) => childDisplayNames.includes(displayName));

        if (hasTable && isListChildrenCanvas) {
          return {
            isDropOnCanvas: false,
          };
        }

        if (draggedComponents.length === 1) {
          switch (dragEffect) {
          
            case DRAG_EFFECT.ADD: {
              const newComponentNode = newGenerateComponentNode(
                draggedComponents[0].widgetType,
                draggedComponents[0].displayName,
                displayName,
                [],
                12
              );

              dispatch(
                componentsActions.addComponentReducer([{ ...newComponentNode }])
              );

              break;
            }
          }
        }
        const mousePosition = cursorPositionRef.current;
        sendMousePositionHandler(
          displayName,
          mousePosition.xInteger,
          mousePosition.yInteger,
          mousePosition.xMod,
          mousePosition.yMod
        );

        return {
          isDropOnCanvas: true,
        };
      },
      collect: (monitor) => {
        return {
          isOver: monitor.isOver({ shallow: true }),
        };
      },
    }),
    [
      isEditMode,
      unitWidth,
      fixedBounds,
      scrollContainerScrollTop,
      displayName,
      containerListMapChildName,
    ]
  );

  const autoScrollTimeID = useRef<number>(0);

  setScrollBarContainerController(displayName, scrollContainerRef);

  useEffect(() => {
    return () => {
      removeScrollBarContainerControllerByDisplayName(displayName);
    };
  }, [displayName]);

  useEffect(() => {
    const scrollContainer = scrollContainerRef.current;
    if (!scrollContainer) return;
    const autoScroll = (e: MouseEvent) => {
      if (
        (!collectedProps.isOver &&
          scrollContainer.dataset.isDraggingOver !== "true") ||
        !scrollContainer ||
        !isRootCanvas
      ) {
        return;
      }
      const { top, bottom } = scrollContainer.getBoundingClientRect();
      const { clientY } = e;
      window.clearInterval(autoScrollTimeID.current);
      autoScrollTimeID.current = window.setInterval(() => {
        if (clientY < top + UNIT_HEIGHT * safeRowNumber) {
          scrollContainer!.scrollBy({
            top: -8,
          });
        }
        if (clientY > bottom - UNIT_HEIGHT * safeRowNumber) {
          scrollContainer!.scrollBy({
            top: 8,
          });
        }
      }, 160);
    };
    scrollContainer?.addEventListener("mousemove", autoScroll);
    return () => {
      if (scrollContainer) {
        scrollContainer?.removeEventListener("mousemove", autoScroll);
      }
      window.clearInterval(autoScrollTimeID.current);
    };
  }, [collectedProps.isOver, isResizingGlobal, isRootCanvas, safeRowNumber]);

  useEffect(() => {
    if (firstDragRef.current && isDraggingGlobal) {
      firstDragRef.current = false;
      dragStartScrollTop.current = scrollContainerScrollTop;
      return;
    }
    if (!isDraggingGlobal) {
      firstDragRef.current = true;
      dragStartScrollTop.current = scrollContainerScrollTop;
    }
  }, [isDraggingGlobal, scrollContainerScrollTop]);

  const { cursorPositionRef } = useMousePositionAsync(
    scrollContainerRef,
    unitWidth,
    displayName,
    isRootCanvas,
    scrollContainerRef
  );
  const isDisabled = false;
  return (
    <div
      css={outerComponentCanvasContainerStyle(
        containerPadding,
        "",
        shadowSize
      )}
      data-outer-canvas-container={displayName}
      ref={isDisabled ? null : canvasRef}
    >
      <div
        css={componentCanvasContainerStyle}
        ref={scrollContainerRef}
        data-scroll-container={displayName}
        data-column-number={columnNumber}
        data-unit-width={unitWidth}
        data-is-dragging-over={false}
        className="scroll-container"
      >
        <div
          ref={(node) => {
            isDisabled ? null : dropRef(node);
            innerCanvasRef.current = isDisabled ? null : node;
          }}
          css={dropZoneStyle()}
        >
          <div
            css={[
              applyComponentCanvasStyle(unitWidth, canShowDot,isEditMode,theme),
              selectoSelectionStyle,
            ]}
            data-isroot={isRootCanvas}
            data-canvas-container={displayName}
            data-column-number={columnNumber}
            data-unit-width={unitWidth}
          >
            {isEditMode && (
              <MousePreview unitW={10} displayName={displayName} />
            )}
            {currentLayoutInfo?.childrenNode?.length > 0 && !isGridCanvas ? (
              currentLayoutInfo?.childrenNode?.map((childName: any) => {
                return (
                  <ComponentParser
                    key={`${displayName}-${childName}`}
                    displayName={childName}
                    unitW={unitWidth}
                    parentNodeDisplayName={displayName}
                    columnNumber={columnNumber}
                  />
                );
              })
            ) : isRootCanvas ? null : (
              <ContainerEmptyState
                isInner
                containerPadding={containerPadding}
              />
            )}
          </div>
        </div>
      </div>
    </div>
  );
};

RenderComponentCanvasContainer.displayName = "RenderComponentCanvasContainer";
export default RenderComponentCanvasContainer;
