import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { produce } from "immer";
import { AnimatePresence, motion } from "motion/react";
import { useContext, useEffect, useState } from "react";
import bg7 from "~/assets/images/map_bi/bottom_utils/bg7.png";
import bg8 from "~/assets/images/map_bi/bottom_utils/bg8.png";
import titleImg from "~/assets/images/map_bi/bottom_utils/title.png";
import titleOnImg from "~/assets/images/map_bi/bottom_utils/title_on.png";
import { NS_BI_MARK } from "~/enumerate/namespace";
import { branchOfficeUtilsList } from "~/pages/Container/Map/components/BottomUtils/branchOfficeUtilsList";
import { Context } from "~/pages/Container/Map/js/context";
import { portUtilsList } from "./portUtilsList";
import { usePortUtilsAnimation } from "./usePortUtilsAnimation";
import "./index.less";

const dangerWorkTypes = [
  "hot_work",
  "confinedspace_work",
  "electricity_work",
  "high_work",
  "cutroad_work",
  "breakground_work",
  "hoisting_work",
  "blindboard_work",
];

const bottomUtilsAnimation = {
  initial: { y: 100, opacity: 0 },
  animate: { y: 0, opacity: 1, transition: { duration: 0.5, ease: "easeOut" } },
  exit: { y: 100, opacity: 0, transition: { duration: 0.3, ease: "easeIn" } },
};

// 分公司子项按顺序进入、反向退出，波浪式效果。
const branchOfficeContainerAnimation = {
  hidden: {
    y: 200,
    opacity: 0,
    transition: { duration: 0.2, ease: "easeIn", staggerChildren: 0.03, staggerDirection: -1 },
  },
  visible: {
    y: 0,
    opacity: 1,
    transition: { duration: 0.3, ease: "easeOut", staggerChildren: 0.05, staggerDirection: 1 },
  },
};

const branchOfficeItemAnimation = {
  hidden: { y: 50, opacity: 0 },
  visible: { y: 0, opacity: 1, transition: { duration: 0.3, ease: "easeOut" } },
};

