import React, { useCallback, useMemo, useRef, useState } from "react";
import {
  Dropdown,
  Menu,
  MenuItem,
  MenuItemIcon,
  MenuItemText,
  DROPDOWN_WIDTH,
  DROPDOWN_ONE_ITEM_HEIGHT,
  DROPDOWN_PADDING,
} from "./styled";
import { generateTranscriptionController, useTranscriptionHooks } from "../../controller";
import { Controller } from "@tingwu/core";
import { getDropdownPosition } from "../../utils";
import { useSyncEffect } from "@tingwu/common";
import { TYIcon } from "@tingwu/design";

interface TranslateMenuProps {
  controller: Controller;
}

export const TranslateMenu: React.FC<TranslateMenuProps> = props => {
  const { controller } = props;
  const tranController = generateTranscriptionController(controller);
  const isLivingMode = controller.getLivingMode();
  const [isShowUp, setIsShowUp] = useState(false);
  const showUpTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
  const dropdownRef = useRef<HTMLDivElement>(null);
  const selectPidRef = useRef("");
  const selectSidRef = useRef("");
  const selectContentRef = useRef("");

  const stateRef = useRef<{
    holdNextHide: boolean;
  }>({
    holdNextHide: false,
  });

  useSyncEffect(() => {
    return controller.on("addFixParagraph", () => {
      setIsShowUp(false);
    });
  }, [controller]);

  const [calcStyle, setCalcStyle] = useState<React.CSSProperties>({});
  const { getTranscriptionContainer, getTranscriptionDocument } = useTranscriptionHooks(
    controller,
    ["getTranscriptionContainer", "getTranscriptionDocument"]
  );

  const getUnfixHeight = useCallback(() => {
    const unfixElement = tranController.getUnfixElement();
    if (!unfixElement) {
      return 0;
    }

    return unfixElement.getBoundingClientRect().height;
  }, [tranController]);

  useSyncEffect(() => {
    return tranController.on(
      "onTranslateMenuShowUp",
      ({ clientX, clientY, rangeRect, isUnfix, startOffset, endOffset, content, pid, sid }) => {
        selectPidRef.current = pid || "";
        selectSidRef.current = sid || "";

        selectContentRef.current = content.slice(startOffset, endOffset);
        clearTimeout(showUpTimeoutRef.current);
        showUpTimeoutRef.current = setTimeout(() => {
          if (getTranscriptionContainer && getTranscriptionDocument) {
            const tranContainer = getTranscriptionContainer();
            const documentContainer = getTranscriptionDocument();
            const contextMenuSize = {
              width: DROPDOWN_WIDTH,
              height: DROPDOWN_ONE_ITEM_HEIGHT,
            };
            // todo: 应去除unfix区的高度
            setCalcStyle(
              getDropdownPosition(
                clientX,
                clientY,
                rangeRect,
                tranContainer,
                documentContainer,
                contextMenuSize.width,
                contextMenuSize.height,
                DROPDOWN_PADDING,
                !isUnfix,
                getUnfixHeight()
              )
            );
          } else {
            setCalcStyle({
              top: clientY,
              left: clientX + DROPDOWN_PADDING,
            });
          }
          setIsShowUp(true);
        }, 150);
      }
    );
  }, [getTranscriptionContainer, tranController, getUnfixHeight, isLivingMode]);

  useSyncEffect(() => {
    return tranController.on("onTranslateMenuHideOff", () => {
      if (stateRef.current.holdNextHide) {
        stateRef.current.holdNextHide = false;
      } else {
        setTimeout(() => {
          setIsShowUp(false);
        }, 200);
      }
    });
  }, [tranController]);

  const generatedStyle = useMemo(() => {
    return {
      ...calcStyle,
      display: isShowUp ? "block" : "none",
    };
  }, [calcStyle, isShowUp]);

  const handleExtraContents = useCallback(() => {
    if (selectContentRef.current) {
      controller.extraContent(
        [selectContentRef.current],
        "translate",
        selectPidRef.current,
        selectSidRef.current
      );
    }
  }, [controller]);

  const originMenu = (
    <Menu>
      <MenuItem onClick={handleExtraContents}>
        <MenuItemIcon>
          <TYIcon
            type={"extend-extract-line"}
            style={{ color: "var(--Text_Primary)", fontSize: 20 }}
          />
        </MenuItemIcon>
        <MenuItemText>一键摘取</MenuItemText>
      </MenuItem>
    </Menu>
  );

  return (
    <Dropdown ref={dropdownRef} style={generatedStyle}>
      {originMenu}
    </Dropdown>
  );
};
