import { defineComponent, ref } from "vue";
import * as RTC from "@rongcloud/plugin-rtc";
import Header from "./header";
import ActionBar, { state as ActionBarRuntime } from "./action-bar";
import VideoStatus from "./video-status";
import { state } from "/src/state";
import event, { LIVE_EVENT_MESSAGE } from "./event";
import runtime, * as RuntimeUtils from "./runtime";
import Chronography from "./chronography";
import runtimeModel, * as RuntimeModelUtils from "/src/components/live-message/model/runtime";
import { requireMedia } from "./helpers";
import styles from "./index.module.less";
import request from "/src/helpers/request";
import dayjs from "dayjs";
import { ElMessageBox } from "element-plus";

const videoRef = ref<HTMLVideoElement | null>(null);

let microphoneAudioTrack: RTC.RCLocalTrack;
let cameraVideoTrack: RTC.RCLocalTrack;

export default defineComponent({
  name: "LiveBroadcast",
  data() {
    return {
      headerStatus: false,
      initAudioUsers: [],
    };
  },
  computed: {
    isLive() {
      console.log(runtime.videoStatus);
      if (runtime.videoStatus === "liveing") {
        setTimeout(() => {
          this.headerStatus = true;
        }, 3000);
      } else {
        this.headerStatus = false;
      }
      return runtime.videoStatus === "liveing";
    },
  },
  async mounted() {
    this.initializeRoom();
    RuntimeUtils.loopSyncLike();
    event.on(LIVE_EVENT_MESSAGE["RC:Chatroom:Like"], this.onLikeMessage);
    window.onbeforeunload = this.beforeunload;
    window.addEventListener('offline', async () => {
      if (!navigator.onLine) {
        try {
          await ElMessageBox.confirm('请检查网络设置，请检查网络', '网络断开', {
            confirmButtonText: '刷新'
          });
          location.reload();
        } catch (error) {}
      }
    })
    // window.addEventListener('focus', this.visibilitychange)
    // window.addEventListener('blur', this.visibilitychange)
  },
  beforeUnmount() {
    event.off(LIVE_EVENT_MESSAGE["RC:Chatroom:Like"], this.onLikeMessage);
    window.onbeforeunload = null;
    // window.removeEventListener('focus', this.visibilitychange)
    // window.removeEventListener('blur', this.visibilitychange)
  },
  methods: {
    visibilitychange(evt: FocusEvent) {
      console.log(evt);
      if (evt.type === "focus") {
        document.exitPictureInPicture();
        document.body.click();
      }
      if (evt.type === "blur") {
        runtime.videoRef?.requestPictureInPicture();
      }
    },
    beforeunload() {
      if (runtime.videoStatus === "liveing") {
        return "当前正在直播中是否确认关闭页面？";
      }
    },
    onLikeMessage(msg: any) {
      runtime.likeCount += msg.counts || 0;
    },
    getDeviceByDeviceType(type: RuntimeUtils.TrackType) {
      const videoDeviceId = localStorage.getItem(RuntimeUtils.VIDEO_DEVICE_ID);
      const audioDeviceId = localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_ID);
      const audioDeviceId2 = localStorage.getItem(
        RuntimeUtils.AUDIO_DEVICE_ID2
      );
      if (type === "camera") {
        if (videoDeviceId) {
          return (
            runtime.cameras.find(
              (camera) => camera.deviceId === videoDeviceId
            ) || runtime.cameras[0]
          );
        }
        return runtime.cameras[0];
      }
      if (audioDeviceId) {
        return (
          runtime.microphones.find(
            (microphone) => microphone.deviceId === audioDeviceId
          ) || runtime.microphones[0]
        );
      }
      if (audioDeviceId2) {
        return (
          runtime.microphones.find(
            (microphone) => microphone.deviceId === audioDeviceId2
          ) || runtime.microphones[0]
        );
      }
      return runtime.microphones[0];
    },
    async FetchUserDetails(userIds: string[]) {
      try {
        const res = await request.post(
          "/api-web/imLiveBroadcastRoom/queryBaseUserInfo",
          {
            requestType: "json",
            data: userIds,
          }
        );
        return res.data;
      } catch (error) {}
      return [];
    },
    async initializeRoom() {
      if (!state.user) throw Error("请先登录");
      let initAudioUsers: any[] = [];
      try {
        runtime.likeCount = state.user?.likeNum || 0;
        runtime.lookCount = state.user?.lookNum || 0;
        const isLiveing =
          sessionStorage.getItem(RuntimeUtils.START_LIVE_STATUS) === "liveing";
        // IM连接
        await RuntimeUtils.connectIM(state.user?.imToken);
        runtime.videoRef = videoRef.value;
        // 获取设备
        await RuntimeUtils.getMicrophones();
        await RuntimeUtils.getCameras();
        // 设置播放设备
        RuntimeUtils.setSelectCamera(this.getDeviceByDeviceType("camera"));
        RuntimeUtils.setSelectMicrophone(
          this.getDeviceByDeviceType("microphone")
        );
        // RuntimeUtils.setSelectMicrophone2(this.getDeviceByDeviceType('microphone2'))
        cameraVideoTrack = await RuntimeUtils.getTrack("camera");
        runtime.videoRef && cameraVideoTrack.play(runtime.videoRef);
        // await RuntimeUtils.setTrack([cameraVideoTrack], 'camera', isLiveing)
        // await RuntimeUtils.getTrack('microphone')
        microphoneAudioTrack = await RuntimeUtils.getTrack("microphone");
        // microphoneAudioTrack.play()
        // console.log(microphoneAudioTrack)
        // console.log(runtime.deviceStatus)
        runtime.videoStatus = "stream";
        const _this = this;
        const join = await RuntimeUtils.joinRoom(
          state.user?.roomUid,
          RTC.RCLivingType.VIDEO,
          {
            onMessageReceive(name, content) {
              console.log(name, content);
            },
            onKickOff(byServer: boolean) {
              if (!byServer) {
                ElMessageBox.alert('您的推流停止，请点击确定刷新页面重新开启直播', '提示', {
                  callback: () => {
                    runtime.videoStatus = 'stream';
                    location.reload();
                  }
                })
              }
              console.log('onKickOff', byServer);
            },
            async onTrackPublish(tracks: RTC.RCRemoteTrack[]) {
              const subscribeRes = await join?.room?.subscribe(tracks);
              console.log(subscribeRes, "subscribeRes");
              if (
                subscribeRes?.code &&
                subscribeRes.code !== RTC.RCRTCCode.SUCCESS
              ) {
                console.log("资源订阅失败 ->", subscribeRes.code);
              }
            },
            onTrackUnpublish(tracks: RTC.RCRemoteTrack[]) {
              event.emit(LIVE_EVENT_MESSAGE["RM:RTC:TrackUnpublish"], tracks);
            },
            onSwitchRole(userId: string, role: RTC.RCRTCLiveRole) {
              event.emit(LIVE_EVENT_MESSAGE["RM:RTC:SwitchRole"], {
                userId,
                role,
              });
            },
            async onTrackReady(track: RTC.RCRemoteTrack) {
              if (track.isAudioTrack()) {
                // 音轨不需要传递播放控件
                track.play();
                const userId = track.getUserId();

                // 当流变化时，更新连麦用户列表
                const joinUser = runtimeModel.joinList[userId];
                console.log(joinUser, "joinUser");
                if (!joinUser) {
                  console.log(runtimeModel.lookList, "runtimeModel.lookList");
                  const userInfo = runtimeModel.lookList[userId];
                  const list = userInfo
                    ? userInfo
                    : await _this.FetchUserDetails([userId]);
                  console.log(list, "list");
                }
                // if (runtimeModel.joinList || runtimeModel.lookList) {

                // }
                const trackUser = initAudioUsers.find(
                  (user: any) => user.userId == Number(userId)
                );
                // console.log(trackUser, initAudioUsers, userId)
                if (trackUser) {
                  runtimeModel.joinList[userId] = {
                    ...trackUser,
                    id: userId,
                    name: trackUser.userName,
                    userRoomType: 4,
                  };
                  initAudioUsers = initAudioUsers.filter(
                    (user: any) => user.userId != Number(userId)
                  );
                }
              }
            },
            onUserJoin(userIds: string[]) {
              console.log("onUserJoin", userIds);
            },
            onUserLeave(userIds: string[]) {
              event.emit(LIVE_EVENT_MESSAGE["RM:RTC:UserLeave"], userIds);
              console.log("onUserLeave", userIds);
            },
          }
        );
        // RuntimeUtils.sendMessage({}, 'Welcome')
        const userIds: string[] | undefined = join?.room?.getRemoteUserIds();
        // console.log('userIds', userIds)
        if (userIds && userIds.length) {
          const list = await this.FetchUserDetails(userIds);
          initAudioUsers.push(...list);
        }
        const remoteTracks: RTC.RCRemoteTrack[] | undefined =
          join?.room?.getRemoteTracks();
        if (remoteTracks && remoteTracks.length) {
          await join?.room?.subscribe(remoteTracks);
        }
        if (join.room && join.code === RTC.RCRTCCode.SUCCESS) {
          runtime.joinedRoom = join.room;
          join.room.registerReportListener({
            onStateReport(report) {
              event.emit("onStateReport", report);
              // console.log('onStateReport', report)
            },
          });
        }
        if (isLiveing) {
          await RuntimeUtils.startLive(false);
          runtime.videoStatus = "liveing";
        } else {
          await RuntimeUtils.setTrack([cameraVideoTrack], "camera", false);
          await RuntimeUtils.setTrack(
            [microphoneAudioTrack],
            "microphone",
            false
          );
        }
        const volume = localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_VOLUME);
        if (volume) {
          ActionBarRuntime.volume = parseInt(volume);
          RuntimeUtils.setVolume(parseInt(volume));
        }

        // 同步移动端观看人数
        await RuntimeUtils.sendMessage(
          { count: state.user?.lookNum || 0 },
          "MemberCount"
        );
      } catch (error) {
        runtime.videoStatus = "error";
        console.log(error);
      }
    },
    closeLive() {
      // removeMedia(runtime.mediaStreams, runtime.mediaStreamTrack)
      runtime.videoStatus = "stream";
    },
  },
  render() {
    return (
      <div class={styles.main}>
        {this.isLive ? null : null}
        <div class={[styles.headerSection]}>
          <Header
            class={[
              styles.headerContent,
              this.headerStatus ? styles["header-top"] : null,
            ]}
          />
        </div>
        <div class={styles.video}>
          <video ref={videoRef}></video>
          {!runtime.screenShareStatus ? <VideoStatus /> : null}
          {runtime.videoStatus === "liveing" ? <Chronography /> : null}
        </div>
        <ActionBar />
        {/* <div>video: {runtime.videoStatus}, imStatus: {runtime.imConnectStatus}</div> */}
      </div>
    );
  },
});
