import consola from 'consola';
import { computed, nextTick, ref, unref } from 'vue';
import TRTC from 'trtc-js-sdk';
import type { LocalStream, Client, RemoteStream } from 'trtc-js-sdk';
import { useRtcStore } from '/@/store/modules/rtc';
// import Dialog from '/@/components/basic/dialog';
import { useI18n } from './useI18n';
import { useMiniApp } from './useMiniApp';
import { useRoom } from './useRoom';

let localClient: Client;
let localStream: LocalStream;
const invitedRemoteStreams = ref<RemoteStream[]>([]);
const muteAudioLeader = ref(false);
const muteVideoLeader = ref(false);
const { isUsingMiniApp } = useMiniApp();
const globalVideoEnable = computed(
  () => Number(import.meta.env.VITE_ENABLE_VIDEO) === 1 && unref(isUsingMiniApp),
);

export const checkDevice = async () => {
  try {
    const rtcStore = useRtcStore();
    const microphoneItems = await TRTC.getMicrophones();
    console.log('microphoneItems', microphoneItems);
    microphoneItems.forEach((item) => {
      item['value'] = item.deviceId;
    });
    if (microphoneItems?.length) {
      rtcStore.setAudioDeviceId(
        microphoneItems[0].deviceId || microphoneItems[0].groupId || 'default',
      );
    } else {
      rtcStore.setAudioDeviceId('');
    }

    const camerasItems = await TRTC.getCameras();
    console.log('camerasItems', camerasItems);
    camerasItems.forEach((item) => {
      item['value'] = item.deviceId;
    });
    if (camerasItems?.length) {
      rtcStore.setVideoDeviceId(camerasItems[0].deviceId || camerasItems[0].groupId || 'default');
    } else {
      rtcStore.setVideoDeviceId('');
    }
  } catch (error) {
    console.log('error', error);
  }
};

const checkSystemRequirements = async () => {
  const result = await TRTC.checkSystemRequirements();
  console.log('result', result);
  const isSmallStreamSupported = await TRTC.isSmallStreamSupported();
  console.log('isSmallStreamSupported', isSmallStreamSupported);
};

// interface UseRtcSdkType {
//     createRTCSocket: () => Promise<void>
// }

async function createLocalStream() {
  try {
    const rtcStore = useRtcStore();

    const enableVideo =
      rtcStore.isLeader && rtcStore.videoDeviceId?.length > 0 && unref(globalVideoEnable);

    console.warn('enableVideo', enableVideo, unref(globalVideoEnable));
    localStream = TRTC.createStream({
      userId: rtcStore.userId,
      audio: true,
      video: enableVideo,
      cameraId: rtcStore.videoDeviceId,
      microphoneId: rtcStore.audioDeviceId,
    });
    //开大小流
    const isSmallStreamSupported = TRTC.isSmallStreamSupported();
    if (isSmallStreamSupported) {
      await localClient.enableSmallStream();
      localClient.setSmallStreamProfile({
        width: 160,
        height: 90,
        bitrate: 100,
        frameRate: 15,
      });
    } else {
      localStream.setVideoProfile('360p');
    }

    //
    await localStream.initialize();
    return Promise.resolve();

    // if (rtcStore.audioMuted) {
    //   localStream.muteAudio();
    // }
  } catch (error) {
    console.log(error, 'createStream');
    return Promise.reject(error);
  }
}

