<script setup lang="ts">
import AgoraRTC from "agora-rtc-sdk-ng"
import type { IAgoraRTCClient, IMicrophoneAudioTrack, ICameraVideoTrack } from "agora-rtc-sdk-ng"
import type { type_dyaw_xlfw_zxhd, type_dyaw_xlfw_zxhd_log, type_archives_item } from '~/types';
import { Search } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import user from '~/store/user';
import { createSocket, socketSend } from '~/utils/ws';
import type { TSocketRes } from '~/utils/ws';
import { formatTimestamp } from '~/utils/time';
let dyaw_xlfw_zxhd = $ref<type_dyaw_xlfw_zxhd | undefined>()
let dyaw_xlfw_zxhd_list = $ref<type_dyaw_xlfw_zxhd[] | undefined>()


let timer: NodeJS.Timeout;
(async function loop() {
  dyaw_xlfw_zxhd_list = (await request({
    url: '/dyaw/xlfw_zxhd/index',
    data: {
      dxz_tea_user_id: user.user_id,
      limit: 20,
      last_msg: 1
    }
  })).data.page_data
  timer = setTimeout(async () => {
    await loop();
  }, 60 * 1000);
})();

const searchValue = $ref('')
watch(
  () => searchValue,
  async () => {
    dyaw_xlfw_zxhd_list = (await request({
      url: '/dyaw/xlfw_zxhd/index',
      data: {
        dxz_tea_user_id: user.user_id,
        dxz_stu_user_realname: searchValue,
        limit: 20,
        last_msg: 1
      }
    })).data.page_data
  }
)

let infoList = $ref<Array<type_dyaw_xlfw_zxhd_log>>([])
let inputValue = $ref('')
let isSending = $ref(false)
let TinyRef = $ref<typeof import('~/components/tinymce-area/index.vue')['default']>()
async function handleClickSend() {
  if (!dyaw_xlfw_zxhd) return;
  if (isSending) return;
  isSending = true
  const reqDate = {
    dxz_id: dyaw_xlfw_zxhd.dxz_id,
    dxzl_stu_user_id: dyaw_xlfw_zxhd.dxz_stu_user_id,
    dxzl_stu_user_realname: dyaw_xlfw_zxhd.dxz_stu_user_realname,
    dxzl_tea_user_id: dyaw_xlfw_zxhd.dxz_tea_user_id,
    dxzl_tea_user_realname: dyaw_xlfw_zxhd.dxz_tea_user_realname,
    dxzl_last_msg_content: encodeURIComponent(inputValue),
    dxzl_type: inputValue.includes('><img') ? '2' : '1'
  }

  // infoList.push({
  //   create_user_id: user.user_id,
  //   create_dateline: Date.now().toString().slice(0, 10),

  //   ...reqDate
  // })
  TinyRef?.clear()
  // console.log('inputValue :>> ', inputValue);
  request({
    url: '/dyaw/xlfw_zxhd_log/add',
    data: {
      dyaw_xlfw_zxhd_log: reqDate
    }
  }).then(res => {
    if (res.code === '1') {
      const fullSendData = {
        create_user_id: user.user_id,
        create_dateline: Date.now().toString().slice(0, 10),
        ...reqDate,
        dxzl_id: `${res.data.insert_id}`
      }
      infoList.push(fullSendData)
      socketSend(ws!, fullSendData)
      isSending = false
    }
  })
}

let ws = $ref<WebSocket>()

let cardLoading = $ref(false)
function handleClickStuCard(stu: type_dyaw_xlfw_zxhd) {
  cardLoading = true
  dyaw_xlfw_zxhd = stu
  stu.dxz_unread_msg_num = "0"
  archivesList = []

  ws?.close()
  request({
    url: '/dyaw/xlfw_zxhd_log/index',
    data: {
      dxzl_stu_user_id: stu.dxz_stu_user_id,
      dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
    }
  }).then(res => {
    if (res.code === '1') {
      infoList = res.data.page_data.reverse()
      cardLoading = false
      ws = createSocket(
        { teacher: user.user_id, student: stu.dxz_stu_user_id },
        {
          message(socketRes: TSocketRes<type_dyaw_xlfw_zxhd_log>) {
            if (socketRes.from_client_name.endsWith('student')) {
              infoList.push(socketRes.content)
              request({
                url: '/dyaw/xlfw_zxhd_log/index',
                data: {
                  dxzl_stu_user_id: stu.dxz_stu_user_id,
                  dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
                  limit: 0
                }
              })

            }
          }
        }
      )

      handleQueryArchives()
    }
  })
}

