import { Controller, OldSelection, PID } from "@tingwu/core";
import React, { useCallback, useEffect, useRef, useMemo, useState } from "react";
import {
  ViewedWord,
  generateViewedWordDiff,
  generateViewedWords,
  isReadonlyState,
} from "../../../model";
import { updateAllWords } from "../../../utils";
import { getTranscriptionController } from "../../../controller";
import { ParagraphTranslate, FixText, TextPolishTagHide } from "./styled";
import { getFirstRange, useSyncEffect } from "@tingwu/common";
import { useRecoilValue } from "recoil";
import { AssistantActiveType, QnAController } from "@tingwu/sphere";

interface TextPolishContentProps {
  controller: Controller; // 控制器
  pid?: PID; // 段落ID
  textPolishSelections?: OldSelection[]; // 改写的段落
  activeFoundSelection?: OldSelection; // 搜索到的段落
  showOrigin?: boolean; // 是否展示原文
  isHighlight?: boolean; // 是否高亮
  aiReviewActive?: AssistantActiveType | null; // 是否开启智能审核
  qaController?: QnAController;
}
// 原文改写图片
// const textPolishIconSrc = [
//   'https://img.alicdn.com/imgextra/i1/O1CN01OnGoNt1P0N7uFm957_!!6000000001778-2-tps-72-72.png',
//   'https://img.alicdn.com/imgextra/i2/O1CN01xu6eUY1doCqJJ8PBl_!!6000000003782-2-tps-72-72.png',
// ];

const doNothing = (id: number) => id;

