<template>
  <div id="app-container" v-loading="isMeetingLoading" ref="appContainer">
    <div class="row">
      <div class="meeting-container" ref="meetingContainerRef">
        <div id="video-element" ref="videoElementRef"></div>
        <el-button @click="setFullScreen" class="fullscreen-btn">
          全屏</el-button
        >
      </div>
      <div class="chat-right" ref="chatRightRef">
        <messageList :messageList="messages"></messageList>
        <div class="option-bar">
          <el-input
            v-model="editingMessage"
            style="margin-right: 15px"
          ></el-input>
          <el-button
            type="success"
            @click="sendMessage"
            :disabled="editingMessage.length === 0"
            >发送</el-button
          >
        </div>
      </div>
    </div>

    <el-tabs class="tabs" type="border-card">
      <el-tab-pane label="会议介绍">
        <div class="meeting-info meeting-note" v-html="meetingNote"></div>
      </el-tab-pane>
      <el-tab-pane label="会议日程"
        ><div
          class="meeting-info meeting-schedule"
          v-html="meetingSchedule"
        ></div
      ></el-tab-pane>
      <el-tab-pane label="专家介绍"
        ><div class="meeting-info expert-info" v-html="expertInfo"></div
      ></el-tab-pane>
      <el-tab-pane label="聊天" class="chat-pane" v-if="screenWidth < 768"
        ><div class="meeting-info chat">
          <messageList :messageList="messages"></messageList>
          <div class="option-bar">
            <el-input
              v-model="editingMessage"
              style="margin-right: 15px"
            ></el-input>
            <!-- <svg-icon :icon-class="search" style="height: 30px; width: 16px" /> -->
            <el-button
              type="success"
              @click="sendMessage"
              :disabled="editingMessage.length === 0"
              >发送</el-button
            >
          </div>
        </div></el-tab-pane
      >
    </el-tabs>

    <el-dialog
      v-model="showSignDialog"
      :close-on-click-modal="false"
      title="签到"
      width="30%"
    >
      <span>是否确认签到</span>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="submitSign">确定</el-button>
          <el-button type="primary" @click="showSignDialog = false"
            >取消</el-button
          >
        </span>
      </template>
    </el-dialog>
    <questions
      mode="1"
      v-if="showExamDialog"
      :showDialog="showExamDialog"
      @close="showExamDialog = $event"
    ></questions>

    <questions
      mode="2"
      v-if="showQuestionnaireDialog"
      :showDialog="showQuestionnaireDialog"
      @close="showQuestionnaireDialog = $event"
    ></questions>
  </div>
</template>
<script setup>
import {
  computed,
  reactive,
  watch,
  ref,
  onMounted,
  onUnmounted,
  nextTick,
} from "vue";
import { useStore } from "vuex";

import { signMeeting, generateSignature } from "@/api/meeting";
import questions from "@/components/questions";
import messageList from "@/components/messageList";
import dayjs from "dayjs";
import ZoomMtgEmbedded from "@zoomus/websdk/embedded";
import _ from "lodash";

import ReconnectingWebSocket from "reconnecting-websocket";
import { ElMessage, ElMessageBox } from "element-plus";
import { useRoute } from "vue-router";
const route = useRoute();
const store = useStore();

const meetingNote = computed(() => store.getters.meetingNote); // 会议介绍
const meetingSchedule = computed(() => store.getters.meetingSchedule); // 会议日程
const expertInfo = computed(() => store.getters.expertInfo); // 专家信息
const isMeetingLoading = ref(true); // 视频课件是否正在加载
const templateId = ref(6); // 布局 id
if (store.getters.templateId) {
  templateId.value = store.getters.templateId;
}
const joinAccount = ref(""); // 参会账号
const joinName = ref(""); // 参会名称
const screenWidth = ref(0); // 屏幕宽度
const meetingWidth = ref(0); // 视频课件容器元素宽度
const meetingHeight = ref(0); // 视频课件容器元素高度
screenWidth.value = document.body.offsetWidth;

joinAccount.value =
  store.getters.icCard || store.getters.phone || store.getters.nickname;