let ifScroll = $ref(true)
function handleLoadMoreInfo() {
  request({
    url: '/dyaw/xlfw_zxhd_log/index',
    data: {
      dxzl_stu_user_id: dyaw_xlfw_zxhd?.dxz_stu_user_id,
      dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
      zxhd_log_id: infoList[0].dxzl_id
    }
  }).then(res => {
    if (res.code === '1') {
      ifScroll = false
      if (res.data.page_data.length === 0) return ElMessage.info('暂无更多消息');
      infoList.unshift(...res.data.page_data.reverse())
    }
  })
}

const scrollbarRef = $ref<HTMLElement>()
function scrollToBottom() {
  if (!scrollbarRef) return;
  const scrollHeight = scrollbarRef!.scrollHeight;
  scrollbarRef!.scrollTo(0, scrollHeight);
}
watch(
  () => (infoList),
  () => {
    nextTick(() => {
      ifScroll && scrollToBottom();
      ifScroll = true
    })
  },
  {
    deep: true,
  }
)


onBeforeUnmount(() => {
  clearInterval(timer)
})

const ArchivesCardRef = $ref<typeof import('~/components/archives-card/index.vue')['default']>()
function handleSubmitArchives() {
  ElMessageBox.confirm('一次咨询只能提交一次档案，请确认完毕后点击提交', '提示')
    .then(() => {
      request({
        url: '/dyaw/xlfw_xsda_dajl/add',
        data: {
          dyaw_xlfw_xsda_dajl: ArchivesCardRef!.form
        }
      }).then(res => {
        if (res.code === '1') {

          handleQueryArchives()
        }
      })
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '取消提交',
      })
    })
}

let archivesList = $ref<type_archives_item[]>([])
function handleQueryArchives() {
  request({
    url: '/dyaw/xlfw_xsda_dajl/index',
    data: {
      user_id: dyaw_xlfw_zxhd!.dxz_stu_user_id
    }
  }).then(res => {
    if (res.code === '1') {
      archivesList = res.data.page_data
    }
  })
}

// ==========
// chat audit/video
// ==========
let rtcInstance: {
  client?: IAgoraRTCClient;
  localAudioTrack?: IMicrophoneAudioTrack;
  localVideoTrack?: ICameraVideoTrack
} = {
  client: undefined,
  localAudioTrack: undefined,
  localVideoTrack: undefined,
}


const ws2 = createSocket(
  { teacher: user.user_id, student: '*' },
  {
    message(socketRes: TSocketRes<type_dyaw_xlfw_zxhd_log & { operate: CHAT_OPERATION }>) {
      if (socketRes.from_client_name.endsWith('student')) {
        // infoList.push(socketRes.content)
        console.log('');
        if (socketRes.content.dxzl_tea_user_id === user.user_id) {
          console.log('operate:', socketRes.content.operate);
          switch (socketRes.content.operate) {
            case CHAT_OPERATION.START:
              auditChatStatus = CHAT_STATUS.WAITING_YOU_ACCEPT
              ChatAudioRef!.open()
              break;
            case CHAT_OPERATION.CANCEL:
              ChatAudioRef!.close()
              break;
            case CHAT_OPERATION.ACCEPT:
              auditChatStatus = CHAT_STATUS.CHATING
              break;
            case CHAT_OPERATION.DENY:
              ChatAudioRef!.close()
              break;
            case CHAT_OPERATION.END:
              ChatAudioRef!.close()
              break;
            default:
              break;
          }
        }
      }
    }
  }
)

enum CHAT_STATUS { 'WAITING_YOU_ACCEPT', 'WAITING_OTHERS_ACCEPT', 'WAITING_BUSY', 'CHATING' }
enum CHAT_OPERATION { 'START', 'CANCEL', 'ACCEPT', 'DENY', 'END' }
let auditChatStatus = $ref<CHAT_STATUS>(CHAT_STATUS.WAITING_OTHERS_ACCEPT)

const ChatAudioRef = $ref<typeof import("~/components/chat-dialog/index.vue")['default']>()
const ChatVideoRef = $ref<typeof import("~/components/chat-dialog/index.vue")['default']>()


