<template>
  <div
    class="seats_box"
    v-loading="loading"
    element-loading-text="加载中..."
    element-loading-svg-view-box="-10, -10, 50, 50"
    element-loading-background="rgba(122, 122, 122, 0.1)"
  >
    <div class="seats_container">
      <div
        v-for="(item, index) in seatsList"
        class="seats_item"
        ref="textRefs"
        @click="handleClick(index, item)"
      >
        <img
          src="@/assets/img/seats/service.png"
          alt=""
          class="seats_item_service"
        />
        <p class="seats_item_tel">{{ item.telNo }}</p>
        <p class="seats_item_name" v-if="item.state === 'logout'">未登录</p>
        <p class="seats_item_name" v-else>
          {{ item.workUserName ? item.workUserName : "未知" }}
        </p>
        <span @click.stop>
          <el-dropdown
            @command="handleCommand($event, item)"
            class="seats_item_dropdown"
            trigger="click"
            v-if="item.state === 'busy' && globalState.callCenterIsSignIn"
          >
            <el-icon class="seats_item_more" size="18">
              <Operation />
            </el-icon>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item command="listen">监 听</el-dropdown-item>
                <el-dropdown-item command="interject">插 话</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </span>
        <div class="seats_item_state">
          <img :src="getImageUrl('seats/' + item.state + '.png')" alt="" />
          <span class="seats_item_telNo">
            {{ currentStatusText(item.state) }}</span
          >
        </div>
      </div>
    </div>

    <el-popover
      ref="popoverRef"
      :virtual-ref="textRef"
      :visible="hidePopover"
      virtual-triggering
      placement="right-start"
      @hide="popoverHide"
      width="220"
      popper-class="call_popover_popper"
    >
      <template #default>
        <div v-click-outside="onClickOutside" class="call_popover">
          <div class="call_popover_item">
            <span class="label">坐席名称：</span>{{ call.workUserName }}
          </div>
          <div class="call_popover_item">
            <span class="label">分机号：</span>{{ call.telNo }}
          </div>
          <div class="call_popover_item">
            <span class="label">通话时长：</span
            ><span v-if="talkTime">{{ formatDuration(talkTime) }}</span>
          </div>
          <div class="call_popover_item">
            <span class="label">呼入类型：</span>
            <el-text v-if="call.callDirection === 'inbound'">呼入</el-text>
            <el-text v-if="call.callDirection === 'outbound'">外呼</el-text>
            <i></i>
          </div>
          <div class="call_popover_item">
            <span class="label">电话号码：</span>{{ call.otherNumber }}
          </div>
          <div class="call_popover_item">
            <span class="label">今日接听量：</span>{{ call.onStateCount }}
          </div>
        </div>
      </template>
    </el-popover>
  </div>
</template>
<script setup lang="ts">
import { onMounted, ref, nextTick, onBeforeUnmount, watch } from "vue";
import { getImageUrl } from "@/utils/tools";
import signalR from "@/utils/signalR";
import { ClickOutside as vClickOutside } from "element-plus";
import { formatDuration } from "@/utils/formatTime";
import dayjs from "dayjs";
import { getExtensionStatus } from "api/seats";
import { useIntervalFn } from "@vueuse/core";
import { useGlobalState } from "@/utils/callCenter";
import { Operation } from "@element-plus/icons-vue";
import mittBus from "@/utils/mitt";

const props = defineProps({
  data: {
    type: Array,
    default: () => [],
  },
});

