<template>
  <div class="trtccom" v-if="show">
    <Device @switchDevice="switchDevice" @canUseDevice="canUseDevice" />
    <div class="local" :class="{disabledlocal:role=='customer'}" id="local" v-if="isJoined"></div>

    <template v-if="isJoined && invitedRemoteStreams.length > 0">
      <div class="local" :data-role="item.userId_" :class="{disabledlocal:item.userId_.indexOf('customer')>-1}" v-for="(item, i) in invitedRemoteStreams" :id="item.getId()" :key="i"></div>
    </template>

    <div class="videoBox userVideo" v-show="props.videoMuted">
      <img :src="require('@/assets/images/rtcLive/avatar_small@2x.png')" alt="" />
      <img class="loadingTip" :src="require('@/assets/images/rtcLive/loading@2x.png')" alt="" />
    </div>
  </div>
</template>

<script setup>
import TRTC, { Client, LocalStream } from "trtc-js-sdk";
import { Dialog } from "@/global_components/";
import { ref, computed, watch, defineEmits, defineProps, nextTick } from "vue";
import Device from "./trtc/Device";
import { useStore } from "vuex";
import browser from "@/utils/browser";

const emit = defineEmits(["audioMuted", "videoMuted"]);

const store = useStore();

const show = ref(false);
const invitedRemoteStreams = ref([]);

const role = ref(browser.getURLParam("role"));

const isJoined = computed(() => store.getters["rtc/isJoined"]);
const isPublished = computed(() => store.getters["rtc/isPublished"]);
const userSig = computed(() => store.getters["rtc/userSig"]);

const initParamsStates = computed(
  () => !!(store.getters["rtc/sdkAppId"] && store.getters["rtc/secretKey"] && store.getters["rtc/roomId"] && store.getters["rtc/userId"])
);

let localClient = "";
let localStream = "";
let shareClient = "";

const props = defineProps({
  audioMuted: {
    default: false,
  },
  videoMuted: {
    default: false,
  },
});

watch(
  () => props.audioMuted,
  () => {
    if (props.audioMuted) {
      localStream.muteAudio();
    } else {
      localStream.unmuteAudio();
    }
  }
);

watch(
  () => props.videoMuted,
  () => {
    if (props.videoMuted) {
      localStream.muteVideo();
    } else {
      localStream.unmuteVideo();
    }
  }
);

watch(
  () => isJoined.value,
  () => {
    if (!isJoined.value) {
      handleLeave();
    }
  }
);

TRTC.checkSystemRequirements().then((checkResult) => {
  if (!checkResult.result) {
    Dialog.toast({ content: `您的設備不支持音視頻通訊`, type: "error" });
  } else {
    show.value = true;
  }
});

async function createLocalStream() {
  let isLeader = role.value == 'leader'
  try {
    localStream = TRTC.createStream({
      userId: store.getters["rtc/userId"],
      audio: true,
      video: isLeader,
      cameraId: isLeader ? store.getters["rtc/videoDeviceId"] : '',
      microphoneId: store.getters["rtc/audioDeviceId"],
    });
    isLeader && localStream.setVideoProfile("480p");

    await localStream.initialize();
  } catch (error) {}
}

async function handleJoin() {
  if (!initParamsStates.value) {
    return;
  }

  try {
    localClient = TRTC.createClient({
      mode: "rtc",
      sdkAppId: parseInt(store.getters["rtc/sdkAppId"], 10),
      userId: store.getters["rtc/userId"],
      userSig: userSig.value,
    });
    installEventHandlers();


    await localClient.join({ roomId: parseInt(store.getters["rtc/roomId"], 10) });
    store.commit("rtc/setIsJoined", true);
    // inviteLink.value = store.commit("rtc/createShareLink");
  } catch (error) {
    console.error(error, "error-----------");
  }

  await createLocalStream();
  await handlePublish();
  localStream
    .play("local")
    .then(() => {
      // addLocalControlView();
    })
    .catch((e) => {});
}