async function handleAuditChatStart() {
  try {
    let rtcOptions
    await request({
      url: '/dyaw/xlfw_zxhd/get_rtc_token',
      data: {
        dxz_id: dyaw_xlfw_zxhd?.dxz_id
      }
    }).then(async res => {
      if (res.code === '1') {
        let resp: { jgim_roomid: string; rtc_appid: string; rtc_token: string } = res.data.one_info
        rtcOptions = {
          appId: resp.rtc_appid,
          channel: resp.jgim_roomid,
          token: resp.rtc_token,
          uid: user.user_id
        }

        let client = rtcInstance.client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });

        client.on("user-published", async (user, mediaType) => {
          // 发起订阅
          await client.subscribe(user, mediaType);

          // 如果订阅的是音频轨道
          if (mediaType === "audio") {
            const audioTrack = user.audioTrack;
            // 自动播放音频
            audioTrack?.play();
          } else {
            const videoTrack = user.videoTrack;
            // 自动播放视频
            videoTrack?.play(RemotePlayerContainerRef as HTMLElement);
          }
        });

        await rtcInstance.client.join(rtcOptions.appId, rtcOptions.channel, rtcOptions?.token, rtcOptions.uid);
        rtcInstance.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
        // rtcInstance.localVideoTrack = await AgoraRTC.createCameraVideoTrack();
        await rtcInstance.client.publish([rtcInstance.localAudioTrack]);
        // rtcInstance.localVideoTrack.play(LocalPlayerContainerRef as HTMLElement);
      }
    })
    ChatAudioRef!.open()
    socketSend(ws2, {
      dxzl_stu_user_id: dyaw_xlfw_zxhd!.dxz_stu_user_id,
      dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
      operate: CHAT_OPERATION.START,
      rtcOptions
    })
  } catch (error) {
    console.error(error);
  }

}
function handleAuditChatCancel() {
  socketSend(ws2, {
    dxzl_stu_user_id: dyaw_xlfw_zxhd!.dxz_stu_user_id,
    dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
    operate: CHAT_OPERATION.CANCEL
  })
  ChatAudioRef!.close()
}
function handleAuditChatAccept() {
  socketSend(ws2, {
    dxzl_stu_user_id: dyaw_xlfw_zxhd!.dxz_stu_user_id,
    dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
    operate: CHAT_OPERATION.ACCEPT
  })
  // ChatAudioRef!.close()
  auditChatStatus = CHAT_STATUS.CHATING
}
function handleAuditChatDeny() {
  socketSend(ws2, {
    dxzl_stu_user_id: dyaw_xlfw_zxhd!.dxz_stu_user_id,
    dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
    operate: CHAT_OPERATION.DENY
  })
  ChatAudioRef!.close()
}
function handleAuditChatEnd() {
  socketSend(ws2, {
    dxzl_stu_user_id: dyaw_xlfw_zxhd!.dxz_stu_user_id,
    dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
    operate: CHAT_OPERATION.END
  })
  ChatAudioRef!.close()
}


const LocalPlayerContainerRef = $ref<HTMLElement>()
const RemotePlayerContainerRef = $ref<HTMLElement>()
async function handleVideoChatStart() {
  await request({
    url: '/dyaw/xlfw_zxhd/get_rtc_token',
    data: {
      dxz_id: dyaw_xlfw_zxhd?.dxz_id
    }
  }).then(async res => {
    if (res.code === '1') {
      let resp: { jgim_roomid: string; rtc_appid: string; rtc_token: string } = res.data.one_info
      const rtcOptions = {
        appId: resp.rtc_appid,
        channel: resp.jgim_roomid,
        token: resp.rtc_token,
        uid: user.user_id
      }

      let client = rtcInstance.client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });

      client.on("user-published", async (user, mediaType) => {
        // 发起订阅
        await client.subscribe(user, mediaType);

        // 如果订阅的是音频轨道
        if (mediaType === "audio") {
          const audioTrack = user.audioTrack;
          // 自动播放音频
          audioTrack?.play();
        } else {
          const videoTrack = user.videoTrack;
          // 自动播放视频
          videoTrack?.play(RemotePlayerContainerRef as HTMLElement);
        }
      });

      await rtcInstance.client.join(rtcOptions.appId, rtcOptions.channel, rtcOptions?.token, rtcOptions.uid);
      rtcInstance.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
      rtcInstance.localVideoTrack = await AgoraRTC.createCameraVideoTrack();
      await rtcInstance.client.publish([rtcInstance.localAudioTrack, rtcInstance.localVideoTrack]);
      rtcInstance.localVideoTrack.play(LocalPlayerContainerRef as HTMLElement);
    }
  })
  ChatVideoRef!.open()
}

