import { iDocumentState } from '../../document.type';
import { getDefaultDocPlayerData, iDocPlayerData } from '../docPlayer.types';

import { iDocBaseData } from '../../docBase/docBase.type';
import * as docBaseUtils from '../../docBase/docBase.utils';
import { iDocTagData } from '../../docTag/docTag.type';

import { docTagActions } from '../../docTag/docTag.operator';
import * as docPlayerActions from './docPlayer.actions';
// *** 工具相关 ***
import { delay } from '../../../utils/delay.util';

// DocPlayer Effects
export const docPlayerEffects = {
  // 初始化播放器数据
  *initDocPlayerDataEffect(
    action: ReturnType<typeof docPlayerActions.initDocPlayerDataAction>,
    { take, call, 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],
      }),
    );

    // todo @rdm  未登录情况不存在docTagData Model层 缺少是否登录标识 待与@songsong 确认如何调整
    // 非登录情况下，返回的是默认 Tag（或者从TransResult 来的 Tag）
    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 call(delay, 50);
        }
      })();
    }

    // 4. 组合播放器数据
    let basePlayerData = getDefaultDocPlayerData()!;
    // 基础数据
    const {
      isVideo,
      videoUrl,
      videoPoster,
      audioUrl,
      audioSegments,
      audioSpectrum,
    } = docBaseUtils.getDocPlayerData(docBaseData, docScene);

    // Tag 数据
    const { mediaTag } = docTagData || {};

    basePlayerData = {
      ...basePlayerData,
      playerMode: isVideo ? 'video' : 'audio',
      docIsVideo: isVideo,
      videoUrl,
      videoPoster,
      audioUrl,
      audioSegments,
      audioSpectrum,
      // tag同步
      skipBlankSegment: !!mediaTag?.skipBlank,
      showSubtitle: !!mediaTag?.subtitle,
      showSubtitleSpeaker: !!mediaTag?.subtitleSpeaker,
      subtitlesModel: mediaTag?.subtitlesModel || 'dark',
      // 播放器状态记录
      playerRecordTime: 0,
      // playerRecordTime: playerTimeRecord,
    };
    // 更新播放器数据
    yield put(
      docPlayerActions.updateDocPlayerDataAction({
        docId,
        docScene,
        data: basePlayerData,
      }),
    );
  },
  // 更新播放器状态
  *updateDocPlayerStatusEffect(
    action: ReturnType<typeof docPlayerActions.changeDocPlayerStatusAction>,
    { put, fork, select },
  ) {
    const { docId, docScene } = action.payload;
    const docPlayerUpdateData = action.payload.data!;

    // Tag业务状态同步服务端
    const syncToMediaTagStatus: Record<string, any> = {};
    const checkTagKeys = [
      'showSubtitle',
      'showSubtitleSpeaker',
      'skipBlankSegment',
      'subtitlesModel',
    ];
    Object.keys(docPlayerUpdateData).forEach((key) => {
      if (checkTagKeys.includes(key)) {
        syncToMediaTagStatus[key] = docPlayerUpdateData[key];
      }
    });
    // 需要同步 Tag 变更
    if (Object.keys(syncToMediaTagStatus).length) {
      // 1. 已有数据获取其他字段补充
      const { docPlayerData }: { docPlayerData: iDocPlayerData } = yield select(
        (state: { documentModel: iDocumentState }) => ({
          docPlayerData: state.documentModel.docPlayerDataMap[docId],
        }),
      );
      const mediaTag = {
        subtitle: docPlayerData.showSubtitle,
        subtitleSpeaker: docPlayerData.showSubtitleSpeaker,
        skipBlank: docPlayerData.skipBlankSegment,
        subtitlesModel: docPlayerData.subtitlesModel,
      };

      // 2. 数据更新，判断是否需要同步
      let shouldSyncState = false;
      if (
        syncToMediaTagStatus.showSubtitle !== undefined &&
        mediaTag.subtitle !== syncToMediaTagStatus.showSubtitle
      ) {
        mediaTag.subtitle = syncToMediaTagStatus.showSubtitle;
        shouldSyncState = true;
      }

      if (
        syncToMediaTagStatus.showSubtitleSpeaker !== undefined &&
        mediaTag.subtitleSpeaker !== syncToMediaTagStatus.showSubtitleSpeaker
      ) {
        mediaTag.subtitleSpeaker = syncToMediaTagStatus.showSubtitleSpeaker;
        shouldSyncState = true;
      }

      if (
        syncToMediaTagStatus.subtitlesModel !== undefined &&
        mediaTag.subtitlesModel !== syncToMediaTagStatus.subtitlesModel
      ) {
        mediaTag.subtitlesModel = syncToMediaTagStatus.subtitlesModel;
        shouldSyncState = true;
      }

      if (
        syncToMediaTagStatus.skipBlankSegment !== undefined &&
        mediaTag.skipBlank !== syncToMediaTagStatus.skipBlankSegment
      ) {
        mediaTag.skipBlank = syncToMediaTagStatus.skipBlankSegment;
        shouldSyncState = true;
      }

      if (shouldSyncState) {
        yield fork(
          put,
          docTagActions.updateDocTagAndSyncTagAction({
            docId,
            docScene,
            data: {
              mediaTag,
            },
          }),
        );
      }
    }

    // 更新播放器数据
    yield put(
      docPlayerActions.updateDocPlayerDataAction({
        docId,
        docScene,
        data: docPlayerUpdateData,
      }),
    );
  },
};
