import { Flex } from "antd";
import { Button, message, Modal, Select, Tooltip } from "antd";
import React, {
  useCallback,
  useEffect,
  useImperativeHandle,
  useMemo,
  useRef,
  useState,
} from "react";
import { PlayCircleFill, DownLine, TranslateLang } from "../../Icon";
import { languageOptions, translateLanguageOptions } from "./constance";
import styles from "./index.module.less";
import classnames from "classnames";
import {
  AudioEffectExperience,
  eMicrophonePermissionState,
  UploadFile,
  useMicrophonePermission,
  InfoOutlined,
  useMeetingState,
  iAudioEffectExperienceRef,
  MicLine,
} from "@tingwujs/components";
import { createTaskAPI, APP_ID, getTokens, websocketUrl } from "@tingwujs/service";
import { eTranscriptionStatusType } from "../TranscriptionStatus";
import useMeetingGetTaskStatus from "../../hooks/useMeetingGetTaskStatus";
import { toDetail } from "../../../../utils/metting";
import { FailedMapTable } from "../../../../constant";
import { initErrorInfo } from "../..";
import { TextAnimation } from "../TextAnimation";

export enum eTabsConfigType {
  AUDIO_AND_VIDEO_FILE = "AUDIO_AND_VIDEO_FILE",
  REAL_TIME_RECORDING = "REAL_TIME_RECORDING",
}

export interface iEnterControlPropsType {
  setCurrStatus: (next: eTranscriptionStatusType) => void;
  setErrorInfo: (next: { code: string; message: string; canRetry: boolean }) => void;
}

export interface iEnterControlRefType {
  onTryAgainHandler: () => void;
  onCloseRequest: () => void;
}

