import { useCallback, useEffect } from 'react';
import { atom, useRecoilValue, useSetRecoilState } from 'recoil';

import { Word } from '@tingwujs/core';

import { docBaseHooks, modelUtils } from '../../../../../documentModel';

import { markColors } from '../../../../../pages/docASR/utils/config';

import { useDataHooks } from '../../../../../pages/docASR/components/businessCommon/separateHooks/dataShare';

// 标记
export interface iVideoMark {
  startTime: number;
  endTime: number;
  color: string;
  text: string;
}
// 标记类型
type tMediaMarkToken = iVideoMark;

// 公用 MarkToken 数据
const makeTokenRecoilState = atom<tMediaMarkToken[]>({
  key: 'media_MarkToken',
  default: [],
});

// 标记数据计算
export const transformTokens = (markedContinuousWords: Word[][]) => {
  const marks: tMediaMarkToken[] = markedContinuousWords.map((item) => {
    const _item: tMediaMarkToken = {
      startTime: 0,
      endTime: 0,
      color: 'blue',
      text: '',
    };
    for (let index = 0; index < item.length; index++) {
      if (index === 0) {
        _item.startTime = item[index].beginTime / 1000;
        _item.color =
          (markColors &&
            markColors.find((i) => i.type === item[index].tag)?.color) ||
          '#fff';
      }
      _item.text += item[index].text;
      if (index === item.length - 1) {
        _item.endTime = item[index].endTime / 1000;
      }
    }
    return _item;
  });
  return marks;
};

// 获取播放器标记数据
export const useMediaMarkTokens = () => {
  const { controller } = useDataHooks();
  const { docBaseData } = docBaseHooks.useDocBaseData();

  const markTokens = useRecoilValue(makeTokenRecoilState);
  const setMarkToken = useSetRecoilState(makeTokenRecoilState);

  // 计算标记数据
  const computeMarkToken = useCallback(() => {
    if (!controller) return;

    const blueResult = controller.getMarkedContinuousWords('blue');
    const radResult = controller.getMarkedContinuousWords('red');
    const yellowResult = controller.getMarkedContinuousWords('yellow');
    const tokens = blueResult.concat(radResult).concat(yellowResult);
    // 数据转为标记
    const _markTokens = transformTokens(tokens);
    setMarkToken(_markTokens);
  }, [controller, setMarkToken]);

  // 原文内容更新后，获取标记数据
  const docTransResult: any =
    modelUtils.getTransResultDataFromDocBase(docBaseData as any) || {};
  useEffect(() => {
    if (!docTransResult?.result || !controller) return;
    // 原文内容更新后，异步获取标记数据
    setTimeout(computeMarkToken, 800);
  }, [controller, docTransResult?.result, computeMarkToken]);

  // 监听标记变更
  useEffect(() => {
    if (!controller) return;
    // 标记变更监听
    controller.on('markWordsChanged', computeMarkToken); // 标记监听
    return () => {
      controller.off('markWordsChanged', computeMarkToken); // 标记监听
    };
  }, [controller, computeMarkToken]);

  return {
    markTokens,
  };
};
