<script setup>
import request from '~/utils/request';
// import CommonHeader from "@/components/CommonHeader/index.vue";
import { ElMessage } from 'element-plus';
import AgoraRTC from "agora-rtc-sdk-ng"
import { user as loginUser } from '~/store/user';
import { timestamp2string } from '~/utils/string';
import { resolveSingleFileString, getFullUrl } from '~/utils/helper';
import { createSocket, socketSend } from '~/utils/ws';

const props = defineProps({
  id: String
})

let loading = $ref(true)
let detailInfo = $ref({})
let isNonSpeak = $ref(true)
let nonSpeakUsers = $ref({})

const ws = createSocket({ room: `tbjy-${props.id}` }, {
  message(socketRes) {
    if (socketRes.content.to_user_id === loginUser.user_id) {
      if (socketRes.content.type === 'disableSpeak') {
        ElMessage.warning('您已被禁言')
        isNonSpeak = true
        rtc?.client?.unpublish(rtc?.localAudioTrack)
        // rtc?.client?.unpublish([rtc?.localAudioTrack, rtc?.localVideoTrack])
      } else if (socketRes.content.type === 'enableSpeak') {
        ElMessage.success('您已被解除禁言')
        isNonSpeak = false
        rtc?.client?.publish(rtc?.localAudioTrack)
        // rtc?.client?.publish([rtc?.localAudioTrack, rtc?.localVideoTrack])
      }
    }
  }
})

let clientAllUsers = $ref({})
let clientRemoteUsers = ref([])
let clientRemoteUsersNum = $ref(0)

const localPlayerContainer = ref()
const showingPlayerContainer = ref()
const remotePlayerContainer = ref([])

function getClientRemoteUsers(arr) {
  return arr.filter((user) => user.uid !== loginUser.user_id && user.uid !== loginUser.user_id + 'b')
}

const isCreator = $computed(() => {
  return detailInfo?.create_user_id === loginUser.user_id
})

request({
  url: '/zhjy/tbjy/detail',
  data: {
    zt_id: props.id
  }
}).then(async (res) => {
  if (res.code === '1') {
    detailInfo = res.data.one_info
    console.log('detailInfo :>> ', detailInfo);
    await request({
      url: '/zhjy/tbjy_jy/index',
      data: {
        ztj_zt_id: props.id,
        ztj_user_id: isCreator ? undefined : loginUser.user_id
      }
    }).then(res1 => {
      console.log('isCreator ', isCreator,);
      console.log('data ', res1.data.page_data);
      if (res1.code === '1') {
        if (isCreator) {
          isNonSpeak = false
          res1.data.page_data.forEach(item => {
            nonSpeakUsers[item.ztj_user_id] = item
          })
          console.log('nonSpeakUsers :>> ', nonSpeakUsers);
        } else {
          isNonSpeak = (res1.data.page_data.length > 0)
          if (isNonSpeak) {
            ElMessage.warning('您处于禁言状态')
          }
        }
      }
    })

    {
      options = {
        appId: detailInfo.rtc_appid,
        channel: detailInfo.zt_id,
        token: detailInfo.rtc_token,
        uid: loginUser.user_id,
      }
      let client = rtc.client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });
      clientRemoteUsers.value = getClientRemoteUsers(rtc.client.remoteUsers)
      clientRemoteUsersNum = clientRemoteUsers.value.length
      await nextTick()
      // console.log('remotePlayerContainer', remotePlayerContainer.value);

      rtc.client.remoteUsers.forEach(async (user, idx) => {
        await client.subscribe(user, 'video');
        await client.subscribe(user, 'audio');

        const audioTrack = user.audioTrack;
        audioTrack?.play();

        const videoTrack = user.videoTrack;
        videoTrack?.play(remotePlayerContainer.value[idx]);

        clientAllUsers[idx] = ({ user, _show: false })
      });

      client.on("user-published", async (user, mediaType) => {
        // console.log('user-published :>> ', user.uid !== loginUser.user_id && user.uid !== loginUser.user_id + 'b');
        // console.log('user-published :>> user', user);
        // console.log('user-published :>> mediaType', mediaType);

        // 不订阅自己发布的
        if (user.uid !== loginUser.user_id && user.uid !== loginUser.user_id + 'b') {
          clientRemoteUsers.value = getClientRemoteUsers(rtc.client.remoteUsers)
          clientRemoteUsersNum = clientRemoteUsers.value.length

          // 发起订阅
          await client.subscribe(user, mediaType);

          // 如果订阅的是音频轨道
          if (mediaType === "audio") {
            const audioTrack = user.audioTrack;
            // 自动播放音频
            audioTrack?.play();
          } else {
            await nextTick()
            clientAllUsers[clientRemoteUsers.value.length - 1] = ({ user, _show: false })
            // console.log('user-published :>> ', user);
            // console.log(remotePlayerContainer.value.length);

            const videoTrack = user.videoTrack;
            // 自动播放视频
            videoTrack?.play(remotePlayerContainer.value[clientRemoteUsers.value.length - 1]);
          }
        }
      });

      // rtc.client.setClientRole("host");
      await rtc.client.join(options.appId, options.channel, options?.token, options.uid);
      // Create an audio track from the audio sampled by a microphone.
      rtc.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
      // Create a video track from the video captured by a camera.
      rtc.localVideoTrack = await AgoraRTC.createCameraVideoTrack({
          encoderConfig:'1080p_1'
      });
      // Publish the local audio and video tracks to the channel.

      // todo: 未禁言时才发布
      await rtc.client.publish(rtc.localVideoTrack);
      if (!isNonSpeak) {
        // await rtc.client.publish(rtc.localVideoTrack);
        await rtc.client.publish(rtc.localAudioTrack);
      }

      rtc.localVideoTrack?.play(localPlayerContainer.value);
      clientAllUsers[-1] = ({ user: 'self', _show: false })

    }

    loading = false
  } else {
    ElMessage.error(res.msg)
  }
}).catch(err => {
  ElMessage.error(err)
})