joinName.value =
  store.getters.nickname || store.getters.phone || store.getters.icCard;

// 设置会议背景大小、图片
const meetingContainerRef = ref(null); // 会议容器元素(包含背景)
const videoElementRef = ref(null); // 视频课件容器元素
const chatRightRef = ref(null); // 右侧聊天元素
onMounted(() => {
  meetingContainerRef.value.style.background = `url(${store.getters.templateBackgroundPic}) 0% 0% / cover no-repeat`; // 设置背景图片
  setTextLabel();
  meetingWidth.value = meetingContainerRef.value.offsetWidth * 0.95; // zoom 会议组件宽度是父元素宽度的 95%
  meetingHeight.value = (meetingWidth.value * 9) / 16; // 根据 zoom 会议组件长宽比 16:9 计算出会议组件高度
  meetingContainerRef.value.style.paddingTop = `${meetingHeight.value * 0.2}px`; // 父元素顶部padding 是会议组件高度的20%
  videoElementRef.value.style.width = meetingWidth.value + "px";
  videoElementRef.value.style.height = meetingHeight.value + "px";
});

// 设置文本标签
const setTextLabel = () => {
  document.querySelectorAll(".text-tag").forEach((el) => {
    el.remove();
  });
  store.getters.textLabelList.forEach((item) => {
    const labelObj = JSON.parse(item.textLabel);
    const textEl = document.createElement("div");
    textEl.id = `${_.uniqueId("tag-")}`;
    textEl.innerHTML = labelObj.content;
    textEl.className = "text-tag";
    textEl.style.backgroundColor = labelObj.backgroundColor;
    textEl.style.visibility =
      labelObj.visibility === "1" ? "visible" : "hidden";
    textEl.style.left = `${labelObj.x}`;
    textEl.style.top = `${labelObj.y}`;
    meetingContainerRef.value.appendChild(textEl);
  });
};

// 会议配置
const meetingConfig = reactive({
  client: ZoomMtgEmbedded.createClient(),
  // This Sample App has been updated to use SDK App type credentials https://marketplace.zoom.us/docs/guides/build/sdk-app
  sdkKey: "99Spa64AWHYVZD95imUpVyMD0KF9CpEIrIb1",
  // meetingNumber: store.getters.meetingNumber,
  meetingNumber: store.getters.meetingNumber,
  passWord: store.state.password,
  // sdkKey: "99Spa64AWHYVZD95imUpVyMD0KF9CpEIrIb1",
  // meetingNumber: "97097842319",
  // passWord: "111916",
  // role: route.name === "Host" ? 1 : 0,
  role: 0,
  // signatureEndpoint: "http://120.26.107.74:4000",
  userEmail: store.getters.email,
  // userEmail: "934510341@qq.com",
  userName: joinName.value,
  // userName: "afasde1",
  // pass in the registrant's token if your meeting or webinar requires registration. More info here:
  // Meetings: https://marketplace.zoom.us/docs/sdk/native-sdks/web/component-view/meetings#join-registered
  // Webinars: https://marketplace.zoom.us/docs/sdk/native-sdks/web/component-view/webinars#join-registered
  // registrantToken:
  //   "Xhi0bKUzyNBnJwe2EJWZ0JZ3IYqtPgyyWE1CXW3z2X4.DQMAAAAWm3t-jxZqSS14R0dCSFRDNkFibVQwakpHbFd3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  registrantToken: store.getters.token,
});
console.log(meetingConfig);

// 生成签名
const getSignature = async () => {
  const { sign } = await generateSignature({
    meetingNumber: store.getters.meetingNumber,
    role: meetingConfig.role,
  });
  console.log(sign);
  startMeeting(sign);
  // axios
  //   .post("http://localhost:4000", {
  //     meetingNumber: store.getters.meetingNumber,
  //     role: meetingConfig.role,
  //   })
  //   .then((res) => {
  //     console.log(res.data.signature);
  //     startMeeting(res.data.signature);
  //   })
  //   .catch((error) => {
  //     console.log(error);
  //   });
};

