import consola from 'consola';
import { computed, nextTick, ref, unref } from 'vue';
import TRTC from 'trtc-js-sdk';

import type { LocalStream, Client } from 'trtc-js-sdk';
import { useMiniApp } from './useMiniApp';
import { useRtcStore } from '/@/store/modules/rtc';
// import Dialog from '/@/components/basic/dialog';
import { useI18n } from './useI18n';
import { muteVideoLeader } from './useTRTC';
// import { useRoom } from './useRoom';

let localClient: Client;
let localStream: LocalStream;
const isHasMicrophone = ref(false);
const audioDeviceId = ref('');
const videoDeviceId = ref('');

// const invitedRemoteStreams = ref<RemoteStream[]>([]);
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);
    if (microphoneItems.length > 0) {
    }
    microphoneItems.forEach((item) => {
      item['value'] = item.deviceId;
    });
    if (microphoneItems?.length) {
      isHasMicrophone.value = true;
      audioDeviceId.value = microphoneItems[0].deviceId || microphoneItems[0].groupId || 'default';
    }

    const camerasItems = await TRTC.getCameras();
    console.warn('camerasItems', camerasItems);
    camerasItems.forEach((item) => {
      item['value'] = item.deviceId;
    });
    if (camerasItems?.length) {
      rtcStore.setHasCamera();
      videoDeviceId.value = camerasItems[0].deviceId || camerasItems[0].groupId || 'default';
    }
  } 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.isHasCamera && unref(globalVideoEnable);

    console.warn('enableVideo', enableVideo, rtcStore.isHasCamera, unref(globalVideoEnable));
    localStream = TRTC.createStream({
      userId: rtcStore.userId,
      audio: true,
      video: enableVideo,
      // cameraId: unref(videoDeviceId),
      facingMode: 'user',
      microphoneId: unref(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);
  }
}

export async function createRTCSocket(
  sdkAppId: string,
  roomId: string,
  sign: string,
  userId: string,
): Promise<Client> {
  try {
    if (!unref(isUsingMiniApp)) {
      console.warn('web rtc入口');
      await checkSystemRequirements();
      await checkDevice();
      await handleJoin(Number(sdkAppId), roomId, sign, userId);
      return Promise.resolve(localClient);
    } else {
      console.log('小程序关闭rtc入口');
      return Promise.resolve(localClient);
    }
  } catch (error) {
    consola.error({
      tag: 'createRTCSocket',
      message: error,
    });
    return Promise.resolve(localClient);
  }
}
async function handleJoin(sdkAppId: number, roomId: string, sign: string, userId: string) {
  const rtcStore = useRtcStore();
  try {
    localClient = TRTC.createClient({
      mode: 'rtc',
      sdkAppId: sdkAppId || parseInt(rtcStore.sdkAppId, 10),
      userId: userId,
      userSig: sign || rtcStore.genUserSig,
      useStringRoomId: true,
      enableAutoPlayDialog: false,
    });
    installEventHandlers();
    await localClient.join({ roomId: roomId });
    rtcStore.setIsRTCJoined(true);
  } 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',
        });
      })
      .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 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--------------');
  }
}

export async function handleLeave() {
  const rtcStore = useRtcStore();
  if (rtcStore.isPublished) {
    await handleUnpublish();
  }
  try {
    uninstallEventHandlers();
    localClient && (await localClient.leave());
    localClient && localClient.destroy();
    // 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) {
  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 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();
        },
      );
    }
  });
}

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()}`,
  );
}
export const mutedAudio = () => {
  //通用禁音方法
  console.error('mutedAudio');
  if (isHasMicrophone.value) {
    localStream.muteAudio();
  }
};
export const unMutedAudio = () => {
  //通用开音方法
  console.error('unMutedAudio');
  if (isHasMicrophone.value) {
    localStream.unmuteAudio();
  }
};
export const muteVideo = () => {
  //通用开音方法
  localStream.muteVideo();
};
export const unMuteVideo = () => {
  localStream.unmuteVideo();
};

export const switchToFrontCam = () => {
  localStream.switchDevice('video', 'user');
};

export const switchToBackCam = () => {
  localStream.switchDevice('video', 'environment');
};