let rtc = {
  // For the local audio and video tracks.
  localAudioTrack: null,
  localVideoTrack: null,
  client: null
};

let options = {
  // Pass your app ID here.
  appId: null,
  // Set the channel name.
  channel: null,
  // Use a temp token
  token: null,
  token2: null,
};




onBeforeUnmount(async () => {
  // Close all the local tracks.
  rtc.localAudioTrack?.close();
  rtc.localVideoTrack?.close();
  // Traverse all remote users.
  // rtc.client.remoteUsers.forEach(user => {
  //   // Destroy the dynamically created DIV containers.
  //   const playerContainer = document.getElementById(user.uid);
  //   playerContainer && playerContainer.remove();
  // });
  if (screenTrack) {
    screenTrack?.close()

  }
  // Leave the channel.
  await rtc?.client?.leave();
  await screenClient?.leave();


})

const wrapperContainer = $ref()

function requestFullscreen() {
  wrapperContainer.requestFullscreen()
}
function exitFullscreen() {
  document.exitFullscreen()
}

function toggleFullscreen() {
  if (document.fullscreenElement === null) {
    requestFullscreen()
  } else {
    exitFullscreen()
  }
}

const volume = $ref(50)
function handleChangeVolume(val) {
  clientRemoteUsers.value.forEach(remoteUser => {
    remoteUser.audioTrack.setVolume(val * 2);
  })
}

// function handleShowing(id) {
//   // if (oldShowId !== undefined && oldShowId !== id) {
//   //   clientAllUsers[oldShowId]._show = false
//   // }
//   // oldShowId = id

//   const currentMode = clientAllUsers[id]._show
//   if (currentMode) {
//     if (id === -1) {
//       rtc.localVideoTrack?.play(localPlayerContainer.value);
//     } else {
//       clientRemoteUsers.value[id].videoTrack?.play(remotePlayerContainer.value[id])
//     }
//   } else {
//     showingPlayerContainer.value.childNodes.forEach(node => {
//       node.remove()
//     })
//     if (id === -1) {
//       rtc.localVideoTrack?.play(showingPlayerContainer.value);
//     } else {
//       clientRemoteUsers.value[id].videoTrack?.play(showingPlayerContainer.value)
//     }
//   }
//   clientAllUsers[id]._show = !clientAllUsers[id]._show
// }

