import { iDocBaseData } from '../../docBase/docBase.type';
import * as docBaseUtils from '../../docBase/docBase.utils';
import { docTagActions } from '../../docTag/docTag.operator';
import { iDocTagData } from '../../docTag/docTag.type';
import { iDocumentState } from '../../document.type';
import * as docTranslateActions from './docTextPolish.actions';

import { delay } from '../../../utils/delay.util';
import { iDocTextPolishData } from '../docTextPolish.type';
import { docTextPolishToLocalDataTransfer } from './docTextPolish.dataTransfer';

const INTERVAL_SHORT_TIME = 50; // 轮询短时间

// DocTranslate Effects
export const docTextPolishEffects = {
  /** 对外 Action */
  // 初始化 DocTextPolish
  *initDocTextPolishDataEffect(
    action: ReturnType<typeof docTranslateActions.initDocTextPolishDataAction>,
    { take, select, put },
  ) {
    const { docId, docScene } = action.payload;
    // 1. 获取 Doc 基础数据
    const { docBaseData }: { docBaseData: iDocBaseData } = yield select(
      (state: { documentModel: iDocumentState }) => ({
        docBaseData: state.documentModel.docBaseDataMap[docId],
      }),
    );
    // 2. docTag 数据(并发请求，不一定更新完成)
    let { docTagData }: { docTagData?: iDocTagData } = yield select(
      (state: { documentModel: iDocumentState }) => ({
        docTagData: state.documentModel.docTagDataMap[docId],
      }),
    );
    if (docTagData === undefined) {
      // 确保 DocTag 返回数据
      yield (function* () {
        while (true) {
          yield take(docTagActions.updateDocTagDataAction(null as any).type);
          docTagData = yield select(
            (state: { documentModel: iDocumentState }) =>
              state.documentModel.docTagDataMap[docId],
          );
          if (docTagData) return docTagData;
          yield delay(INTERVAL_SHORT_TIME);
        }
      })();
    }
    // 组合AI改写数据
    const docBaseTagData = docBaseUtils.getDocBaseTag(docBaseData);
    const { textPolishSwitch, textPolishLanguageConf } = docBaseTagData!;

    const docTextPolishData: iDocTextPolishData = {
      textPolishSwitch: textPolishSwitch || 0,
      textPolishLanguageConf: textPolishLanguageConf || 1,
      textPolishedDoc: {},
      textPolishIsLoading: false,
    };
    // 更新AI原文改写数据
    yield put(
      docTranslateActions.updateDocTextPolishDataAction({
        docId,
        docScene,
        data: docTextPolishData,
      }),
    );
    // 若是开启状态,获取值
    if (textPolishSwitch === 1)
      yield put(
        docTranslateActions.changeTextPolishSwitchAction({
          docId,
          docScene,
          data: textPolishSwitch,
        }),
      );
  },

  /** 更改显示模式 */
  *changeTextPolishSwitchEffect(
    action: ReturnType<typeof docTranslateActions.changeTextPolishSwitchAction>,
    { call, put, select },
  ) {
    const { docId, docScene, data: textPolishSwitch } = action.payload;
    if (textPolishSwitch === 0) {
      // 关闭
      yield put(
        docTranslateActions.updateDocTextPolishPartialDataAction({
          docId,
          docScene,
          data: { textPolishIsLoading: false, textPolishSwitch },
        }),
      );
      yield put(
        docTagActions.updateDocTagAndSyncTagAction({
          docId,
          docScene,
          data: { textPolishSwitch },
        }),
      );
      return true;
    } else if (textPolishSwitch === 1) {
      const { docResult }: { docResult: iDocBaseData } = yield select(
        (state: { documentModel: iDocumentState }) => ({
          docResult: state.documentModel.docBaseDataMap[docId],
        }),
      );
      // 开启获取
      yield put(
        docTranslateActions.updateDocTextPolishPartialDataAction({
          docId,
          docScene,
          data: {
            textPolishIsLoading: false,
            textPolishSwitch,
            textPolishedDoc: docTextPolishToLocalDataTransfer(
              docResult.textPolishedDoc,
            ),
          },
        }),
      );
      yield put(
        docTagActions.updateDocTagAndSyncTagAction({
          docId,
          docScene,
          data: { textPolishSwitch },
        }),
      );
    }
    return null;
  },
};
