import { AnimatePresence, motion } from "framer-motion";
import { FC, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
import TransformIcon from "@mui/icons-material/Transform";
import ArrowCircleUpIcon from "@mui/icons-material/ArrowCircleUp";
import PanToolIcon from "@mui/icons-material/PanTool";
import ArrowCircleDownIcon from "@mui/icons-material/ArrowCircleDown";
import  ComponentIcon  from "@/assets/button-rect.svg";
import { MovableModal } from "@/components/Modal/movableModal";
import { panelBarItemContainerAnimationVariants } from "@/components/PanelBar/style";
import {
  getCopiedWidget,
  getExpandedWidgets,
  getMoveWidget,
  getSelectedComponentDisplayNames,
} from "@/redux/config/configSelector";
import { configActions } from "@/redux/config/configSlice";
import { MoreAction } from "../MoreAction";
import { WorkSpaceTreeNode } from "../WorkSpaceTreeItem/WorkSpaceTreeNode";
import { BaseDataItemProps } from "./interface";
import {
  applyExpandIconStyle,
  expendContainerStyle,
  iconContainerStyle,
  itemContainerStyle,
  itemContentStyle,
  modalBodyContainerStyle,
  outerContainerStyle,
  rectangleStyle,
  titleAndIconContainerStyle,
  titleStyle,
} from "./style";
import { ViewItemShape } from "@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/interface";
import LeftIcon from "@mui/icons-material/ArrowRightOutlined";
import { useTheme } from "@mui/material";
import { componentsActions } from "@/redux/currentApp/components/componentsSlice";
import { DisplayNameGenerator } from "@/utils/generators/generateDisplayName";
import { getComponentMap } from "@/redux/currentApp/components/componentsSelector";
import _ from "lodash";
import {
  ComponentMapNode,
  ComponentTreeNode,
} from "@/redux/currentApp/components/componentsState";
const formatModalTitle = (index: number) => {
  switch (index) {
    case 0: {
      return "header";
    }
    case 1: {
      return "body";
    }
    case 2: {
      return "footer";
    }
    default: {
      return "container";
    }
  }
};
export const mapToFlatTree = (
  map: Record<string, ComponentMapNode>,
  rootDisplayName: string
): ComponentTreeNode => {
  const reconstruct = (displayName: string): ComponentTreeNode => {
    const node = map[displayName];
    return {
      ...node,
      childrenNode: node.childrenNode.map((childDisplayName) => {
        const childNode = reconstruct(childDisplayName);
        return {
          ...childNode,
          displayName: DisplayNameGenerator.generateDisplayName(
            childNode.showName
          ),
        };
      }),
    };
  };

  return reconstruct(rootDisplayName);
};
export const BaseDataItem: FC<BaseDataItemProps> = (props) => {
  const {
    title,
    fakeTitle,
    type,
    level,
    canExpand,
    haveMoreAction,
    value,
    onClick,
    dataType,
    selectedDisplayNames,
  } = props;
  const copyWidgetName = useSelector(getCopiedWidget);
  const ComponentsMap = useSelector(getComponentMap);
  const moveWidgetName = useSelector(getMoveWidget);
  const [isOpenCodeModal, setIsOpenCodeModal] = useState(false);
  const expandedStatus = useSelector(getExpandedWidgets);
  const selectedComponent = useSelector(getSelectedComponentDisplayNames);
  const isExpanded = (canExpand ?? false) && (expandedStatus?.[title] ?? false);
  const theme = useTheme();
  const isSelected = selectedDisplayNames?.includes(title) ?? false;
  const dispatch = useDispatch();
  const handleClickOnContainer = () => {
    onClick?.(title, type ?? "");
  };

  const handleClickOnExpandIcon = (e: React.MouseEvent) => {
    e.stopPropagation();
    if (!isExpanded) {
      dispatch(configActions.addExpandedWidgetReducer([title]));
    } else {
      dispatch(configActions.removeExpandWidgetReducer([title]));
    }
  };
  const handleAddComponent = (
    targetWidgetparentDisplayName: string,
    targetWidgetDisplayName: string,
    copiedOrMoveWidgetName: string,
    addType: "down" | "up",
    actionType: "copy" | "move"
  ) => {
    const realDisplayName = DisplayNameGenerator.generateDisplayName(
      ComponentsMap[copiedOrMoveWidgetName].showName
    );

    const newComponentNode: ComponentMapNode = _.cloneDeep(
      ComponentsMap[copiedOrMoveWidgetName]
    );
    newComponentNode.displayName = realDisplayName;
    newComponentNode.parentNode = targetWidgetparentDisplayName;
    const flatTreeComponentNode: ComponentTreeNode = mapToFlatTree(
      { ...ComponentsMap, [realDisplayName]: newComponentNode },
      realDisplayName
    );

    const newChildrenNode = [];
    let addIndex = 0;
    ComponentsMap[targetWidgetparentDisplayName].childrenNode.map((e, i) => {
      if (e == copiedOrMoveWidgetName) {
        if (actionType === "move") {
          return;
        }
      }
      if (i >= addIndex && addIndex !== 0) {
        newChildrenNode[i + 1] = e;
        return;
      }
      if (e === targetWidgetDisplayName) {
        addIndex = i + 1;
        if (addType === "down") {
          newChildrenNode[i] = e;
          newChildrenNode[i + 1] = realDisplayName;
        } else {
          newChildrenNode[i] = realDisplayName;
          newChildrenNode[i + 1] = e;
        }
        return;
      }
      newChildrenNode[i] = e;
    });

    dispatch(componentsActions.addComponentReducer([flatTreeComponentNode]));
    if (actionType === "move") {
      componentsActions.deleteComponentNodeReducer({
        displayNames: [copiedOrMoveWidgetName],
      });
    }
    dispatch(
      componentsActions.sortComponentNodeChildrenReducer({
        parentDisplayName: targetWidgetparentDisplayName,
        newChildrenNode: newChildrenNode,
      })
    );
    // dispatch(configActions.updateSelectedComponent([realDisplayName]));
  };
  const handleMoveInit = (title: string) => {
    dispatch(configActions.updateMovedWidget(title));
    dispatch(configActions.updateCopiedWidget(""));
  };
  const handleCopyInit = (title: string) => {
    dispatch(configActions.updateCopiedWidget(title));
    dispatch(configActions.updateMovedWidget(""));
  };
  const handleAddDown = (title: string, parentDisplayName: string) => {
    return handleAddComponent(
      parentDisplayName,
      title,
      copyWidgetName || moveWidgetName,
      "down",
      copyWidgetName ? "copy" : "move"
    );
  };
  const handleAddUp = (title: string, parentDisplayName: string) => {
    handleAddComponent(
      parentDisplayName,
      title,
      copyWidgetName || moveWidgetName,
      "up",
      copyWidgetName ? "copy" : "move"
    );
  };
  return (
    <>
      <div
        css={outerContainerStyle(isSelected, !!canExpand, theme)}
        onClick={handleClickOnContainer}
        id={`${title}-baseDataItemContainer`}
      >
        <div css={itemContainerStyle(level)}>
          <div css={expendContainerStyle}>
            <span
              css={applyExpandIconStyle(isExpanded, !!canExpand, isSelected)}
              onClick={handleClickOnExpandIcon}
              id="expand-icon"
            >
              <LeftIcon sx={{ fontSize: "12px" }} />
            </span>
            {!!type && level >= 1 && <div css={rectangleStyle} />}
            <div css={titleAndIconContainerStyle}>
              {!!type && (
                <ComponentIcon width="10px" height="10px"/>
              )}

              <span css={titleStyle(theme, selectedComponent[0] == title)}>
                {fakeTitle ?? title}
              </span>
            </div>
          </div>
          <div css={iconContainerStyle} id="action-bar">
            {dataType === "widget" && (
              <div
                style={
                  {
                    // marginLeft: "70px"
                  }
                }
              >
                <span
                  style={{
                    color: theme.palette.text.primary,
                    marginRight: "5px",
                    cursor: "pointer",
                  }}
                  title="Add Down"
                >
                  <ArrowCircleDownIcon
                    onClick={() =>
                      handleAddDown(title, value["$parentNode"] as string)
                    }
                    style={{ width: "12px", height: "12px" }}
                  />
                </span>
                <span
                  style={{
                    color: theme.palette.text.primary,
                    marginRight: "5px",
                    cursor: "pointer",
                  }}
                  title="Add Above"
                >
                  <ArrowCircleUpIcon
                    onClick={() =>
                      handleAddUp(title, value["$parentNode"] as string)
                    }
                    style={{ width: "12px", height: "12px" }}
                  />
                </span>
                <span
                  style={{
                    color:
                      moveWidgetName == title
                        ? theme.palette.text.disabled
                        : theme.palette.text.primary,
                    marginRight: "5px",
                    cursor: moveWidgetName == title ? "none" : "move",
                  }}
                  title="Move"
                >
                  <PanToolIcon
                    onClick={() => handleMoveInit(title)}
                    style={{ width: "12px", height: "12px" }}
                  />
                </span>
                <span
                  style={{
                    color:
                      copyWidgetName == title
                        ? theme.palette.text.disabled
                        : theme.palette.text.primary,
                    cursor: copyWidgetName == title ? "none" : "copy",
                  }}
                  title="Copy"
                >
                  <ContentCopyIcon
                    onClick={() => handleCopyInit(title)}
                    style={{ width: "12px", height: "12px" }}
                  />
                </span>
              </div>
            )}
            {haveMoreAction && (
              <span title="Copy">
                <MoreAction displayName={title} actionType={dataType} />
              </span>
            )}
          </div>
        </div>
      </div>

      {dataType === "widget" && Array.isArray(value.$childrenNode) && (
        <AnimatePresence>
          {isExpanded && (
            <motion.div
              css={itemContentStyle}
              variants={panelBarItemContainerAnimationVariants}
              animate={isExpanded ? "enter" : "exit"}
              transition={{ duration: 0.2 }}
              exit="exit"
            >
              {value.$childrenNode.map((item, index) => {
                if (value.$widgetType === "CONTAINER_WIDGET") {
                  return (
                    <BaseDataItem
                      key={item.displayName}
                      title={item.displayName}
                      fakeTitle={
                        (value.viewList as ViewItemShape[])[index].label
                      }
                      value={item}
                      level={level + 1}
                      dataType="widget"
                      type={item.$widgetType as string}
                      canExpand={item.$childrenNode.length > 0}
                      haveMoreAction={item.$widgetType.endsWith("_WIDGET")}
                      selectedDisplayNames={selectedDisplayNames}
                      onClick={onClick}
                    />
                  );
                }
                if (
                  value.$widgetType === "MODAL_WIDGET" ||
                  value.$widgetType === "FORM_WIDGET"
                ) {
                  return (
                    <BaseDataItem
                      key={item.displayName}
                      title={item.displayName}
                      fakeTitle={formatModalTitle(index)}
                      value={item}
                      level={level + 1}
                      dataType="widget"
                      type={item.$widgetType as string}
                      canExpand={item.$childrenNode.length > 0}
                      haveMoreAction={item.$widgetType.endsWith("_WIDGET")}
                      selectedDisplayNames={selectedDisplayNames}
                      onClick={onClick}
                    />
                  );
                }
                if (
                  value.$widgetType === "LIST_WIDGET" ||
                  value.$widgetType === "GRID_LIST_WIDGET"
                )
                  return (
                    <BaseDataItem
                      key={item.displayName}
                      title={item.displayName}
                      fakeTitle="list template"
                      value={item}
                      level={level + 1}
                      dataType="widget"
                      type={item.$widgetType as string}
                      canExpand={item.$childrenNode.length > 0}
                      haveMoreAction={item.$widgetType.endsWith("_WIDGET")}
                      selectedDisplayNames={selectedDisplayNames}
                      onClick={onClick}
                    />
                  );

                return (
                  <BaseDataItem
                    key={item.displayName}
                    title={item.displayName}
                    value={item}
                    level={level + 1}
                    dataType="widget"
                    type={item.$widgetType as string}
                    canExpand={item.$childrenNode.length > 0}
                    haveMoreAction={item.$widgetType.endsWith("_WIDGET")}
                    selectedDisplayNames={selectedDisplayNames}
                    onClick={onClick}
                  />
                );
              })}
            </motion.div>
          )}
        </AnimatePresence>
      )}
      {isOpenCodeModal && (
        <MovableModal
          title={title}
          bodyContent={
            <div css={modalBodyContainerStyle}>
              {Object.keys(value)
                .filter((key) => !key.startsWith("$"))
                .map((key) => {
                  return (
                    <WorkSpaceTreeNode
                      key={key}
                      name={key}
                      value={value[key]}
                      itemKey={key}
                      level={0}
                      parentKey={title}
                    />
                  );
                })}
            </div>
          }
          onClose={() => {
            setIsOpenCodeModal(false);
          }}
          // docLink={getDocLink(dataType, type)}
          defaultPosition={{
            x:
              document
                .querySelector(`#${title}-baseDataItemContainer`)
                ?.getBoundingClientRect().right ?? 0,
            y:
              document
                .querySelector(`#${title}-baseDataItemContainer`)
                ?.getBoundingClientRect().top ?? 0,
            width: 320,
            height: 214,
          }}
        />
      )}
    </>
  );
};
