<template>
  <BaseLive :room-info="roomInfo">
    <div class="student">
      <div class="middle">
        <!-- 教师学员列表 -->
        <PersonnelList
          :has-video="isShowPersonnelList"
          :student-list="student_list"
          :teacher-name="roomInfo.teacher_name"
        />

        <!-- 直播视频与连线 -->
        <div v-show="!isShowDraw" class="live-main">
          <div class="live-connection" :style="{ 'padding-top': connect || callLoading ? '131px' : '0' }">
            <div class="live">
              <div v-show="isTVideo" id="live"></div>
            </div>
            <div v-show="callLoading" class="call-loading">
              <span>等待接通...</span>
            </div>
            <div v-show="connect" id="student" class="student-video"></div>
          </div>
          <div v-show="(callLoading || connect) && invite" class="close">
            <el-button type="danger" @click="() => (connect ? handsDown() : inviteAccept())">
              {{ connect ? '结束连线' : '连线' }}
            </el-button>
          </div>
        </div>

        <div class="draw" :style="{ left: isShowDraw ? '0' : '-3000px' }">
          <div id="draw-parent"></div>
        </div>

        <!-- 聊天 -->
        <ChatPage ref="cPage" :chat-list="chatList" :chat-show="chatShow" @sendMsg="sendMsg" />

        <!-- 成员列表 -->
        <MemberList :member-show="memberShow" :student-list="student_list" />
      </div>
      <div class="bottom">
        <div class="operation"></div>
        <div class="operation">
          <div :class="['operation-item', { active: chatShow }]" @click="toggle(toggleList[0].type)">
            <img src="@/assets/live/communication.png" alt="" />
            <span>聊天</span>
          </div>
          <div :class="['operation-item', { active: memberShow }]" @click="toggle(toggleList[1].type)">
            <img src="@/assets/live/peoples.png" alt="" />
            <span>成员列表</span>
          </div>
        </div>
        <div class="operation">
          <button class="live-button" @click="exitRoom(task_id, room_user_id)">退出房间</button>
        </div>
      </div>
    </div>
    <!-- 选择设备 -->
    <SelectDevice
      :dialog-visible-device="dialogVisibleDevice"
      :device="device"
      @dialogDeviceClose="dialogDeviceClose"
    />
    <!-- 学员当前推送资料 -->
    <CurMaterial
      ref="material"
      :task-id="task_id"
      :material-id="materialId"
      :material-type="materialType"
      :is-finished="is_finished"
      @dialogMaterialClose="dialogMaterialClose"
    />
  </BaseLive>
</template>

<script>
export default {
  name: 'StudentLive'
};
</script>

<script setup>
import { ref, watch, computed, inject, provide, onBeforeUnmount } from 'vue';
import { useRoute } from 'vue-router/composables';
import { Message } from 'element-ui';
import { useInit, useChat, useMemberList, useLive } from '../common/common';
import { useInitListener, useConnect, useStudentLive } from './live';
import store from '@/store';
import { app } from '@/store/mutation-types';

import BaseLive from '../common/BaseLive.vue';
import SelectDevice from '../common/SelectDevice';
import ChatPage from '../common/ChatList.vue';
import MemberList from '../common/MemberList.vue';
import PersonnelList from '../common/PersonnelList.vue';
import CurMaterial from '@/components/live/CurMaterial.vue';

const route = useRoute();
const room_user_id = route.query.room_user_id;
provide('room_user_id', room_user_id);
const $t = inject('$t');
const task_id = route.query.task_id;
provide('task_id', task_id);

let remoteStreamType = ref(-1);
let roomData = ref({
  desc: '直播间标题',
  name: '姓名',
  user: {
    id: '',
    name: '',
    role: 'talker',
    rommid: ''
  },
  max_users: 1,
  allow_chat: true,
  allow_audio: true,
  allow_speak: true
});
let invite = ref(false);
let speakData = ref({});
let roomContext = ref({});

// 推送的资料
let material = ref();
let materialId = ref('');
let materialType = ref('');
let is_finished = ref(false);

function showMaterial(id, type, isFinished) {
  materialId.value = id;
  materialType.value = type;
  is_finished.value = isFinished === 'true';
  material.value.dialogShow();
}

function dialogMaterialClose() {
  materialId.value = '';
  materialType.value = '';
  is_finished.value = false;
}

// 本地视频流画面、声音
let device = ref({
  video: [],
  audio: []
});
let hasVideo = ref(false);
let hasAudio = ref(false);
/**
 * 本地流视频开启、关闭
 */
function playOrPauseVideo() {
  if (device.value.video.length === 0) {
    return Message.warning($t('Key399'));
  }

  if (hasVideo.value) {
    pauseVideo({
      streamName: 'main',
      success: () => {
        Message.success($t('Key433'));
        hasVideo.value = false;
      },
      fail: (str) => {
        Message.warning(str);
      }
    });
  } else {
    playVideo({
      streamName: 'main',
      success: () => {
        Message.success($t('Key434'));
        hasVideo.value = true;
      },
      fail: (str) => {
        Message.warning(str);
      }
    });
  }
}