async function handlePublish() {
  if (!isJoined.value) {
    return;
  }
  if (isPublished.value) {
    return;
  }

  try {
    await localClient.publish(localStream);
    store.commit("rtc/setIsPublished", true);
  } catch (error) {}
}

async function handleStartShare() {
  shareClient = new ShareClient({
    sdkAppId: parseInt(store.getters["rtc/sdkAppId"], 10),
    userId: `share${store.getters["rtc/userId"]}`,
    roomId: parseInt(store.getters["rtc/roomId"], 10),
    secretKey: store.getters["rtc/secretKey"],
  });
  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() {
  if (!isJoined.value) {
    return;
  }
  if (!isPublished.value) {
    return;
  }
  try {
    await localClient.unpublish(localStream);
    store.commit("rtc/setIsPublished", false);
  } catch (error) {}
}

async function handleLeave() {
  if (isPublished.value) {
    await handleUnpublish();
  }
  try {
    uninstallEventHandlers();
    await localClient.leave();
    if (localStream) {
      localStream.stop();
      localStream.close();
      localStream = null;
    }
  } catch (error) {}
}

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("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`);
}

function handleMuteAudio(event) {
  console.log(`[${event.userId}] mute audio`);
}

function handleUnmuteVideo(event) {
  console.log(`[${event.userId}] unmute video`);
}

function handleUnmuteAudio(event) {
  console.log(`[${event.userId}] unmute audio`);
}

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();

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

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

async function handleStreamSubscribed(event) {
  const remoteStream = event.stream;

  if (remoteStream.userId_ == store.getters["rtc/userId"]) {
    return
  }

  if (!invitedRemoteStreams.value.some(item=>item.userId_==remoteStream.userId_)) {
    invitedRemoteStreams.value.push(remoteStream);
  }

  console.log(invitedRemoteStreams.value, "invitedRemoteStreams.value");
  await nextTick();
  remoteStream
    .play(remoteStream.getId())
    .then(() => {
      console.log(`RemoteStream play success`, 88888888888888888888);
    })
    .catch((error) => {
      console.log(`RemoteStream play failed:  error: ${error.message_}`);
    });

  // const remoteStream = event.stream;
  // const userId = remoteStream.getUserId();
  // console.log(`RemoteStream subscribed: [${userId}]`);
}

function handleStreamRemoved(event) {
  const remoteStream = event.stream;
  const userId = remoteStream.getUserId();
  console.log(`RemoteStream removed: [${userId}]`);
}

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

let switchDevice = async ({ videoId, audioId }) => {
  if (!isJoined.value) {
    return;
  }
  if (videoId) {
    try {
      await localStream.switchDevice("video", videoId);
    } catch (error) {}
  }
  if (audioId) {
    try {
      await localStream.switchDevice("audio", audioId);
    } catch (error) {}
  }
};

let canUseDevice = () => {
  console.log("可用");
  handleJoin();
};
</script>

<style lang="scss" scoped>
.trtccom {
  .local {
    width: 70px;
    height: 70px;
    position: fixed;
    z-index: 9999;
    top: 0.69rem;
    left: 0.53rem;
    border-radius: 50%;
    overflow: hidden;
    background: url(~@/assets/images/rtcLive/avatar_small@2x.png) center center no-repeat;
  }
  .videoBox {
    width: 72px;
    height: 72px;
    top: 0.67rem;
    left: 0.52rem;
    position: fixed;
    z-index: 99999;
    .loadingTip {
      position: absolute;
      z-index: 101;
      left: 0;
      top: 0;
      bottom: 0;
      right: 0;
      animation: Rotate 1.5s infinite;
      @keyframes Rotate {
        0% {
          transform: rotate(0deg);
        }
        100% {
          transform: rotate(360deg);
        }
      }
    }
    > img {
      width: 1.94rem;
      height: 1.94rem;
    }
  }
  .disabledlocal {
    opacity: 0 !important;
    visibility: hidden !important;
  }
}
</style>