function BottomUtils(props) {
  const {
    mapMethods,
    currentPort,
    pureMap,
    currentBranchOffice,
    bottomUtilsCurrentIndex,
    bottomUtilsResetVersion,
    actions,
    portArea,
  } = useContext(Context);

  const bottomUtilsMode = !pureMap && currentPort && !currentBranchOffice
    ? "port"
    : !pureMap && currentPort && currentBranchOffice ? "branchOffice" : null;
  const [list, setList] = useState(() => bottomUtilsMode === "port"
    ? portUtilsList
    : bottomUtilsMode === "branchOffice" ? branchOfficeUtilsList : []);
  const [listMode, setListMode] = useState(bottomUtilsMode);

  const {
    parentControls: portUtilsParentControls,
    childControls: portUtilsChildControls,
    optionRefs: portUtilsOptionRefs,
    isAnimating: portUtilsIsAnimating,
    hasInteracted: portUtilsHasInteracted,
    shouldHideInactive: portUtilsShouldHideInactive,
    animationConfig: portUtilsAnimationConfig,
  } = usePortUtilsAnimation(
    portUtilsList.length,
    bottomUtilsCurrentIndex,
    bottomUtilsMode === "port",
  );

  const resetAllCheck = () => {
    setList(produce((draft) => {
      draft.forEach((item) => {
        item.list.forEach((item1) => {
          item1.check = false;
        });
      });
    }));
  };

  useEffect(() => {
    if (bottomUtilsMode === "port") {
      setList(portUtilsList);
    }
    else if (bottomUtilsMode === "branchOffice") {
      setList(branchOfficeUtilsList);
    }
    else {
      setList([]);
    }
    setListMode(bottomUtilsMode);
  }, [bottomUtilsMode]);

  useEffect(() => {
    resetAllCheck();
  }, [bottomUtilsResetVersion]);

  const optionsClick = (index) => {
    actions.setBottomUtilsIndex(bottomUtilsCurrentIndex === index ? -1 : index);
  };

  const optionsItemsClick = async (index, index1, item, item1) => {
    const check = !list[index].list[index1].check;
    if (check) {
      if (item1.request) {
        let pointData = [];
        const requestParams = { portArea, corpinfoId: currentBranchOffice, pageIndex: 1, pageSize: 9999 };
        if (dangerWorkTypes.includes(item1.type)) {
          requestParams.workType = item1.type;
        }
        const { data = [] } = await props[item1.request](requestParams);
        pointData = [...data];
        if (dangerWorkTypes.includes(item1.type)) {
          for (let i = 0; i < pointData.length; i++) {
            pointData[i].latitude = pointData[i].info.latitude;
            pointData[i].longitude = pointData[i].info.longitude;
          }
        }
        if (["platCamera", "video"].includes(item1.type)) {
          pointData = [];
          for (let i = 0; i < data.length; i++) {
            pointData.push(...data[i].fixedCameraCOList);
          }
        }
        mapMethods.current.addMarkPoint(pointData, {
          markType: item1.type,
          markIcon: item1.markIcon,
          subLabel: item1.label,
          titleKey: item1.titleKey,
          isShowModal: item1.isShowModal,
        });
      }
    }
    else {
      mapMethods.current.removeMarkPoint(item1.type);
    }
    setList(produce((draft) => {
      draft[index].list[index1].check = check;
    }));
  };

  const renderPortUtils = () => {
    if (bottomUtilsMode === "port" && listMode === bottomUtilsMode) {
      return list.map((item, index) => {
        const isCurrentActive = bottomUtilsCurrentIndex === index;
        const hasActiveChildren = bottomUtilsCurrentIndex !== -1;
        const isAllowClick = hasActiveChildren && !isCurrentActive && portUtilsShouldHideInactive;

        return (
          <motion.div
            key={index}
            ref={el => (portUtilsOptionRefs.current[index] = el)}
            className="option"
            animate={portUtilsHasInteracted ? portUtilsParentControls[index] : false}
            onClick={() => !portUtilsIsAnimating && !isAllowClick && optionsClick(index)}
            style={{
              cursor: isAllowClick ? "default" : "pointer",
              zIndex: isAllowClick ? -1 : 0,
            }}
          >
            <img src={isCurrentActive ? item.checkImg : item.img} alt="" className="img" />
            <div className="label" style={{ backgroundImage: `url(${isCurrentActive ? titleOnImg : titleImg})` }}>
              {item.label}
            </div>
            {isCurrentActive && (
              <motion.div
                className="child_items"
                animate={portUtilsChildControls}
                initial={{ opacity: 0 }}
              >
                {item.list?.map((item1, index1) => {
                  return (
                    <motion.div
                      key={index1}
                      className="child_item"
                      initial={{ opacity: 0 }}
                      animate={{ opacity: 1 }}
                      transition={{ delay: index1 * portUtilsAnimationConfig.staggerDelay }}
                      onClick={(e) => {
                        e.stopPropagation();
                        optionsItemsClick(index, index1, item, item1);
                      }}
                    >
                      <img src={item1.check ? item1.checkImg : item1.img} alt="" className="child_img" />
                      <div className="child_label">{item1.label}</div>
                    </motion.div>
                  );
                })}
              </motion.div>
            )}
          </motion.div>
        );
      });
    }
  };

  const renderBranchOfficeUtils = () => {
    if (bottomUtilsMode === "branchOffice" && listMode === bottomUtilsMode) {
      return (
        list.map((item, index) => {
          const isCurrentActive = bottomUtilsCurrentIndex === index;
          return (
            <div
              key={index}
              className="option"
              style={{ backgroundImage: `url(${isCurrentActive ? bg7 : bg8})` }}
              onClick={() => optionsClick(index)}
            >
              <div className="label">{item.label}</div>
              <AnimatePresence>
                {(isCurrentActive && item.list?.length > 0) && (
                  <motion.div
                    className="items"
                    initial="hidden"
                    animate="visible"
                    exit="hidden"
                    variants={branchOfficeContainerAnimation}
                  >
                    {item.list?.map((item1, index1) => {
                      return (
                        <motion.div
                          key={index1}
                          className={`item ${item1.check ? "active" : ""}`}
                          onClick={(e) => {
                            e.stopPropagation();
                            optionsItemsClick(index, index1, item, item1);
                          }}
                          variants={branchOfficeItemAnimation}
                        >
                          <div className="child_label">{item1.label}</div>
                        </motion.div>
                      );
                    })}
                  </motion.div>
                )}
              </AnimatePresence>
            </div>
          );
        })
      );
    }
  };

  return (
    <div className="map_content_bottom_utils_container">
      <AnimatePresence mode="wait">
        {bottomUtilsMode && (
          <motion.div
            key={bottomUtilsMode}
            className={bottomUtilsMode === "port" ? "bottom_utils port" : "bottom_utils branch_office"}
            {...bottomUtilsAnimation}
          >
            {renderPortUtils()}
            {renderBranchOfficeUtils()}
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}

export default Connect([NS_BI_MARK], true)(BottomUtils);