export const EnterControl = React.memo(
  React.forwardRef<iEnterControlRefType, iEnterControlPropsType>((props, ref) => {
    const { setCurrStatus, setErrorInfo } = props;
    const [currentTabs, setCurrentTabs] = useState<eTabsConfigType>(
      eTabsConfigType.AUDIO_AND_VIDEO_FILE
    );
    const [tooltipVisible, setTooltipVisible] = useState(false);

    const taskIdRef = useRef<string | null>(null);

    const { runGetTaskStatus, cancel, onReset } = useMeetingGetTaskStatus({
      callback: ({ output }) => {
        if ([2, 3, 0].includes(output?.status)) {
          switch (output?.status) {
            case 3:
              cancel();
              break;
            case 0:
              setCurrStatus(eTranscriptionStatusType.SUCCESS);
              toSuccessDetail();
              break;
            case 2:
              const next =
                FailedMapTable.find(({ code }) => code === output?.errorCode) || initErrorInfo;
              setErrorInfo(next);
              setCurrStatus(eTranscriptionStatusType.ERROR);
            default:
              break;
          }
        }
      },
    });

    const [showAudioEffectExperience, setShowAudioEffectExperience] = useState<boolean>(false);
    const [languageConfig, setLanguageConfig] = useState({
      language: "multilingual",
      translateLanguage: "en",
    });

    const audioEffectExperienceRef = useRef<iAudioEffectExperienceRef>();

    const { store: meetingState, updateStore: updateMeetingState } = useMeetingState();
    const { createTaskOutput } = meetingState;

    const { permission, requestPermission } = useMicrophonePermission();

    const [tempClose, setTempClose] = useState<boolean>(false);

    const isEnabled = useMemo(
      () => permission === eMicrophonePermissionState.GRANTED,
      [permission]
    );

    const onCreateRealtimeTaskHandler = useCallback(async () => {
      try {
        const { language, translateLanguage } = languageConfig;
        const requestParams = {
          input: {
            task: "createTask",
            type: "realtime",
            format: "pcm",
            sampleRate: 16000,
            appId: APP_ID,
          },
          parameters: {
            transcription: {
              model: language,
              diarizationEnabled: true,
              diarizationSpeakerCount: 0,
              translationTargetLang: [translateLanguage],
              translationEnabled: true,
            },
            analysis: {
              actionsEnabled: false,
              autoChapterGranularity: "General",
              autoChapterTitleLengthLevel: "Short",
              autoChaptersEnabled: true,
              conversationalEnabled: true,
              customPromptContent: "",
              customPromptEnabled: false,
              customPromptModel: "tingwu-turbo",
              customPromptTransType: "default",
              fullSummaryEnabled: true,
              fullSummaryFormat: "markdown",
              keyInformationEnabled: true,
              mindMapEnabled: true,
              mindMapFormat: "timestamp",
              model: "default",
              pptExtractionEnabled: true,
              questionsAnsweringEnabled: true,
              textPolishEnabled: false,
            },
          },
        };

        const { output } = await createTaskAPI(requestParams);
        if (output?.dataId) {
          // 获取临时token
          const result = await getTokens();
          if (result?.token) {
            updateMeetingState(draft => {
              draft.createTaskOutput.dataId = output?.dataId;
              draft.createTaskOutput.status = 1;
              draft.createTaskOutput.meetingJoinUrl = `${websocketUrl}?api_key=${result.token}`;
            });
            setShowAudioEffectExperience(true);
            taskIdRef.current = output?.dataId;
            return;
          } else {
            throw new Error("获取token失败");
          }
        }
        throw new Error("创建任务失败");
      } catch (error) {
        message.error("开启录音失败，请稍后重试！");
        console.log(error);
      }
    }, [languageConfig.language, languageConfig.translateLanguage]);

    const toSuccessDetail = () => {
      setTimeout(() => {
        toDetail(taskIdRef.current!);
      }, 1000);
    };

    useEffect(() => {
      if (!showAudioEffectExperience) return;
      if (!audioEffectExperienceRef.current) return;
      setTimeout(() => {
        audioEffectExperienceRef.current?.initAudioHandler();
      }, 200);
    }, [showAudioEffectExperience]);

    const onCreateOnlineTaskHandler = useCallback(
      async (fileUrl: string) => {
        try {
          setCurrStatus(eTranscriptionStatusType.TRANSCRIBING);
          const { output, code } = await createTaskAPI({
            input: {
              task: "createTask",
              type: "offline",
              fileUrl,
              appId: APP_ID,
            },
            parameters: {
              transcription: {
                diarizationEnabled: true,
                diarizationSpeakerCount: 0,
                translationEnabled: false,
              },
              analysis: {
                actionsEnabled: false,
                autoChapterGranularity: "General",
                autoChapterTitleLengthLevel: "Short",
                autoChaptersEnabled: true,
                conversationalEnabled: true,
                customPromptContent: "",
                customPromptEnabled: false,
                customPromptModel: "tingwu-turbo",
                customPromptTransType: "default",
                fullSummaryEnabled: true,
                fullSummaryFormat: "markdown",
                keyInformationEnabled: true,
                mindMapEnabled: true,
                mindMapFormat: "timestamp",
                model: "default",
                pptExtractionEnabled: true,
                questionsAnsweringEnabled: true,
                textPolishEnabled: false,
              },
            },
          });
          if (output?.dataId) {
            taskIdRef.current = output.dataId;
            runGetTaskStatus(output.dataId);
            return;
          }
          const next = FailedMapTable.find(({ code: _code }) => _code === code) || initErrorInfo;
          setErrorInfo(next);
          throw new Error("创建任务失败");
        } catch (error) {
          setCurrStatus(eTranscriptionStatusType.ERROR);
        }
      },
      [runGetTaskStatus]
    );

    const onStartRecordingHandler = useCallback(async () => {
      if (!navigator.onLine) {
        message.error("当前网络异常，请稍后再试");
        return;
      }
      if (!isEnabled) {
        Modal.confirm({
          type: "warning",
          title: "未授权麦克风权限",
          content: "请允许浏览器访问您的麦克风权限，以便完整体验通义听悟实时记录能力。",
          okText: "去授权",
          cancelText: "取消",
          onOk: requestPermission,
        });
        return;
      }
      onCreateRealtimeTaskHandler();
    }, [requestPermission, isEnabled, onCreateRealtimeTaskHandler]);

    const nextFileIdRef = useRef<string | undefined>("");
    useImperativeHandle(
      ref,
      () => ({
        onTryAgainHandler: async () => {
          setCurrStatus(eTranscriptionStatusType.TRANSCRIBING);
          if (currentTabs === eTabsConfigType.REAL_TIME_RECORDING) {
            updateMeetingState(draft => {
              draft.createTaskOutput.status = 1;
            });
            onStartRecordingHandler();
            return;
          }
          if (!nextFileIdRef.current) {
            setCurrStatus(eTranscriptionStatusType.WAITING);
            return;
          }
          updateMeetingState(draft => {
            draft.createTaskOutput.status = 1;
          });
          onReset();
          onCreateOnlineTaskHandler(nextFileIdRef.current);
        },
        onCloseRequest: cancel,
      }),
      [onStartRecordingHandler, onCreateOnlineTaskHandler, cancel, onReset, currentTabs]
    );

    const renderRealTimeRecording = useMemo(() => {
      return (
        <div className={styles.RealTimeRecording}>
          <Flex vertical align="center" className={styles.RealTimeRecording__Content}>
            <div className={styles.RealTimeRecording__Icon}>
              <MicLine width={23} height={23} />
            </div>
            <Flex
              justify="center"
              align="center"
              className={styles.RealTimeRecording__Lang}
              gap={4}
            >
              <Flex
                align="center"
                justify="flex-end"
                className={styles.RealTimeRecording__Lang__Item}
              >
                <div className={styles.RealTimeRecording__Lang__Label}>源语言：</div>
                <Flex gap={4} align="center">
                  <Select
                    rootClassName={styles.OriginLangSelect}
                    value={languageConfig.language}
                    onChange={value => {
                      setLanguageConfig(prev => ({
                        ...prev,
                        language: value,
                      }));
                    }}
                    options={languageOptions.map(({ value, label }) => {
                      if (
                        value ===
                        translateLanguageOptions.find(
                          ({ value: _value }) => _value === languageConfig.translateLanguage
                        )?.value
                      ) {
                        return {
                          value,
                          label,
                          disabled: true,
                        };
                      }
                      return {
                        value,
                        label,
                      };
                    })}
                    variant="borderless"
                    labelRender={item => {
                      if (item.value === "multilingual") {
                        return (
                          <Flex align="center" justify="space-between" gap={4}>
                            <span>{item.label}</span>
                            <Tooltip
                              title="支持中英日韩粤德法俄混合识别"
                              placement="top"
                              open={tooltipVisible}
                            >
                              <span
                                onClick={e => {
                                  e.stopPropagation();
                                  console.log("onClick");
                                }}
                                style={{ cursor: "help" }}
                                onMouseLeave={() => {
                                  setTooltipVisible(false);
                                }}
                                onMouseEnter={() => {
                                  setTooltipVisible(true);
                                }}
                              >
                                <InfoOutlined />
                              </span>
                            </Tooltip>
                          </Flex>
                        );
                      }
                      return item.label;
                    }}
                    suffixIcon={<DownLine />}
                  />
                </Flex>
              </Flex>
              <TranslateLang style={{ color: "rgba(38, 36, 76, 0.45)" }} />
              <Flex
                align="center"
                justify="flex-start"
                className={styles.RealTimeRecording__Lang__Item}
              >
                <div className={styles.RealTimeRecording__Lang__Label}>翻译为：</div>
                <Select
                  options={translateLanguageOptions.map(({ value, label }) => {
                    if (
                      value ===
                      languageOptions.find(
                        ({ value: _value }) => _value === languageConfig.language
                      )?.value
                    ) {
                      return {
                        value,
                        label,
                        disabled: true,
                      };
                    }
                    return {
                      value,
                      label,
                    };
                  })}
                  value={languageConfig.translateLanguage}
                  onChange={value => {
                    setLanguageConfig(prev => ({
                      ...prev,
                      translateLanguage: value,
                    }));
                  }}
                  suffixIcon={<DownLine />}
                  variant="borderless"
                />
              </Flex>
            </Flex>
            <Button
              type="primary"
              className={`${styles.RealTimeRecording__Button}`}
              onClick={onStartRecordingHandler}
              data-autolog="feature=button&exp=true&key=tingwu_exp_start_record_click&text=开始录音"
            >
              <Flex justify="center" align="center" gap={8}>
                <PlayCircleFill />
                开始录音
              </Flex>
            </Button>
          </Flex>
        </div>
      );
    }, [languageConfig, onStartRecordingHandler]);

    const tabsConfig = useMemo(
      () => [
        {
          type: eTabsConfigType.AUDIO_AND_VIDEO_FILE,
          label: "音视频文件",
          dataAutolog: "feature=button&exp=true&key=tingwu_exp_media_file_click&text=音视频文件",
          render: (
            <div
              className={`${styles.UploadFileWrapper} ${
                !navigator.onLine ? styles.UploadFileWrapper__Disabled : ""
              }`}
              data-autolog="feature=button&exp=true&key=tingwu_exp_upload_click&text=上传文件"
            >
              <UploadFile
                fileStatusPosition="cover"
                onConfirmHandler={async ({ fileUrl = "" }) => {
                  nextFileIdRef.current = fileUrl;
                  onCreateOnlineTaskHandler(fileUrl);
                }}
                onClickContainerHandler={async () => {
                  if (!navigator.onLine) {
                    message.error("当前网络异常，请稍后再试");
                    return;
                  }
                }}
                confirmDataAutolog="feature=button&exp=true&key=tingwu_exp_file_analysis_click&text=开始分析"
              />
            </div>
          ),
        },
        {
          type: eTabsConfigType.REAL_TIME_RECORDING,
          label: "实时录音",
          render: renderRealTimeRecording,
          dataAutolog: "feature=button&exp=true&key=tingwu_exp_realtime_record_click&text=实时录音",
        },
      ],
      [renderRealTimeRecording, navigator.onLine, onCreateOnlineTaskHandler]
    );

    return (
      <Flex vertical align="center" className={styles.EnterControl}>
        <Flex className={styles.EnterControl__Title} gap={8}>
          使用通义听悟
          <div className={styles.EnterControl__Title__Sub}>
            <TextAnimation />
          </div>
        </Flex>
        <Flex justify="center" align="center" className={styles.EnterControl__Tabs}>
          {tabsConfig.map(({ type, label, dataAutolog }) => (
            <div
              className={classnames(styles.EnterControl__Tabs__Item, {
                [styles.EnterControl__Tabs__Item__Active]: type === currentTabs,
              })}
              key={type}
              data-autolog={dataAutolog}
              onClick={() => {
                setCurrentTabs(type);
              }}
            >
              {label}
            </div>
          ))}
        </Flex>
        <Flex className={styles.EnterControl__Content} justify="center">
          <img
            src="https://img.alicdn.com/imgextra/i3/O1CN01gawoDY1vCnk5TFvP9_!!6000000006137-2-tps-336-450.png"
            alt=""
            className={styles.UploadFile__AttachedPictures}
          />
          {tabsConfig.find(({ type }) => type === currentTabs)?.render}
          <img
            src="https://img.alicdn.com/imgextra/i3/O1CN01Nuyply1eSVrT3d3K6_!!6000000003870-2-tps-336-450.png"
            alt=""
            className={styles.UploadFile__AttachedPictures}
          />
        </Flex>
        {showAudioEffectExperience ? (
          <Flex
            justify="center"
            align="center"
            className={styles.AudioEffectExperienceWrapper}
            style={
              tempClose
                ? {
                    width: 0,
                    height: 0,
                    overflow: "hidden",
                  }
                : {}
            }
          >
            <AudioEffectExperience
              ref={audioEffectExperienceRef as any}
              dataId={createTaskOutput?.dataId || ""}
              appId={APP_ID}
              meetingJoinUrl={createTaskOutput?.meetingJoinUrl}
              onStopRecord={() => {
                setTempClose(false);
                setShowAudioEffectExperience(false);
                runGetTaskStatus(createTaskOutput?.dataId);
              }}
              onStopRecordBefore={() => {
                setTempClose(true);
                setCurrStatus(eTranscriptionStatusType.TRANSCRIBING);
              }}
              updateMeetingState={updateMeetingState}
              postAgentRequest={createTaskAPI}
              checkMicPerm={false}
              meetingState={meetingState}
              onErrorMessage={data => {
                if (data.type === "connection" && data?.data?.type === "error")
                  setShowAudioEffectExperience(false);
              }}
              dataAutologs={{
                paused: "feature=button&exp=true&key=tingwu_exp_paused_record_click&text=暂停录音",
                continue:
                  "feature=button&exp=true&key=tingwu_exp_continue_record_click&text=继续录音",
                end: "feature=button&exp=true&key=tingwu_exp_end_record_click&text=继续录音",
              }}
            />
          </Flex>
        ) : null}
      </Flex>
    );
  })
);