async function createRTCSocket(): Promise<void> {
  try {
    if (!unref(isUsingMiniApp)) {
      const rtcStore = useRtcStore();
      await checkSystemRequirements();
      await checkDevice();
      console.log('createRTCSocket', rtcStore.videoDeviceId);
      await handleJoin();
    } else {
      console.log('小程序关闭rtc入口');
    }
  } catch (error) {
    consola.error({
      tag: 'createRTCSocket',
      message: error,
    });
  }
}
async function handleJoin() {
  const rtcStore = useRtcStore();
  try {
    const { getSign } = useRoom();
    const res = await getSign(rtcStore.userId);
    console.warn('sign', res);
    localClient = TRTC.createClient({
      mode: 'rtc',
      sdkAppId: res.sdkAppId || parseInt(rtcStore.sdkAppId, 10),
      userId: rtcStore.userId,
      userSig: res.sign || rtcStore.genUserSig,
      useStringRoomId: true,
      enableAutoPlayDialog: false,
    });
    installEventHandlers();

    await localClient.join({ roomId: rtcStore.roomId });
  } catch (error) {
    console.error(error, 'error-----------');
  }

  await createLocalStream();
  await handlePublish();
  await nextTick();
  //
  // setTimeout(() => {
  const playLocal = () => {
    const playId = 'camera_box_' + rtcStore.userId;
    localStream
      .play(playId)
      .then(() => {
        consola.info({
          message: '本地采集成功！',
          tag: 'rtc:audio',
        });
        rtcStore.setIsRTCJoined(true);
      })
      .catch((error) => {
        consola.info({
          message: '本地采集失败！' + error,
          tag: 'rtc:audio',
        });
        setTimeout(() => {
          console.log('再次播放');
          playLocal();
        }, 500);
      });
  };

  playLocal();
  // }, 1000);

  // if (!rtcStore.isLeader) {
  localStream.muteAudio();
  console.log('参加者默认-muteAudio');
  // }

  localStream.on('error', (error) => {
    if (error.getCode() === 0x4043) {
      // 自动播放受限导致播放失败，此时引导用户点击页面。
      // 在点击事件的回调函数中，执行 stream.resume();
      const rtcStore = useRtcStore();
      const { t } = useI18n();
      rtcStore.showBaseDialog(
        {
          title: t('base.tips'),
          desc: t('base.audioPermission'),
          okTxt: t('base.confirm'),
          closeTxt: t('base.cancel'),
        },
        () => {
          localStream.resume();
        },
      );
    }
  });
}

async function handlePublish() {
  const rtcStore = useRtcStore();

  if (!rtcStore.isJoined) {
    return;
  }
  if (rtcStore.isPublished) {
    return;
  }
  // if (!rtcStore.isLeader) {
  //   return;
  // }
  try {
    await localClient.unpublish(localStream);
    await localClient.publish(localStream);
    rtcStore.setIsPublished(true);
  } catch (error) {
    console.error(error, '---------------handlePublish--------------------');
  }
}

// async function handleStartShare() {
//     shareClient = new ShareClient({
//         sdkAppId: parseInt(store.getters["rtc/sdkAppId"], 10),
//         userId: `share${store.getters["rtc/userId"]}`,
//         roomId: store.getters["rtc/roomId"],
//         secretKey: store.getters["rtc/secretKey"],
//         useStringRoomId: true,
//     });
//     try {
//         await shareClient.join();
//         await shareClient.publish();
//         console.log("Start share screen success");
//         store.isShared = true;
//     } catch (error) {
//         console.error(`Start share error: ${error.message_}`);
//     }
// }

async function handleUnpublish() {
  const rtcStore = useRtcStore();
  if (!rtcStore.isJoined) {
    return;
  }
  if (!rtcStore.isPublished) {
    return;
  }
  try {
    await localClient.unpublish(localStream);
    // store.commit("rtc/setIsPublished", false);
    rtcStore.setIsPublished(false);
  } catch (error) {
    console.error(error, '-----------handleUnpublish--------------');
  }
}

async function handleLeave() {
  const rtcStore = useRtcStore();
  if (rtcStore.isPublished) {
    await handleUnpublish();
  }
  try {
    uninstallEventHandlers();
    localClient && (await localClient.leave());
    localClient && localClient.destroy();
    // localClient = null;
    invitedRemoteStreams.value.forEach((item) => {
      item.stop();
    });
    invitedRemoteStreams.value = [];
    rtcStore.setVideoDeviceId('');
    rtcStore.setAudioDeviceId('');
    // store.commit("rtc/setVideoDeviceId", "");
    // store.commit("rtc/setAudioDeviceId", "");

    if (localStream) {
      localStream.stop();
      localStream.close();
      // localStream = null;
      console.log('有执行到这里-------------');
    }
  } catch (error) {
    console.error(error, '-----------handleLeave--------------');
  }
}

