import { Image, Text, View, type CommonEvent } from "@tarojs/components";
import {
  forwardRef,
  useEffect,
  useImperativeHandle,
  useState,
  useMemo,
  useCallback,
  memo,
} from "react";

import { useVoiceRecord } from "@/components/voice-recorder";
import IconShare from "@/images/icon-share.png";
import { chat } from "@/service/character";
import { useCharacterAIStore } from "@/store/characterAIStore";
import {
  greeting,
} from '@/service/character'
import type { ICharacter } from "@/types";
import { ECharacterAISTATUS } from "@/types/index";
import { useAudioPlayer } from "@/utils/audio";
import { useBase64AudioPlayer } from "@/utils/audioBase64";
import { handleShare } from "@/utils/share";
import Taro, { useDidHide, useUnload } from "@tarojs/taro";
import { axios } from "taro-axios";
import style from "./index.module.less";
import SharePopup from "@/components/custom-share/share-popup/index";
import SpeakStatus from "./components/speak-status"
import IconKeyboard from '@/components/icon/icon-keyboard';
import { AvatarMedia } from "./components/AvatarMedia";
import { setChatSession, getChatSession } from '@/store/chat'
let cancelTokenSource = axios.CancelToken.source();
interface Props {
  character: ICharacter;
  getSession?: boolean; // 是否发起greeting 请求获取聊天用的 session
  playGreeting?: boolean; // 是否播放欢迎语
  shareButton?: boolean; // 是否显示分享按钮
  avatarRenderer?: () => JSX.Element; // 自定义渲染头像
  nicknameRenderer?: () => JSX.Element; // 自定义渲染昵称
  enableGoPreview?: boolean; // 允许点击头像去预览
  buttonSize?: string; // 按钮大小
}
let source: AudioBufferSourceNode;
export interface IChatAIComponent {
  stop: () => void;
}