let activeShowId = $ref(undefined)
function handleShowing(id) {
  if (id === activeShowId) {
    activeShowId = undefined
  } else {
    if (activeShowId !== undefined) {
      if (activeShowId === -1) {
        rtc.localVideoTrack?.play(localPlayerContainer.value);
      } else {
        clientRemoteUsers.value[activeShowId].videoTrack?.play(remotePlayerContainer.value[activeShowId])
      }
    }
    activeShowId = id
  }

  if (activeShowId === undefined) {
    // 切换为小屏模式
    if (id === -1) {
      rtc.localVideoTrack?.play(localPlayerContainer.value);
    } else {
      clientRemoteUsers.value[id].videoTrack?.play(remotePlayerContainer.value[id])
    }
  } else {
    // 切换为大屏模式
    // showingPlayerContainer.value.childNodes.forEach(node => {
    //   node.remove()
    // })
    if (id === -1) {
      rtc.localVideoTrack?.play(showingPlayerContainer.value);
    } else {
      clientRemoteUsers.value[id].videoTrack?.play(showingPlayerContainer.value)
    }
  }
  clientAllUsers[id]._show = !clientAllUsers[id]._show
}



let screenClient
let screenTrack
let shareBtnLoading = $ref(false)
let shareBtnState = $ref(false)
async function handleShareScreen() {
  if (shareBtnState) {
    await screenTrack.close();
    shareBtnState = false
  }
  else {
    if (shareBtnLoading === false) {
      shareBtnLoading = true
      const res = await request({
        url: '/zhjy/tbjy/rtc_token',
        data: {
          channelname: props.id
        }
      })
      console.log('handleShareScreen res :>> ', res);
      if (res.code === '1') {
        detailInfo = res.data.one_info

        const _options = {
          appId: detailInfo.rtc_appid,
          channel: props.id,
          token: detailInfo.rtc_token,
          uid: loginUser.user_id + 'b'
        }
        AgoraRTC.createScreenVideoTrack({
          // 配置屏幕共享编码参数，详情请查看 API 文档。
          encoderConfig: "1080p_1",
          // 设置视频传输优化策略为清晰优先或流畅优先。
          optimizationMode: "detail",//"motion"

          withAudio: 'disable'
        }).then(async localScreenTrack => {
          screenTrack = localScreenTrack
          /** ... **/
          if (!screenClient) {
            screenClient = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });
            await screenClient.join(_options.appId, _options.channel, _options?.token, _options.uid);
          }
          localScreenTrack.on("track-ended", async () => {
            console.log('track-ended :>> ');
            if (screenTrack) {
              screenTrack.close();
            }
            shareBtnState = false
          })
          localScreenTrack?.play(showingPlayerContainer.value)
          await screenClient.publish(localScreenTrack)
          shareBtnState = true
        });
      }
    }
    shareBtnLoading = false
  }
}


const tabVal = ref('gg')


const queryCommentForm = reactive({
  limit: 10,
  page: 1
})
let commentData = $ref([])
let commentTotal = $ref(0)
function queryCommentList() {
  request({
    url: '/zhjy/tbjy_kcdg_jygw/index',
    data: {
      zt_id: props.id,
      ...queryCommentForm
    }
  }).then(res => {
    if (res.code === '1') {
      commentData = res.data.page_data
      commentTotal = res.data.total_rows * 1
    }
  })
}
queryCommentList()

let form_ztkj_gwnr = $ref('')
function handleSubmitComment() {
  if (form_ztkj_gwnr.length >= 100 && form_ztkj_gwnr.length <= 500) {
    request({
      url: '/zhjy/tbjy_kcdg_jygw/add',
      data: {
        zhjy_tbjy_kcdg_jygw: {
          ztkj_user_realname: loginUser.user_realname,
          zt_id: props.id,
          ztkj_gwnr: form_ztkj_gwnr
        }
      }
    }).then(res => {
      if (res.code === '1') {
        ElMessage.success('提交成功')
        form_ztkj_gwnr = ''
        queryCommentList()
      }
    })
  } else {
    ElMessage.warning('教研感悟至少100个字且不超过500个字')
  }
}