/**
 * 本地流音频开启、关闭
 */
function playOrPauseAudio() {
  if (device.value.audio.length === 0) {
    return Message.warning($t('Key401'));
  }

  if (hasAudio.value) {
    pauseAudio({
      streamName: 'main',
      success: () => {
        Message.success($t('Key435'));
        hasAudio.value = false;
      },
      fail: (str) => {
        Message.warning(str);
      }
    });
  } else {
    playAudio({
      streamName: 'main',
      success: () => {
        Message.success($t('Key436'));
        hasAudio.value = true;
      },
      fail: (str) => {
        Message.warning(str);
      }
    });
  }
}

let dialogVisibleDevice = ref(false);
let isRecreate = ref(false);
// 设置音视频设备
function setDevice(isRec) {
  isRecreate.value = isRec;
  dialogVisibleDevice.value = true;
}

function dialogDeviceClose(device) {
  store.commit(`app/${app.SET_DEVICE}`, device);
  dialogVisibleDevice.value = false;
}

const { pauseVideo, playVideo, pauseAudio, playAudio, unSubscribeStream } = useLive();

// 聊天
let cPage = ref();
const { chatList, chatShow, sendMsg, toggle: chatToggle } = useChat(cPage);
// 成员列表
const { memberShow, toggle: memberToggle } = useMemberList();

// 教师流
let tStream = ref(null);
// 教师流是否有视频流
let isTVideo = ref(false);
setInterval(() => {
  isTVideo.value = tStream.value?.hasVideo() ?? false;
}, 1000);

let isShowDraw = ref(false);

let isShowPersonnelList = computed(() => {
  return isTVideo.value || connect.value || callLoading.value || isShowDraw.value;
});

const { exitRoom } = useStudentLive();
const { callLoading, connect, connectStudent, material_list, roomInfo, student_list, dealStudentConnection } = useInit(
  useInitListener,
  {
    roomData,
    chatList,
    device,
    roomContext,
    speakData,
    remoteStreamType,
    isShowDraw,
    setDevice,
    invite,
    room_user_id,
    tStream,
    exitRoom
  }
);

watch(
  () => roomInfo.value.is_enable_whiteboard,
  (val) => {
    isShowDraw.value = val;
  }
);

const { handsDown, inviteAccept } = useConnect({
  roomInfo,
  room_user_id,
  connect,
  callLoading,
  invite,
  dealStudentConnection
});

onBeforeUnmount(() => {
  if (callLoading.value || connect.value) handsDown();
  if (tStream.value) unSubscribeStream(tStream.value);
});

// 多个附属界面切换
const toggleList = [
  {
    type: 'chat',
    toggle: chatToggle
  },
  {
    type: 'member',
    toggle: memberToggle
  }
];
function toggle(type) {
  let item = toggleList.find((item) => item.type === type);
  if (item === undefined) return;
  item.toggle();
  toggleList.forEach((item) => {
    if (item.type !== type) {
      item.toggle(false);
    }
  });
}
</script>

<style lang="scss" scoped>
.student {
  display: flex;
  flex-direction: column;
  height: 100%;

  .middle {
    position: relative;
    flex: 1;
    overflow: hidden;

    .live-main {
      display: flex;
      flex-direction: column;
      width: 100%;
      height: 100%;
      background-color: #434343;

      .live-connection {
        display: flex;
        flex: 1;

        .live {
          flex: 1;
          background-color: #000;

          #live {
            width: 100%;
            height: 100%;
          }
        }

        .call-loading {
          display: flex;
          flex-basis: 50%;
          align-items: center;
          justify-content: center;
          color: #fff;
          background-color: #333;
        }

        .student-video {
          flex-basis: 50%;
        }
      }

      .close {
        display: flex;
        justify-content: center;
        padding: 90px 0 16px;
      }
    }

    .draw {
      position: absolute;
      width: 100%;
      height: 100%;
      overflow: hidden;

      #draw-parent {
        height: 100%;
        margin: auto;
      }
    }
  }

  .bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 96px;
    padding: 12px 16px;
    background-color: #f8f8f8;

    .operation {
      display: flex;
      column-gap: 16px;

      &-item {
        display: flex;
        flex-direction: column;
        row-gap: 4px;
        align-items: center;
        width: 80px;
        height: 70px;
        padding: 8px;
        cursor: pointer;
        border-radius: 8px;
        transition: background-color 0.3s;

        &.active,
        &:active {
          background-color: #e5e5e5;
        }

        img {
          width: 32px;
          height: 32px;
        }
      }

      .line {
        width: 2px;
        height: 70px;
        background-color: #d0d0d0;
      }

      .live-button {
        height: 48px;
        padding: 8px 24px;
        font-size: 20px;
        font-weight: 500;
        color: #e52e2e;
        cursor: pointer;
        border: 2px solid #e52e2e;
        border-radius: 4px;
      }
    }
  }
}
</style>