// 开始会议
const startMeeting = async (signature) => {
  let meetingSDKElement = document.getElementById("video-element");
  try {
    meetingConfig.client.init({
      debug: true,
      zoomAppRoot: meetingSDKElement,
      language: "zh-CN",
      customize: {
        video: {
          isResizable: false,
          popper: {
            disableDraggable: true,
          },
          viewSizes: {
            default: {
              width: meetingWidth.value,
              height: meetingHeight.value - 45,
            },
          },
        },

        meetingInfo: [
          "topic",
          "host",
          "mn",
          "pwd",
          "telPwd",
          "invite",
          "participant",
          "dc",
          "enctype",
        ],
      },
    });

    await meetingConfig.client.join({
      sdkKey: meetingConfig.sdkKey,
      signature: signature,
      meetingNumber: meetingConfig.meetingNumber,
      password: meetingConfig.passWord,
      userName: meetingConfig.userName,
      userEmail: meetingConfig.userEmail,
      tk: meetingConfig.registrantToken,
    });
    document.querySelector("#suspension-view-tab-thumbnail-gallery").click();
    initDesktopLayout();
    isMeetingLoading.value = false;
  } catch (error) {
    isMeetingLoading.value = false;
  }
};
const setFullScreen = () => {
  videoElementRef.value.requestFullscreen();
};
onMounted(() => {
  getSignature();
});
// 初始化
const initDesktopLayout = () => {
  // 初始化高度

  const heightEl = document.querySelectorAll(
    ".zmwebsdk-MuiBox-root.zmwebsdk-MuiBox-root"
  )[2];
  heightEl.style.height = `${meetingHeight.value - 45}px`;
  console.log(meetingHeight.value);

  // 初始化宽度
  document.querySelectorAll(
    ".zmwebsdk-MuiPaper-root.zmwebsdk-MuiPaper-elevation1.zmwebsdk-MuiPaper-rounded"
  )[1].style.width = `${meetingWidth.value - 4}px`;
  // 加载完成显示 video element
  document.querySelector("#video-element").style.visibility = "visible";
};
// 检测屏幕共享开启状态变化
const inSharing = ref(false); // 是否开启屏幕共享
setInterval(() => {
  const elSharing = document.querySelector(
    "div[class*=zmwebsdk-makeStyles-inSharing]"
  );
  if (elSharing) {
    inSharing.value = true;
  } else {
    inSharing.value = false;
  }
}, 500);

const avatarList = ref("");
setInterval(() => {
  const avatarElList = document.querySelectorAll(
    'ul[class^="zmwebsdk-makeStyles-avatarList"] li'
  );
  const arr = [];
  avatarElList.forEach((el) => {
    arr.push({
      videoOn: el.className.includes("videoOn"),
    });
  });
  avatarList.value = arr
    .map((el) => {
      return el.videoOn ? "on" : "off";
    })
    .join(",");
  // console.log(avatarList.value);
}, 500);
watch(avatarList, (val) => {
  if (inSharing.value) {
    document
      .querySelectorAll(`ul[class^="zmwebsdk-makeStyles-avatarList"] li`)
      .forEach((el) => {
        if (el.className.includes("videoOn")) {
          el.style.visibility = "visible";
        } else {
          el.style.visibility = "hidden";
        }
      });
  }
});
// 当观众被设为嘉宾时，摄图会自动改为 ribbon,通过setInterval 监听变化，将其重新设为gallery view
const isRibbon = ref(null);
setInterval(() => {
  isRibbon.value = document.querySelector(
    "#suspension-view-tab-thumbnail-ribbon.zmwebsdk-MuiTab-selected"
  );
}, 500);

watch(isRibbon, (val) => {
  if (val) {
    const galleryViewButton = document.querySelector(
      "#suspension-view-tab-thumbnail-gallery"
    );
    if (galleryViewButton) galleryViewButton.click();
    initDesktopLayout();
  }
});

// 当被设为嘉宾时自动点击同意按钮
setInterval(() => {
  const isSetAsGuest = document.querySelector(
    ".zmwebsdk-MuiButtonBase-root.zmwebsdk-MuiButton-root.zmwebsdk-MuiButton-contained.zmwebsdk-MuiButton-containedPrimary.zmwebsdk-MuiButton-containedSizeSmall.zmwebsdk-MuiButton-sizeSmall.zmwebsdk-MuiButton-disableElevation"
  );
  if (isSetAsGuest) {
    isSetAsGuest.click();
  }
}, 500);