function installEventHandlers() {
  if (!localClient) {
    return;
  }
  localClient.on('error', handleError);
  localClient.on('client-banned', handleBanned);
  localClient.on('peer-join', handlePeerJoin);
  localClient.on('peer-leave', handlePeerLeave);
  localClient.on('stream-added', handleStreamAdded);
  localClient.on('stream-subscribed', handleStreamSubscribed);
  localClient.on('stream-removed', handleStreamRemoved);
  localClient.on('stream-updated', handleStreamUpdated);
  localClient.on('mute-video', handleMuteVideo);
  localClient.on('mute-audio', handleMuteAudio);
  localClient.on('unmute-video', handleUnmuteVideo);
  localClient.on('unmute-audio', handleUnmuteAudio);
}

function uninstallEventHandlers() {
  if (!localClient) {
    return;
  }
  localClient.off('error', handleError);
  localClient.off('client-banned', handleBanned);
  localClient.off('peer-join', handlePeerJoin);
  localClient.off('peer-leave', handlePeerLeave);
  localClient.off('stream-added', handleStreamAdded);
  localClient.off('stream-subscribed', handleStreamSubscribed);
  localClient.off('stream-removed', handleStreamRemoved);
  localClient.off('stream-updated', handleStreamUpdated);
  localClient.off('mute-video', handleMuteVideo);
  localClient.off('mute-audio', handleMuteAudio);
  localClient.off('unmute-video', handleUnmuteVideo);
  localClient.off('unmute-audio', handleUnmuteAudio);
}

function handleMuteVideo(event) {
  console.log(`[${event.userId}] mute video`);
  const rtcStore = useRtcStore();
  const roomLeader = rtcStore.getRoomLeader();
  if (event.userId === roomLeader?.UserId) {
    muteVideoLeader.value = true;
  }
}

function handleMuteAudio(event) {
  if (event.userId.indexOf('leader') > -1) {
    muteAudioLeader.value = true;
  }
  console.log(event, `[] mute audio`);
}

function handleUnmuteVideo(event) {
  console.log(`[${event.userId}] unmute video`);
  const rtcStore = useRtcStore();
  const roomLeader = rtcStore.getRoomLeader();
  if (event.userId === roomLeader?.UserId) {
    muteVideoLeader.value = false;
  }
}

function handleUnmuteAudio(event) {
  console.log(`[${event.userId}] unmute audio`);
  if (event.userId.indexOf('leader') > -1) {
    muteAudioLeader.value = false;
  }
}

function handleError(error) {
  console.log(`LocalClient error: ${error.message_}`);
}

function handleBanned(error) {
  console.log(`Client has been banned for ${error.message_}`);
}

function handlePeerJoin(event) {
  const { userId } = event;
  if (userId !== 'local-screen') {
    console.log(`Peer Client [${userId}] joined`);
  }
}

function handlePeerLeave(event) {
  const { userId } = event;
  if (userId !== 'local-screen') {
    console.log(`[${userId}] leave`);
  }
}

function handleStreamAdded(event) {
  const remoteStream = event.stream;
  const id = remoteStream.getId();
  const userId = remoteStream.getUserId();
  const rtcStore = useRtcStore();

  console.log(remoteStream, '-------------remoteStream');

  if (remoteStream.getUserId() === rtcStore.userId) {
    // don't need to screen shared by us
    localClient.unsubscribe(remoteStream).catch((error) => {
      console.info(`unsubscribe failed: ${error.message_}`);
    });
  } else {
    console.log(`remote stream added: [${userId}] ID: ${id} type: ${remoteStream.getType()}`);
    localClient.subscribe(remoteStream).catch((error) => {
      console.info(`subscribe failed: ${error.message_}`);
    });
  }
}