const queryFileForm = reactive({
  limit: 10,
  page: 1
})
let fileData = $ref([])
let fileTotal = $ref(0)
function queryFileList() {
  request({
    url: '/zhjy/tbjy_file/index',
    data: {
      zt_id: props.id,
      ...queryFileForm
    }
  }).then(res => {
    if (res.code === '1') {
      fileData = res.data.page_data
      fileTotal = res.data.total_rows * 1
    }
  })
}
queryFileList()

let form_file = $ref(undefined)
let t1 = $ref(Date.now())
function handleSubmitFile() {
  console.log('form_file :>> ', form_file);
  console.log(resolveSingleFileString(form_file));
  const file = resolveSingleFileString(form_file)
  form_file = undefined
  t1 = Date.now()
  {
    request({
      url: '/zhjy/tbjy_file/add',
      data: {
        zhjy_tbjy_file: {
          zt_id: props.id,

          user_name: loginUser.user_realname,
          ztf_name: file.name,
          ztf_file: file.origin
        }
      }
    }).then(res => {
      if (res.code === '1') {
        ElMessage.success('提交成功')
        queryFileList()
      }
    })
  }
}

function handleFileDelete(row) {
  request({
    url: '/zhjy/tbjy_file/delete',
    data: {
      ztf_id: row.ztf_id
    }
  }).then(res => {
    if (res.code === '1') {
      ElMessage.success('删除成功')
      queryFileList()
    }
  })
}

let dialogVisible = $ref(false)
let dialogDataFile = $ref('')

function handlePreview(d) {
  console.log('d :>> ', d);
  dialogDataFile = d
  dialogVisible = true
}

let audioInUse = $ref(true)
let videoInUse = $ref(true)

function handleSwitchAudio() {
  audioInUse = !audioInUse
  try {
    rtc.localAudioTrack.setEnabled(audioInUse)
  } catch (error) {
    console.error(error);
  }

}
function handleSwitchVideo() {
  videoInUse = !videoInUse
  try {
    rtc.localVideoTrack.setEnabled(videoInUse)
  } catch (error) {
    console.error(error);
  }
}

function handleSwitchSpeak(uid) {
  console.log('handleSwitchSpeak :>> ', uid, clientRemoteUsers.value);
  const speakStatus = nonSpeakUsers[uid]
  if (speakStatus) {
    request({
      url: '/zhjy/tbjy_jy/delete',
      data: {
        ztj_zt_id: props.id,
        ztj_user_id: uid,
      }
    }).then(
      res => {
        if (res.code === '1') {
          socketSend(ws, {
            to_user_id: uid,
            type: 'enableSpeak',
          })
          delete nonSpeakUsers[uid]
          ElMessage.success('解除禁言成功')
        }
      }
    )
  } else {
    request({
      url: '/zhjy/tbjy_jy/add',
      data: {
        zhjy_tbjy_jy: {
          ztj_zt_id: props.id,
          ztj_user_id: uid,
        }
      }
    }).then(res => {
      if (res.code === '1') {
        socketSend(ws, {
          to_user_id: uid,
          type: 'disableSpeak',
        })
        nonSpeakUsers[uid] = res.data.one_info
        ElMessage.success('禁言成功')
      }
    })

  }


}

</script>