// 根据id设置布局
const setLayout = (templateId) => {
  console.log(templateId);
  const v_s_wrap_el = document.querySelectorAll(
    ".zmwebsdk-MuiBox-root.zmwebsdk-MuiBox-root"
  )[2]; // 包含视频和课件的容器
  v_s_wrap_el.style.flexDirection = "";

  const v_wrap_el = v_s_wrap_el.lastChild;
  if (!inSharing.value) return;

  const s_wrap_el = document.querySelector(
    `div[class*="zmwebsdk-makeStyles-inSharing"]`
  );
  if (templateId === "1") {
    // 课件|视频 对半分
    v_wrap_el.style.width = `${meetingWidth.value / 2 - 2}px`;
  } else if (templateId === "2") {
    // 视频|课件 对半分
    v_wrap_el.style.width = `${meetingWidth.value / 2 - 2}px`;
    v_s_wrap_el.style.flexDirection = "row-reverse";
  } else if (templateId === "3") {
    // 课件|视频 左4/5 | 右边1/5
    v_wrap_el.style.width = `${(meetingWidth.value - 4) / 5}px`;
  } else if (templateId === "4") {
    // 视频|课件 左1/4 | 右边3/4
    v_wrap_el.style.width = `${(meetingWidth.value - 4) / 5}px`;
    v_s_wrap_el.style.flexDirection = "row-reverse";
  } else if (templateId === "5") {
    // 只显示课件
    v_wrap_el.style.display = `none`;
  } else if (templateId === "6") {
    // 只显示视频
    s_wrap_el.style.display = "none";
    v_wrap_el.style.width = `${meetingWidth.value - 4}px`;
  }
};
watch(inSharing, (newVal) => {
  console.log(newVal);
  if (newVal) {
    setLayout(templateId.value);
  } else {
    const galleryViewButton = document.querySelector(
      "#suspension-view-tab-thumbnail-gallery"
    );
    if (galleryViewButton) galleryViewButton.click();
    const v_s_wrap_el = document.querySelectorAll(
      ".zmwebsdk-MuiBox-root.zmwebsdk-MuiBox-root"
    )[2];
    if (!v_s_wrap_el) return;
    const v_wrap_el = v_s_wrap_el.lastChild;
    v_wrap_el.style.width = "";
    v_s_wrap_el.style.flexDirection = "";
  }
});

let socket = reactive({});
const initWebSocket = () => {
  // 建立websocket连接
  socket = new ReconnectingWebSocket(
    `wss://meeting.chuhuankj.com/wss/websocket/meeting/${store.getters.meetingId}/${joinAccount.value}`
  );
  socket.addEventListener("open", () => {
    // socket.send("Hello Server!");
    console.log("websocket,已连接");
  });

  // 监听websocket消息
  socket.addEventListener("message", async (event) => {
    const data = JSON.parse(JSON.parse(event.data));
    console.log(data);
    // 会议信息更新时
    if (data.type === "isRefreshMeeting") {
      await store.dispatch("getMeetingInfo", store.getters.meetingId);
      meetingContainerRef.value.style.background = ` url(${store.getters.templateBackgroundPic}) 0% 0% / cover no-repeat`;
      templateId.value = store.getters.templateId;
      setLayout(templateId.value);
      setTextLabel();
    }
    // 开始签到时
    else if (data.type === "isStartSign") {
      console.log(data);
      showSignDialog.value = true;
    }
    // 签到结束时
    else if (data.type === "isEndSign") {
      showSignDialog.value = false;
    }
    // 收到聊天消息时
    else if (data.type === "isChat") {
      console.log(JSON.parse(JSON.parse(JSON.parse(data.content).msg)));
      messages.value.push({
        ...JSON.parse(JSON.parse(JSON.parse(data.content).msg)),
        id: _.uniqueId(),
        time: dayjs().format("YYYY-MM-DD HH:mm:ss"),
      });
    }
    // 开始考试时
    else if (data.type === "isStartExam") {
      showExamDialog.value = true;
    }
    // 开始问卷时
    else if (data.type === "isStartQuestionnaire") {
      showQuestionnaireDialog.value = true;
    }
    // 会议结束时
    else if (data.type === "isCloseMeeting") {
      showExamDialog.value = false;
      showQuestionnaireDialog.value = false;
      ElMessageBox.alert("会议已结束");
      socket.close();
    }
  });
  socket.addEventListener("close", (event) => {
    console.log(event, "close");
  });
  socket.addEventListener("error", (event) => {
    console.log(event, "error");
  });
};
initWebSocket();
/* 签到功能 */
// 提交签到
const showSignDialog = ref(false); //是否显示签到窗口
const submitSign = async () => {
  await signMeeting({
    meetingId: store.getters.meetingId,
    signTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
    account: joinAccount.value,
  });
  showSignDialog.value = false;
  ElMessage.success("签到成功");
};