async function handleStreamSubscribed(event) {
  const remoteStream = event.stream;
  const rtcStore = useRtcStore();
  // const { t } = useI18n();
  // debugger;
  const remoteUserId = remoteStream.getUserId();
  const remoteId = remoteStream.getId();
  if (remoteUserId == rtcStore.userId) {
    return;
  }

  if (!rtcStore.isIdInRemoteStream(remoteId)) {
    consola.info({
      message: remoteId,
      tag: 'rtc:audio',
    });
    rtcStore.pushRemoteStreams(remoteStream);
    // debugger
  }
  await nextTick();
  const playRemote = () => {
    // const playId = 'camera_remote_box_' + rtcStore.userId;
    const playId = 'cameraRemoteBox';
    remoteStream
      .play(playId)
      .then(() => {
        consola.info({
          message: '远端采集成功 ！playId: ' + playId + ' remoteId:' + remoteId,
          tag: 'rtc:audio',
        });
      })
      .catch((error) => {
        consola.info({
          message: '远端采集失败！' + error,
          tag: 'rtc:audio',
        });
        setTimeout(() => {
          console.log('远端再次播放' + remoteId);
          playRemote();
        }, 500);
      });
  };
  playRemote();
  remoteStream.on('error', (error) => {
    if (error.getCode() === 0x4043) {
      // 自动播放受限导致播放失败，此时引导用户点击页面。
      // 在点击事件的回调函数中，执行 stream.resume();
      const rtcStore = useRtcStore();
      const { t } = useI18n();
      rtcStore.showBaseDialog(
        {
          title: t('base.tips'),
          desc: t('base.audioPermission'),
          okTxt: t('base.confirm'),
          closeTxt: t('base.cancel'),
        },
        () => {
          console.log('手机端', rtcStore.remoteStreams);
          rtcStore.remoteStreams.forEach((item) => {
            item.resume();
          });
          remoteStream.resume();
        },
      );
    }
  });

  // setTimeout(async () => {
  //   try {
  //     consola.info({
  //       message: '客音源-->' + remoteId,
  //       tag: 'rtc:audio',
  //     });
  //     consola.info({
  //       message: rtcStore.remoteStreams,
  //       tag: 'rtc:audio',
  //     });
  //     await remoteStream.play(remoteId);
  //   } catch (error) {}
  // }, 200);
}

function handleStreamRemoved(event) {
  const remoteStream = event.stream;
  const userId = remoteStream.getUserId();
  const remoteStreamId = remoteStream.getId();
  consola.info({
    message: `远端流删除: [${userId},${remoteStreamId}]`,
    tag: 'rtc:audio',
  });
  const rtcStore = useRtcStore();
  rtcStore.removeRemoteStreams(remoteStreamId);
  const node = document.getElementById(`player_` + remoteStreamId);
  consola.info({
    message: `远端流删除:` + node,
    tag: 'rtc:audio',
  });
  if (node) {
    console.log('node', node);
  }
}

function handleStreamUpdated(event) {
  const remoteStream = event.stream;
  const userId = remoteStream.getUserId();
  console.log(
    `RemoteStream updated: [${userId}] audio:${remoteStream.hasAudio()} video:${remoteStream.hasVideo()}`,
  );
}

// const switchDevice = async ({ videoId, audioId }) => {
//   const rtcStore = useRtcStore();
//   if (!rtcStore.isJoined) {
//     return;
//   }
//   if (videoId) {
//     try {
//       await localStream.switchDevice('video', videoId);
//     } catch (error) {}
//   }
//   if (audioId) {
//     try {
//       await localStream.switchDevice('audio', audioId);
//     } catch (error) {}
//   }
// };

export function useRtcSdk() {
  return {
    createRTCSocket,
    handleJoin,
    handleLeave,
    localStream,
    muteVideoLeader,
    invitedRemoteStreams,
    client: localClient,
    globalVideoEnable,
  };
}