<template>
  <common-header />
  <div class="w-full flex items-center justify-center shadow h-60px bg-hex-fefefe">
    <div class="w-1400px flex items-center">
      <breadcrumb-text title="智慧教研-同步教研-详情"></breadcrumb-text>
    </div>
  </div>

  <!-- <div class="w-full flex items-center justify-center shadow h-60px bg-hex-fefefe">
                                                                                      <div class="w-1400px flex items-center">
                                                                                        <div class="text-lg text-hex-050026" >{{ detailInfo?.zt_name }}</div>
                                                                                      </div>
                                                                                    </div> -->

  <div class="w-full flex items-center justify-center mt-4">
    <div ref="wrapperContainer" class="w-1400px h-min-930px flex flex-col relative bg-light-500" v-loading="loading">
      <div
        class="w-full h-210px flex overflow-x-auto bg-light-700 p-2 space-x-2 _scrollbar scrollbar-thin scrollbar-thumb-rounded scrollbar-thumb-gray-300 scrollbar-track-transparent">
        <div class="w-280px h-full flex-none bg-black relative" ref="localPlayerContainer" @click="handleShowing(-1)">
          <div class="w-full h-full bg-black text-white text-sm flex_center absolute inset-0 z-30"
            v-show="activeShowId === -1">
            点击切换至小屏模式
          </div>
          <div v-if="!isCreator"
            class="py-1 px-2 text-xs rounded-sm cursor-pointer absolute bottom-4 right-6 flex_center z-40 bg-dark-300 text-white"
            :class="(!isNonSpeak) && 'hidden'">
            禁言中</div>
        </div>
        <div class="w-280px h-full flex-none relative bg-black" v-for="(_, idx) in clientRemoteUsersNum"
          :ref="(el) => remotePlayerContainer[idx] = el" @click="handleShowing(idx)">
          <!-- <div class="w-full h-full bg-black text-white text-sm flex_center" v-show="clientAllUsers[idx]?._show">
                                                                          点击切换至小屏模式</div> -->
          <div class="w-full h-full bg-black text-white text-sm flex_center absolute inset-0 z-30"
            v-show="activeShowId === idx">
            点击切换至小屏模式</div>
          <div v-if="isCreator"
            class="py-1 px-2 text-xs rounded-sm cursor-pointer absolute bottom-4 right-6 flex_center z-40 bg-dark-300 text-white"
            @click.stop="handleSwitchSpeak(clientRemoteUsers[idx].uid)">
            {{ nonSpeakUsers[clientRemoteUsers[idx].uid] ? '取消禁言' : '禁言' }}</div>
        </div>
      </div>
      <div ref="showingPlayerContainer" class="w-full h-full "></div>

      <div
        class="w-full h-36px absolute bottom-0 left-0 flex justify-end items-center text-xl text-white bg-black px-4 opacity-10 hover:opacity-60 space-x-2">

        <span class="text-xs cursor-pointer px-2 py-1 bg-dark-900" @click="handleSwitchAudio">{{ audioInUse ? '禁用麦克风' :
          '启用麦克风' }}</span>

        <span class="text-xs cursor-pointer px-2 py-1 bg-dark-900" @click="handleSwitchVideo">{{ videoInUse ? '禁用摄像头' :
          '启用摄像头' }}</span>

        <span class="text-xs cursor-pointer px-2 py-1 bg-dark-900" :class="shareBtnLoading && 'cursor-wait'"
          @click="handleShareScreen">{{ shareBtnState ? '退出共享' : '屏幕共享' }}</span>

        <div class="w-140px flex items-center">
          <i-clarity:volume-up-solid />
          <el-slider v-model="volume" @change="handleChangeVolume" class="ml-2" />
        </div>

        <i-bx:fullscreen @click="toggleFullscreen" class="cursor-pointer" />
      </div>
    </div>
  </div>

  <div class="w-full flex flex-col items-center  my-8">
    <div class="w-1400px flex flex-col items-center shadow-md min-h-400px p-4">
      <div class="w-full">
        <el-tabs v-model="tabVal">
          <el-tab-pane label="公告" name="gg">
            <div v-if="detailInfo.zt_notice" v-html="detailInfo.zt_notice" class="gg"></div>
            <div v-else class="flex justify-center w-full">
              <el-empty description="暂无数据" />
            </div>
          </el-tab-pane>
          <el-tab-pane label="教研感悟" name="jygw"></el-tab-pane>
          <el-tab-pane label="资源" name="zy"></el-tab-pane>

        </el-tabs>
      </div>

      <div v-show="tabVal === 'jygw'" class="w-full flex flex-col justify-start items-start">
        <el-input v-model="form_ztkj_gwnr" maxlength="500" placeholder="至少100个字不超过500个字" show-word-limit type="textarea"
          rows="5" />
        <div
          class="mt-2 flex_center h-32px text-sm w-110px leading-26px px-4 bg-gradient-to-l from-green-400 to-blue-500 text-white rounded-14px cursor-pointer btn"
          @click="handleSubmitComment">
          发表感悟</div>

        <div class="w-full divide-y divide-dashed divide-2px">
          <template v-if="commentData.length">
            <div class="text-hex-171721 text-sm py-5" v-for="i in commentData">
              <div class="flex items-end mb-3">
                <div class="">{{ i.ztkj_user_realname }}</div>
                <div class="text-hex-8083A3 text-xs ml-8">{{ timestamp2string(i.create_dateline * 1000) }}</div>
              </div>
              <div class="indent">{{ i.ztkj_gwnr }}</div>
            </div>
          </template>

          <div v-else class="flex justify-center w-full">
            <el-empty description="暂无数据" />
          </div>

        </div>

        <div class="w-full flex justify-end mt-8 mb-8">
          <el-pagination background layout="prev, pager, next" :total="commentTotal"
            v-model:current-page="queryCommentForm.page" @current-change="queryCommentList()" />
        </div>
      </div>
      <div v-show="tabVal === 'zy'" class="w-full flex flex-col justify-start items-center">
        <file-upload-progress :key="t1" v-model:full="form_file" @compile="handleSubmitFile"
          v-if="user.user_role_id < 76">
          <div
            class="mt-2 flex_center h-32px text-sm w-110px leading-26px px-4 bg-gradient-to-l from-green-400 to-blue-500 text-white rounded-14px cursor-pointer btn">
            上传附件</div>
          <template #file>
            <span class="w-0 h-0"></span>
          </template>
        </file-upload-progress>

        <div class="w-full divide-y divide-dashed divide-2px">
          <template v-if="fileData.length">
            <div class="text-hex-171721 text-sm py-5" v-for="i in fileData">
              <div class="flex items-end mb-3">
                <div class="">{{ i.user_name }}</div>
                <div class="text-hex-8083A3 text-xs ml-8">{{ timestamp2string(i.create_dateline * 1000) }}</div>
              </div>
              <div class="flex justify-between">
                <div class="">{{ i.ztf_name }}</div>
                <div>
                  <el-button type="primary" plain @click="handlePreview(getFullUrl(i.ztf_file))" class="mr-2">预览
                  </el-button>

                  <a :href="getFullUrl(i.ztf_file)">
                    <el-button type="primary" plain>下载
                    </el-button>
                  </a>
                  <el-button type="primary" plain @click="handleFileDelete(i)"
                    :disabled="loginUser.user_id !== i.create_user_id" class="ml-2">删除</el-button>
                </div>
              </div>
            </div>
          </template>

          <div v-else class="flex justify-center w-full">
            <el-empty description="暂无数据" />
          </div>

        </div>

        <div class="w-full flex justify-end mt-8 mb-8">
          <el-pagination background layout="prev, pager, next" :total="fileTotal"
            v-model:current-page="queryFileForm.page" @current-change="queryFileList()" />
        </div>
      </div>
    </div>

    <el-dialog v-model="dialogVisible" draggable width="65vw" :key="dialogDataFile">
      <file-preview :url="dialogDataFile" alt="" class="w-full min-h-65vh" />
    </el-dialog>
  </div>
  <common-footer />
</template>

<style scoped>
:deep(.el-tabs__nav-wrap::after) {
  background-color: transparent;
}

/* .gg {
  height: 330px;
  overflow-y: scroll;
} */
.gg {
  height: 343px;
  overflow-x: hidden;
  overflow-y: scroll;
  line-height: 30px;
}

/*滚动条样式*/
.gg::-webkit-scrollbar {
  width: 3px;
  height: 200px;
}

/* 上下滚动的滚动条颜色 */
.gg::-webkit-scrollbar-thumb {
  border-radius: 10px;
  -webkit-box-shadow: inset 0 0 5px #00a3ff;
  background: #00a3ff;
}

/* 滚动条的整体背景颜色 */
.gg::-webkit-scrollbar-track {
  -webkit-box-shadow: inset 0 0 5px white;
  border-radius: 0;
  background: white;
}
</style>