/* 聊天功能 */
const messages = ref([]); // 消息列表
const editingMessage = ref(""); // 正在编辑的内容
// 发送消息
const sendMessage = () => {
  console.log(
    JSON.stringify(
      JSON.stringify({
        account: joinName.value,
        msg: editingMessage.value,
      })
    )
  );
  socket.send(
    JSON.stringify(
      JSON.stringify({
        account: joinName.value,
        msg: editingMessage.value,
      })
    )
  );
  // socket.send(editingMessage.value);
  messages.value.push({
    id: _.uniqueId(),
    account: joinName.value,
    msg: editingMessage.value,
    isMe: true,
    time: dayjs().format("YYYY-MM-DD HH:mm:ss"),
  });
  editingMessage.value = "";
};

const leaveConference = () => {
  meetingConfig.client.leaveMeeting();
};
window.addEventListener("beforeunload", leaveConference);
onUnmounted(() => {
  window.removeEventListener("beforeunload", leaveConference);
});

// 是否显示考试和问卷弹窗
const showExamDialog = ref(false);
const showQuestionnaireDialog = ref(false);
</script>
<style scoped lang="scss">
#app-container {
  width: 100%;
  margin: 0 auto;
  :deep(.text-tag) {
    position: absolute;
    z-index: 999;
    border-radius: 4px;
    padding: 5px;
    background-color: #fff;
    * {
      margin: 0;
      padding: 0;
    }
  }
}

.row {
  width: 100%;
  display: flex;
}
.meeting-container {
  position: relative;
  width: 80%;
  display: flex;
  justify-content: center;
}

.chat-right {
  width: 20%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  .option-bar {
    margin-top: 0;
    margin: 5px;
  }
  :deep(.message-list) {
    overflow-y: scroll;
    margin-bottom: 0;
    // height: 80%;
    flex: 1;
    p {
      margin: 0;
    }
  }
}

@media screen and (max-width: 768px) {
  .meeting-container {
    width: 100%;
  }
  .chat-right {
    display: none;
  }
}
#video-element {
  // visibility: hidden;
  // height: 600px;
}

.tabs {
  width: 100%;
  .meeting-info {
    :deep(p) {
      margin: 0;
    }
  }
  // :deep(.el-tabs__content) {
  //   .chat {
  //   }
  // }
}
.option-bar {
  display: flex;
  align-items: center;
  justify-content: space-around;
}
:deep(.zmwebsdk-MuiPaper-root) {
  background: transparent;
  box-shadow: 0 0;
}

:deep(.zmwebsdk-MuiToolbar-root) {
  display: none;
}
:deep(.zmwebsdk-makeStyles-singleView-7) {
  // background-color: transparent;
  padding: 0;
}
:deep(.zmwebsdk-MuiPaper-root.zmwebsdk-makeStyles-root-50.zmwebsdk-MuiPaper-elevation1.zmwebsdk-MuiPaper-rounded) {
  width: 20%;
  background: #ccc;
}
.fullscreen-btn {
  position: absolute;
  right: 0;
  bottom: 0;
}
</style>