export const TextPolishContent: React.FC<TextPolishContentProps> = props => {
  const {
    controller,
    pid,
    aiReviewActive,
    showOrigin = false,
    isHighlight = false,
    activeFoundSelection,
    textPolishSelections,
    qaController,
  } = props;

  const transController = getTranscriptionController(controller); // 段落控制器
  const isReadonly = useRecoilValue(isReadonlyState); // 仅读状态

  const stateRef = useRef<{
    lastActiveWord: ViewedWord | undefined;
  }>({
    lastActiveWord: undefined,
  });
  const containerRef = useRef<HTMLDivElement>(null);
  const fixedRef = useRef<HTMLDivElement>(null);
  const [updateId, setUpdateId] = useState(0);

  const getRange = (
    callback: (range: { range: Range; startOffset: number; endOffset: number }) => void,
    fallback?: () => void,
    debug?: string
  ) => {
    if (!containerRef.current) {
      return;
    }

    const range = getFirstRange(containerRef.current);
    if (!range) {
      console.log("No range found", debug);
      fallback && fallback();
      return;
    }

    callback(range);
  };

  const viewedWords: ViewedWord[] = useMemo(() => {
    doNothing(updateId);
    if (!pid) return [];
    const textPolish = controller.getTextPolish(pid);
    if (!textPolish) return [];
    return generateViewedWords(
      [
        {
          wid: "",
          sentenceId: String(textPolish.textPolishResult.sentence_ids[0]),
          beginTime: textPolish.textPolishResult.st,
          endTime: textPolish.textPolishResult.et,
          text: textPolish.textPolishResult.formal_paragraph,
          tag: "",
        },
      ],
      textPolishSelections,
      activeFoundSelection
    );
  }, [activeFoundSelection, controller, pid, textPolishSelections, updateId]);

  useEffect(() => {
    const { length } = viewedWords;
    if (!pid || length === 0) {
      return;
    }
    viewedWords.some((viewedWord, index) => {
      if (viewedWord.searchedOffsets) {
        const found = viewedWord.searchedOffsets.find(offset => offset.isActive);
        if (found) {
          const { lastActiveWord } = stateRef.current || {};
          if (!lastActiveWord || lastActiveWord.wid !== viewedWord.wid) {
            stateRef.current.lastActiveWord = viewedWord;
            transController.emitAsync("onDisplayWordShowUp", {
              pid,
              word: viewedWord,
            });
          }
          return true;
        }
      }
      if (index === length - 1) {
        stateRef.current.lastActiveWord = undefined;
      }
      return false;
    });
  }, [viewedWords, pid, transController]);

  const allContent = useMemo(() => {
    return viewedWords.map(word => word.text).join("");
  }, [viewedWords]);

  const isEmptyContent = viewedWords.length === 0;

  const viewedWordDiff = useMemo(() => {
    return generateViewedWordDiff();
  }, []);

  // 改写更新后替换文案
  useEffect(() => {
    if (!fixedRef.current || isEmptyContent) {
      return;
    }
    updateAllWords(fixedRef.current, viewedWords);
  }, [viewedWords, isEmptyContent, viewedWordDiff]);

  // 改写数据更新监听
  useSyncEffect(() => {
    return controller.on("fixParagraphTextPolishChange", ({ pid: _pid }) => {
      if (_pid === pid) {
        setUpdateId(prev => prev + 1);
      }
    });
  }, [controller, pid]);

  /** 交互事件处理 */

  /** 阻止默认事件 */
  const preventDefault = useCallback(
    (event: React.ClipboardEvent | React.FocusEvent | React.DragEvent) => {
      event.preventDefault();
    },
    []
  );
  /** 鼠标弹起事件 */
  const handleMouseUp = useCallback(() => {}, []);

  /** 输入编辑事件处理 */
  const handleComposition = useCallback((event: React.CompositionEvent<HTMLDivElement>) => {
    event.preventDefault();
    containerRef.current?.blur();
  }, []);

  /** 输入按下事件 */
  const handleKeyDown = useCallback((event: React.KeyboardEvent) => {
    if (!event.metaKey && !event.ctrlKey) {
      event.preventDefault();
    }
  }, []);

  /** 输入事件 */
  const handleInput = useCallback((event: React.SyntheticEvent<HTMLDivElement, InputEvent>) => {
    event.preventDefault();
  }, []);

  const handleMouseDown = useCallback(() => {
    qaController?.setActiveQnaIndex(-1);
  }, [qaController]);

  /** 划选事件: 展示标记或者隐藏标记 */
  const handleSelect = useCallback(
    (event: React.SyntheticEvent<HTMLDivElement>) => {
      const { clientX, clientY, type } = event.nativeEvent as MouseEvent;
      if (!transController.getIsShowTranslatePopup()) {
        return;
      }

      getRange(
        ({ startOffset, endOffset, range }) => {
          if (startOffset !== endOffset) {
            const rangeRect = range.getBoundingClientRect();
            if (type === "mouseup") {
              // setTimeout(() => {
              //   transController.emit('onTranslateMenuShowUp', {
              //     clientX,
              //     clientY,
              //     rangeRect,
              //     isUnfix: true,
              //     pid,
              //     startOffset,
              //     endOffset,
              //     content: allContent,
              //   });
              // }, 100);
            }
          } else {
            transController.emit("onTranslateMenuHideOff", {});
          }
        },
        () => {}
      );
    },
    [pid, transController, allContent]
  );

  /** 失焦事件 */
  const handleBlur = useCallback(() => {
    transController.emit("onTranslateMenuHideOff", {});
  }, [transController]);

  // 空内容
  if (isEmptyContent) return null;
  // 非空内容
  return (
    <div style={{ position: "relative", width: "100%" }}>
      <ParagraphTranslate
        className={`${!props.showOrigin ? "tingwu2_paragraphTranslate_showOrigin" : "tingwu2_paragraphTranslate"}`}
        contentEditable={!isReadonly}
        onMouseDown={handleMouseDown}
        onMouseUp={handleMouseUp}
        onFocus={preventDefault}
        onBlur={handleBlur}
        onInput={handleInput}
        onCompositionStart={handleComposition}
        onCompositionEnd={handleComposition}
        onCut={preventDefault}
        onPaste={preventDefault}
        onDrop={preventDefault}
        onKeyDown={handleKeyDown}
        onSelect={handleSelect}
        showOrigin={showOrigin}
        isHighlight={isHighlight}
        isUnfix={false}
        spellCheck={false}
        aiReviewActive={aiReviewActive}
        ref={containerRef}
      >
        <FixText isHighlight={isHighlight} ref={fixedRef} />
        {/* <TextPolishTagHide /> */}
      </ParagraphTranslate>
    </div>
  );
};