const ChatAI = memo(forwardRef(
  (
    {
      character,
      playGreeting = false,
      getSession = false,
      enableGoPreview = false,
      shareButton = true,
      avatarRenderer,
      nicknameRenderer,
      buttonSize,
    }: Props,
    ref
  ) => {
    const currentCharacter = character;
    const [speechStatus, setSpeechStatus] = useState(0);
    const { start, stop, onVolumeChange, onStop } = useVoiceRecord();
    const { stopPlayChunk, onPlayerStatusChanged } = useAudioPlayer();
    const { playAudio, stopAudio, onEnded } = useBase64AudioPlayer();
    const { setStatus } = useCharacterAIStore();
    const [sharePopupVisible, setSharePopupVisible] = useState(false);
    // console.log(
    //   "currentCharacter:",
    //   currentCharacter?.profileId,
    //   character.profileId,
    //   getSession
    // );

    const handleShareClick = () => {
      handleShare();
      Taro.hideTabBar();
      setSharePopupVisible(true);
    };
    const handleSharePopupClosed = () => {
      Taro.showTabBar();
      setSharePopupVisible(false);
    };

    const stopSpeek = () => {
      setSpeechStatus(0);
      stop();
    };

    onEnded(()=> {
      setStatus(ECharacterAISTATUS.IDLE)
    })


    onPlayerStatusChanged((status: ECharacterAISTATUS) => {
      setStatus(status)
    });

    const stopPlay = () => {
      source && source.stop();
      stopPlayChunk();
    };

    const stopPropagation = (e?: CommonEvent)=> {
      e?.stopPropagation();
    }
    const onLongPress = (e?: CommonEvent) => {
      e?.stopPropagation();
      setSpeechStatus(1);
      stopPlay();
      start();
    };
    const onTouchEnd = () => {
      stopSpeek();
    };

    const handleTouchStart = (e: CommonEvent) => {
      // fix 解决pc端长按呼出右键菜单
      e.preventDefault();
      // fix 解决移动端长按依旧穿透
      e.stopPropagation();
    };

    onVolumeChange((_v) => {});

    onStop((res) => {
      const session = getChatSession()
      console.log("record stop:", res, session);
      stopSpeek();
      if (!res) {
        return;
      }
      console.log(character.profileId, session);
      if (character?.profileId && session) {
        setStatus(ECharacterAISTATUS.THINKING);
        chat(
          character.profileId,
          session,
          res?.tempFilePath || res?.arrayBuffer
        );
      }
    });

    // 打招呼，聊天前都需要先招呼获取聊天所需的 session
    const showGreeting = async () => {
      // cancelTokenSource.cancel('Previous showGreeting request canceled')
      // 重新创建一个新的取消令牌源
      if (!getSession) {
        return;
      }
      cancelTokenSource = axios.CancelToken.source();
      const res = await greeting(currentCharacter.profileId, {
        cancelToken: cancelTokenSource.token,
      });
      if(res.code !== 0){
        return
      }
      if (res?.data?.audio && playGreeting) {
        setStatus(ECharacterAISTATUS.RESPONDING);
        const _source = await playAudio(res?.data?.audio);
        if (_source) {
          source = _source;
        }
      }
      if (res?.data?.session) {
        setChatSession(res.data?.session);
      }
    };

    const handleNav = () => {
      if (enableGoPreview) {
        Taro.navigateTo({
          url: "/pages/profile/index?profileId=" + character.profileId,
        });
      }
    };
    
    const gotoChat = () => {
      Taro.navigateTo({
        url: "/pages/chat/index?profileId=" + character.profileId,
      });
    };

    // 侦听卡片是否为当前卡片，是的话需要播放欢迎语拿session
    // 后期是否优化考虑保存住每个卡片的 session
    useEffect(() => {
      if (currentCharacter?.profileId === character.profileId) {
        showGreeting();
      }
      return () => {
        cancelTokenSource.cancel("Previous showGreeting request canceled");
        source && source.stop();
      };
    }, [currentCharacter?.profileId, character.profileId, getSession]);
    const stopChatAI = useCallback(() => {
      // todo: 调用此方法会导致组件重新渲染，需要优化
      setStatus(ECharacterAISTATUS.IDLE);
      stopPlay();
    },[]);

    // 对外暴露 stop 方法
    useImperativeHandle(ref, () => {
      return {
        stop: stopChatAI,
      };
    });

    useDidHide(() => {
      stopPlay();
      stopAudio();
    });

    useUnload(() => {
      stopPlay();
      stopAudio();
    });

    // 使用 useCallback 缓存渲染函数
    const renderSpeechButton = useMemo(() => {
      if (process.env.TARO_ENV == "h5") {
        return <></>;
      }
      const idle = speechStatus === 0;
      return (
        <View className={`${idle ? style.speechButton : style.speechButtonActive} ${buttonSize === 'small' ? style.buttonSmall : ''}`}>
          <View className={idle ? style.speechButtonInner : "hidden"}>
            <View className={style.keyboardButton} onLongPress={stopPropagation}
            onTouchStart={stopPropagation}
            onTouchEnd={stopPropagation}
            onClick={()=> {gotoChat()}}
            >
              <IconKeyboard></IconKeyboard>
            </View>
            <Text className={`font-medium ${style.speechText}`}>按住对话</Text>
          </View>
        </View>
      );
    }, [speechStatus]);

    const renderNickName = useMemo(() => {
      if (nicknameRenderer) {
        return nicknameRenderer();
      }
      return <View className="truncate">{character?.name}</View>;
    }, [character?.name, nicknameRenderer]);

    const renderNameAndAvatar = useMemo(() => {
      return (
        <>
          <View
            className={`flex items-center justify-center ${style.nickname} truncate`}
            onClick={handleNav}
            id="user-name"
          >
            {renderNickName}
          </View>

          <View className={style.circleOurter} onClick={handleNav}>
            <View className={style.circleInner}>
              {/* {renderAIStatus} */}
              <SpeakStatus></SpeakStatus>
              {avatarRenderer && avatarRenderer()}
              {character?.avatar && !avatarRenderer && (
                <AvatarMedia character={character}></AvatarMedia>
              )}
            </View>
          </View>
        </>
      );
    }, [character?.avatar, avatarRenderer, handleNav, renderNickName]);

    return (
      <View
        className={`flex flex-col items-center relative w-full ${style.wrapper}`}
      >
        <View
          className={`${style.cardContainer}`}
          style={character.customStyled}
        >
          {renderNameAndAvatar}
          <View
            className={`flex flex-col items-center justify-center pt-42 gap-12`}
            onLongPress={onLongPress}
            onTouchStart={handleTouchStart}
            onTouchEnd={onTouchEnd}
          >
            {renderSpeechButton}

            {shareButton && (
              <>
              <View className={style.shareButton} onClick={handleShareClick}>
                <Image src={IconShare} className="w-20 h-20" />
                {/* <Button openType={"share"} className="share-button"></Button> */}
                <Text>分享</Text>
              </View>
              <SharePopup
                character={character}
                visible={sharePopupVisible}
                onClose={handleSharePopupClosed}
              ></SharePopup>
              </>
            )}
            
          </View>
        </View>
      </View>
    );
  }
));

// 添加显示名称，方便调试
ChatAI.displayName = 'ChatAI';

export default ChatAI;