let RtcDialogRef = $ref<typeof import("~/components/rtc-dialog/index.vue")['default']>()
</script>

<template>
  <div class="h-590px bg-hex-f2f2f295 flex justify-center divide-x">
    <div class="w-320px p-10px h-full flex flex-col justify-start bg-white space-y-4">
      <el-input v-model="searchValue" size="large" :prefix-icon="Search" clearable></el-input>
      <div
        class="max-h-520px flex flex-col flex-none divide-y scrollbar scrollbar-thin scrollbar-thumb-rounded-md scrollbar-thumb-gray-200 scrollbar-track-transparent">
        <chat-stu-card v-for="item in dyaw_xlfw_zxhd_list" :d="item" @click="handleClickStuCard(item)"
          class="h-68px"></chat-stu-card>
      </div>
    </div>
    <div class="w-680px h-full divide-y flex flex-col">
      <template v-if="dyaw_xlfw_zxhd">
        <div class="bg-pink-300 flex justify-between h-48px items-center px-18px">
          <span class="text-lg px-1 tracking-wider">{{ dyaw_xlfw_zxhd.dxz_stu_user_realname }}
            {{ dyaw_xlfw_zxhd.dxz_stu_school_name }} {{ dyaw_xlfw_zxhd.dxz_class_name }}</span>
        </div>
        <div ref="scrollbarRef"
          class="bg-hex-fff8fb space-y-2 h-410px py-2 px-6 scrollbar scrollbar-thin scrollbar-thumb-rounded-md scrollbar-thumb-gray-200 scrollbar-track-transparent">
          <div v-show="!cardLoading" @click="handleLoadMoreInfo"
            class="w-full text-center text-sm text-blue-400 hover:underline underline-blue-400 cursor-pointer">查看更多
          </div>
          <info-item v-for="item in infoList" :key="item.dxzl_id" :left="item.create_user_id === user.user_id"
            :d="item"></info-item>
        </div>
        <div class="bg-white h-180px p-5px flex flex-col justify-between">
          <tinymce-area v-model="inputValue" ref="TinyRef" @click:audit="handleAuditChatStart"
            @click:video="handleVideoChatStart"></tinymce-area>
          <div class="flex justify-end">
            <div class="bg-pink-300 text-sm text-white w-80px h-32px flex_center rounded-2xl cursor-pointer"
              @click="handleClickSend">发送</div>
          </div>
        </div>
      </template>
      <template v-else>
        <div class="bg-pink-300 flex justify-between h-48px items-center px-18px"></div>
        <div class="bg-hex-fff8fb flex-auto w-full flex_center">
          <el-empty description="请先选择聊天的学生"></el-empty>
        </div>
      </template>

    </div>
    <div
      class="w-400px h-full bg-white overflow-y-auto flex flex-col items-center px-2 py-2 divide-y scrollbar scrollbar-thin scrollbar-thumb-rounded-md scrollbar-thumb-gray-200 scrollbar-track-transparent">
      <div v-if="dyaw_xlfw_zxhd" :key="dyaw_xlfw_zxhd.dxz_stu_user_id">
        <div class="w-full"
          v-if="archivesList && (archivesList.length === 0 || dyaw_xlfw_zxhd.dxz_id !== archivesList[0].dxz_id)">
          <archives-card storage ref="ArchivesCardRef"
            :d="{ dxz_id: dyaw_xlfw_zxhd.dxz_id, user_id: dyaw_xlfw_zxhd.dxz_stu_user_id, dxxd_lfzxm: dyaw_xlfw_zxhd.dxz_stu_user_realname, dxxd_jfls: dyaw_xlfw_zxhd.dxz_tea_user_realname, dxxd_school_name: dyaw_xlfw_zxhd.dxz_stu_school_name, dxxd_class_name: dyaw_xlfw_zxhd.dxz_class_name, dxxd_date: formatTimestamp(dyaw_xlfw_zxhd.create_dateline) }"></archives-card>
          <div class="flex_center py-2">
            <el-button @click="handleSubmitArchives" type="primary" size="small">提交</el-button>
          </div>
        </div>
        <div class="bg-hex-FFF7FA py-2">
          <div class="flex_center text-lg">历史档案</div>
          <el-empty v-show="archivesList.length === 0" :image-size="60" description="暂无历史档案"></el-empty>
          <archives-card disabled v-for="item in archivesList" :d="item" :key="item.dxz_id"></archives-card>
        </div>
      </div>

    </div>
  </div>

  <chat-dialog ref="ChatAudioRef">
    <div class="h-full flex_center flex-col text-light-50 space-y-4">
      <el-avatar :size="158" :src="dyaw_xlfw_zxhd?.dxx_user_avatar"></el-avatar>
      <div>{{ dyaw_xlfw_zxhd?.dxz_stu_user_realname }}</div>
      <!-- <div class="text-hex-909090 flex_center flex-col space-y-2 h-16"> -->
      <div class="text-hex-909090 flex_center flex-col space-y-2 h-16"
        v-show="auditChatStatus === CHAT_STATUS.WAITING_OTHERS_ACCEPT">
        <div>正在等待对方接受邀请</div>
        <i:line-md:loading-alt-loop class="text-xl" />
      </div>
      <div class="text-hex-909090 flex_center flex-col space-y-2 h-16"
        v-show="auditChatStatus === CHAT_STATUS.WAITING_YOU_ACCEPT">
        <div>邀请你语音通话...</div>
      </div>
      <div class="text-hex-909090 flex_center flex-col space-y-2 h-16"
        v-show="auditChatStatus === CHAT_STATUS.WAITING_BUSY">
        <div class="text-red-500">对方忙线中请等待</div>
        <div class="text-red-500">当前排队：{{ 4 }}</div>
        <i:line-md:loading-alt-loop class="text-xl" />
      </div>
      <div class="text-hex-909090 flex_center flex-col space-y-2 h-16" v-show="auditChatStatus === CHAT_STATUS.CHATING">
        <div>正在通话中</div>
        <div>{{ '00:30' }}</div>
      </div>
      <!-- </div> -->

      <div class="pt-16 text-xl flex justify-around w-full">
        <div v-show="auditChatStatus === CHAT_STATUS.WAITING_YOU_ACCEPT"
          class="bg-green-600 w-12 h-12 rounded-1 cursor-pointer flex items-center justify-around"
          @click="handleAuditChatAccept">
          <i:ic:baseline-phone />
        </div>
        <div v-show="auditChatStatus === CHAT_STATUS.WAITING_YOU_ACCEPT"
          class="bg-red-600 w-12 h-12 rounded-1 cursor-pointer flex items-center justify-around"
          @click="handleAuditChatDeny">
          <i:mdi:phone-hangup />
        </div>
        <div v-show="auditChatStatus === CHAT_STATUS.CHATING"
          class="bg-hex-efefef text-hex-272636 w-12 h-12 rounded-1 cursor-pointer flex items-center justify-around"
          @click="">
          <i:ant-design:audio-outlined v-show="true" />
          <i:ant-design:audio-muted-outlined v-show="false" />
        </div>
        <div v-show="auditChatStatus === CHAT_STATUS.CHATING"
          class="bg-red-600 w-12 h-12 rounded-1 cursor-pointer flex items-center justify-around"
          @click="handleAuditChatEnd">
          <i:ic:outline-close></i:ic:outline-close>
        </div>
        <div
          v-show="auditChatStatus === CHAT_STATUS.WAITING_OTHERS_ACCEPT || auditChatStatus === CHAT_STATUS.WAITING_BUSY"
          class="bg-red-600 w-12 h-12 rounded-1 cursor-pointer flex items-center justify-around"
          @click="handleAuditChatCancel">
          <i:ic:outline-close></i:ic:outline-close>
        </div>

      </div>
    </div>

  </chat-dialog>

  <chat-dialog>
    <div ref="LocalPlayerContainerRef"></div>
    <div ref="RemotePlayerContainerRef"></div>
  </chat-dialog>

  <rtc-dialog ref="RtcDialogRef"></rtc-dialog>

</template>

<style scoped lang="scss">

</style>