const textRefs = ref<EmptyArrayType>([]);
const textRef = ref();
const popoverRef = ref();
const hidePopover = ref(false);
const call = ref<EmptyObjectType>({});
const globalState = useGlobalState();
// 开始签入时长
const talkTime = ref<any>(0); // 通话时长
const talkTimer = ref<any>(null); // 通话时长定时器
const startCallTimer = (second: any) => {
  if (second) {
    // 从后台获取签入时长
    if (second < 0) second = 0; // 防止后台返回的签入时间大于当前时间
    talkTime.value = second;
    talkTimer.value = useIntervalFn(() => {
      talkTime.value++;
    }, 1000);
  } else {
    talkTimer.value = useIntervalFn(() => {
      talkTime.value++;
    }, 1000);
  }
};
const handleClick = (index: number, item: { state: string; telNo: string }) => {
  textRef.value = textRefs.value[index];
  call.value = item;
  talkTime.value = 0;
  if (talkTimer.value) talkTimer.value.pause();
  if (["busy", "held"].includes(item.state)) {
    getExtensionStatus({ telno: item.telNo }).then((res: any) => {
      hidePopover.value = true;
      call.value = res.result;
      // 获取现在时间与签入时间的秒数
      talkTime.value = dayjs().diff(dayjs(res.result.answeredAt), "second");
      startCallTimer(talkTime.value);
    });
  } else {
    talkTime.value = 0;
    call.value.otherNumber = "";
  }
};
// 隐藏弹窗
const popoverHide = () => {
  if (talkTimer.value) talkTimer.value.pause();
};
const onClickOutside = () => {
  hidePopover.value = false;
};
// 设置当前状态的值
const currentStatusText = (state: string) => {
  const statusMap: any = {
    logout: "签出",
    login: "签入",
    ready: "示闲",
    unready: "小休",
    ring: "振铃中",
    busy: "通话中",
    acw: "整理",
    held: "保持",
    treeWay: "三方会议",
  };
  return statusMap[state] || "";
};
const seatsList = ref<any>([]);
watch(
  () => props.data,
  (newData: any) => {
    seatsList.value = newData;
  },
  { immediate: true }
);
const loading = ref(false);
// 对当前状态进行排序
const sortSeatsList = () => {
  // 通话中的排序
  const busyData = seatsList.value.filter((item: any) => item.state === "busy");
  // 通话中的排序
  const ringData = seatsList.value.filter((item: any) => item.state === "ring");
  // 话后整理
  const acwData = seatsList.value.filter((item: any) => item.state === "acw");
  // 保持
  const heldData = seatsList.value.filter((item: any) => item.state === "held");
  // 三方会议
  const treeWayData = seatsList.value.filter(
    (item: any) => item.state === "treeWay"
  );
  // 小休
  const unreadyData = seatsList.value.filter(
    (item: any) => item.state === "unready"
  );
  // 示闲
  const readyData = seatsList.value.filter(
    (item: any) => item.state === "ready"
  );
  // 签出
  const logoutData = seatsList.value.filter(
    (item: any) => item.state === "logout"
  );
  seatsList.value = [
    ...busyData,
    ...ringData,
    ...readyData,
    ...acwData,
    ...heldData,
    ...treeWayData,
    ...unreadyData,
    ...logoutData,
  ];
};
onMounted(async () => {
  await nextTick();
  // await getSeatsList();
  // 接收消息
  signalR.SR.on("SeatState", (res: any) => {
    const item = seatsList.value.find((item: any) => item.telNo === res.telNo);
    item.loading = true;
    if (item) {
      setTimeout(() => {
        item.state = res.state;
        item.workUserName = res.workUserName;
        item.workUserId = res.workUserId;
        item.loading = false;
        sortSeatsList();
        // hidePopover.value = false;
      }, 500);
    }
  });
  mittBus.on("monitorInfo", (data: any) => {
    console.log("1111", data);
  });
});
// 监听和插话消息
const handleCommand = (command: string, item: any) => {
  console.log(command, item);
  if (command === "listen") {
    // 监听
    globalState.callCenterWs.monitor(
      item.telNo,
      globalState.callCenterWs.username
    );
  } else if (command === "interject") {
    // 强插
    globalState.callCenterWs.intercept(
      item.telNo,
      globalState.callCenterWs.username
    );
  }
};
onBeforeUnmount(() => {
  signalR.SR.off("SeatState");
});
</script>
<style scoped lang="scss">
.seats_box {
  width: 100%;
  overflow: auto;
  height: 100%;

  .seats_container {
    display: grid;
    grid-template-columns: repeat(auto-fill, 100px);
    grid-gap: 20px;

    .seats_item {
      width: 100px;
      border: 1px solid var(--el-color-primary-light-3);
      border-radius: 8px;
      text-align: center;
      padding: 7px 0;
      animation: bounce-out 0.3s ease;
      position: relative;
      cursor: pointer;
      &_service {
        margin: 0 auto;
        width: 40px;
      }

      &_tel {
        font-size: var(--el-font-size-medium);
        color: var(--el-color-white);
        margin-top: 8px;
      }

      &_dropdown {
        position: absolute;
        top: 5px;
        right: 10px;
        outline: none;
      }

      &_more {
        cursor: pointer;
      }

      &_name {
        font-size: var(--el-font-size-medium);
        color: var(--el-color-white);
        margin-top: 5px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        padding: 0 5px;
      }

      &_state {
        display: flex;
        align-items: center;
        justify-content: center;
        margin-top: 8px;

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

        .seats_item_telNo {
          font-size: var(--el-font-size-medium);
          color: var(--el-color-white);
          margin-left: 5px;
        }
      }
    }
  }
}

.call_popover_popper {
  .call_popover {
    .call_popover_item {
      margin-bottom: 5px;
      .label {
        display: inline-block;
        width: 90px;
        text-align: right;
      }
    }
  }
}
</style>
