<template>
  <div class="outer-person-container">
    <div class="container-title">
      <span class="line"></span>
      <span class="title">保密要害部位监控</span>
      <el-tooltip effect="dark" placement="right">
        <span class="position-count">{{ positionCameraCount }}</span>
        <template #content>
          <span>共{{ positionCameraCount }}个监控位置</span>
        </template>
      </el-tooltip>
    </div>
    <div class="monitor-chart">
      <div class="monitor-area">
        <div class="has-main-camera" v-if="curPlayPositionCamera && getCameraUrl(curPlayPositionCamera)">
          <LiveVideo
            :url="getCameraUrl(curPlayPositionCamera)"
            :poster="getCameraImg(curPlayPositionCamera)"
            :id="`monitor-livevideo`"
            class="main-video"
          />
          <el-icon class="switch-icon" @click="switchCameraPage = true"><Switch /></el-icon>
          <div class="monitor-info">
            <img src="@/assets/images/disaster-overview/camera.png" alt="" />
            <span class="camera-name" :title="curPlayPositionCamera?.positionName + '-' + curPlayPositionCamera?.name"
              >{{ curPlayPositionCamera?.positionName }}-{{ curPlayPositionCamera?.name }}</span
            >
            <img
              src="@/assets/images/disaster-overview/full-screen.png"
              alt=""
              class="full-screen"
              @click="isFullScreen ? exitFullscreen() : fullScreen(`monitor-livevideo`, 'overview-monitor')"
            />
          </div>
        </div>
        <div class="no-main-camera" v-if="!curPlayPositionCamera || !getCameraUrl(curPlayPositionCamera)">
          <img class="cameraEmptyImg" src="@/assets/icons/nine-square-grid/cameraEmpty.png" />
          <span>暂无保密要害部位监控</span>
        </div>
        <div class="switch-camera-page" v-if="switchCameraPage">
          <el-icon class="close-icon" @click="switchCameraPage = false"><CloseBold /></el-icon>
          <div class="switch-camera-page-content">
            <div
              class="switch-camera-page-content-item"
              :class="{
                active:
                  curPlayPositionCamera?.id === item.id && curPlayPositionCamera?.positionName === item.positionName,
              }"
              v-for="item in confidentialityPositionCameraInfo"
              :key="item.id"
              @click="switchCamera(item)"
              >{{ item.positionName }}-{{ item.name }}</div
            >
          </div>
        </div>
      </div>
      <div class="chart-area">
        <ConfidentialityPositionChart />
      </div>
    </div>
    <div class="invasion-snapshot-list">
      <div class="invasion-snapshot-list-title"> 近30日抓拍记录明细表 </div>
      <div class="invasion-snapshot-list-table">
        <div class="invasion-snapshot-list-content" ref="scrollContainer" @scroll="handleScroll">
          <div class="snapshot-table">
            <div class="table-header">
              <div class="table-cell">序号</div>
              <div class="table-cell">事件</div>
              <div class="table-cell left-align">地点</div>
              <div class="table-cell">抓拍照片</div>
              <div class="table-cell left-align">抓拍时间</div>
            </div>
            <div class="table-body">
              <div v-for="(item, index) in invasionSnapshotList" :key="item.id" class="table-row">
                <div class="table-cell">{{ index + 1 }}</div>
                <div class="table-cell">{{ item.event }}</div>
                <div class="table-cell left-align">{{ item.location }}</div>
                <div class="table-cell"><ImageViewer :file-list="item.pictures" /></div>
                <div class="table-cell left-align">{{ item.eventTime }}</div>
              </div>
            </div>
          </div>
          <!-- 加载状态 -->
          <div v-if="loading" class="loading-container">
            <el-icon class="is-loading"><Loading /></el-icon>
            <span>加载中...</span>
          </div>
          <!-- 没有更多数据 -->
          <div v-if="!hasMore && invasionSnapshotList.length > 0" class="no-more-data">没有更多数据了</div>
          <!-- 空状态 -->
          <div v-if="!loading && invasionSnapshotList.length === 0" class="empty-state">
            <el-icon><Picture /></el-icon>
            <span>暂无抓拍记录</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { onMounted, onUnmounted, ref, nextTick } from 'vue';
  import { storeToRefs } from 'pinia';
  import screenfull from 'screenfull';
  import urlJoin from 'url-join';
  import { Switch, CloseBold, Loading, Picture } from '@element-plus/icons-vue';
  import LiveVideo from '@/components/live/LiveVideo.vue';
  import ImageViewer from '@/views/traffic/violation/act/components/ImageViewer.vue';
  import ConfidentialityPositionChart from './ConfidentialityPositionChart.vue';
  import { userSplitScreenFullScreen } from '@/store/modules/userSplitScreenFullScreen';
  import { CameraInfo } from '@/api/disaster-overview';
  import {
    getConfidentialityPositionList,
    getInvasionSnapshotList,
    type QueryInvasionSnapshotRes,
  } from '@/api/security-confidentiality-position';
  import dayjs from 'dayjs';

  const { isFullScreen, curFullScreenType } = storeToRefs(userSplitScreenFullScreen());
  const { fullScreen, exitFullscreen } = userSplitScreenFullScreen();

  interface ConfidentialityPositionCameraInfo extends CameraInfo {
    positionName: string;
  }

  const positionCameraCount = ref(0);
  const confidentialityPositionCameraInfo = ref<ConfidentialityPositionCameraInfo[]>([]);
  const curPlayPositionCamera = ref<ConfidentialityPositionCameraInfo>();
  const switchCameraPage = ref(false);

  // 入侵抓拍记录相关状态
  const invasionSnapshotList = ref<QueryInvasionSnapshotRes[]>([]);
  const loading = ref(false);
  const hasMore = ref(true);
  const currentPage = ref(1);
  const pageSize = ref(20);
  const scrollContainer = ref<HTMLElement>();

  // 计算近30天的时间范围
  const getLast30DaysTimeRange = () => {
    return {
      startTime: dayjs().subtract(29, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss'),
      endTime: dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss'),
    };
  };

  const isHttps = () => {
    return window.location.protocol.startsWith('https');
  };

  const getCameraUrl = (val: ConfidentialityPositionCameraInfo) => {
    if (val.pushStreamDTO && val.pushStreamDTO.videoUrls) {
      const videoUrl = val.pushStreamDTO.videoUrls.pushstreamIp;
      const protocol = isHttps() ? 'wss' : 'ws';
      // 如果是绝对地址
      if (videoUrl.startsWith('http')) {
        // 如果是https的话，websocket要用wss
        return videoUrl.replace('http', protocol);
      }
      const u = urlJoin(
        `${protocol}://`,
        window.location.host,
        window.location.pathname === '/' ? '' : window.location.pathname,
        videoUrl,
      );
      return u;
    }
    return '';
  };

  const getCameraImg = (val: ConfidentialityPositionCameraInfo) => {
    if (val.pushStreamDTO && val.pushStreamDTO.imageUrl) {
      return val.pushStreamDTO.imageUrl;
    }
    return '';
  };

  const switchCamera = (item: ConfidentialityPositionCameraInfo) => {
    curPlayPositionCamera.value = item;
    switchCameraPage.value = false;
  };

  // 获取入侵抓拍记录数据
  const loadInvasionSnapshotData = async (isLoadMore = false) => {
    if (loading.value) return;

    loading.value = true;
    try {
      const timeRange = getLast30DaysTimeRange();
      const response = await getInvasionSnapshotList({
        pageNumber: isLoadMore ? currentPage.value : 1,
        pageSize: pageSize.value,
        queryParam: {
          startTime: timeRange.startTime,
          endTime: timeRange.endTime,
        },
      });

      if (isLoadMore) {
        invasionSnapshotList.value = [...invasionSnapshotList.value, ...response.records];
      } else {
        invasionSnapshotList.value = response.records;
        currentPage.value = 1;
      }

      hasMore.value = response.records.length === pageSize.value;
      if (hasMore.value) {
        currentPage.value++;
      }
    } catch (error) {
      console.error('获取入侵抓拍记录失败:', error);
    } finally {
      loading.value = false;
    }
  };

  // 无限滚动处理
  const handleScroll = () => {
    if (!scrollContainer.value || loading.value || !hasMore.value) return;

    const { scrollTop, scrollHeight, clientHeight } = scrollContainer.value;
    // 当滚动到距离底部50px时触发加载
    if (scrollTop + clientHeight >= scrollHeight - 50) {
      loadInvasionSnapshotData(true);
    }
  };

  onMounted(() => {
    getConfidentialityPositionList({
      groupName: '',
      cameraName: '',
    }).then((res) => {
      confidentialityPositionCameraInfo.value = res.flatMap((item) => {
        return item.children.map((child) => ({
          ...child,
          positionName: item.groupName,
        }));
      });
      positionCameraCount.value = confidentialityPositionCameraInfo.value.length;
      curPlayPositionCamera.value = confidentialityPositionCameraInfo.value[0] ?? undefined;
    });

    // 加载入侵抓拍记录数据
    loadInvasionSnapshotData();

    // 绑定滚动事件监听器
    nextTick(() => {
      if (scrollContainer.value) {
        scrollContainer.value.addEventListener('scroll', handleScroll);
      }
    });
  });

  window.onresize = () => {
    if (!screenfull.isFullscreen) {
      isFullScreen.value = false; //判断退出全屏，进行赋值
      curFullScreenType.value = 'single';
    }
  };

  onUnmounted(() => {
    window.onresize = null;
    // 清理滚动事件监听
    if (scrollContainer.value) {
      scrollContainer.value.removeEventListener('scroll', handleScroll);
    }
  });
</script>

<style scoped lang="scss">
  .container-title {
    height: 24px;
    display: flex;
    align-items: center;
    font-weight: 500;
    font-size: 16px;
    color: #000000;

    .line {
      width: 3px;
      height: 16px;
      background: #1777ff;
      margin-right: 10px;
    }

    .title {
      margin-right: 12px;
    }
  }

  .position-count {
    font-size: 18px;
    color: #1777ff;
    text-shadow: 0 0 10px #1777ff;
  }

  .outer-person-container {
    width: 100%;
    height: 100%;
    padding: 14px 0;
    overflow: auto;
  }

  .monitor-chart {
    height: 274px;
    margin: 0 15px 11px 15px;
    padding: 16px 0;
    border-bottom: 1px dashed #c0c4cc;
    display: flex;

    .monitor-area {
      width: 50%;
      height: 100%;
      margin-right: 10px;
      position: relative;

      .has-main-camera {
        width: 100%;
        height: 100%;
        background-color: #000000;
        border-radius: 8px;

        .main-video {
          height: 100%;
        }

        .switch-icon {
          position: absolute;
          top: 10px;
          right: 10px;
          cursor: pointer;
          color: #ffffff;
        }

        .switch-icon:hover {
          color: #1777ff;
        }

        .monitor-info {
          width: 100%;
          position: absolute;
          bottom: 0px;
          left: 0px;
          display: flex;
          align-items: center;
          padding: 5px 10px;
          background: rgba(0, 0, 0, 0.2);
          border-radius: 8px;
          color: #fff;
          gap: 10px;
        }

        .camera-name {
          flex: 1;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
          max-width: 100%;
        }

        .full-screen {
          margin-left: auto;
          cursor: pointer;
        }
      }

      .no-main-camera {
        height: 100%;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 20px;
        color: #999;

        img {
          height: 80%;
        }
      }

      .switch-camera-page {
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.2);
        backdrop-filter: blur(10px);
        z-index: 100;
        position: absolute;
        top: 0;
        left: 0;
        display: flex;
        flex-direction: column;
        padding-bottom: 10px;
        color: #ffffff;
        border-radius: 8px;

        .close-icon {
          margin: 10px 10px 10px auto;
          font-size: 20px;
          cursor: pointer;
        }

        .close-icon:hover {
          color: #1777ff;
        }

        .switch-camera-page-content {
          flex: 1;
          padding: 0 20px;
          overflow: auto;
          display: flex;
          flex-direction: column;
          gap: 10px;
        }

        .switch-camera-page-content-item {
          word-wrap: break-word;
          cursor: pointer;
          padding: 5px 10px;
          border-radius: 5px;
          background-color: rgba(255, 255, 255, 0.2);
          transition: all 0.3s;
        }

        .switch-camera-page-content-item:hover,
        .switch-camera-page-content-item.active {
          background-color: rgba(255, 255, 255, 0.4);
          box-shadow: 0 0 10px rgba(255, 255, 255, 0.4);
          transform: scale(1.03);
        }

        .switch-camera-page-content-item:active {
          background-color: rgba(255, 255, 255, 0.4);
          box-shadow: 0 0 10px rgba(255, 255, 255, 0.4);
          transform: scale(0.98);
        }
      }
    }

    .chart-area {
      width: calc(100% - 50% - 10px);
      height: 100%;
    }
  }

  .invasion-snapshot-list {
    width: 100%;
    height: calc(100% - 274px - 24px - 11px);
    padding: 0 15px;

    .invasion-snapshot-list-title {
      font-size: 16px;
      font-weight: 500;
      color: #000000;
      margin-bottom: 12px;
    }

    .invasion-snapshot-list-table {
      width: 100%;
      height: calc(100% - 24px);
      min-height: 220px;
    }

    .invasion-snapshot-list-content {
      width: 100%;
      height: calc(100% - 20px);
      min-height: 200px;
      background-color: #f5f7fa;
      border-radius: 8px;
      overflow-y: auto;
      margin-bottom: 12px;

      .snapshot-table {
        width: 100%;
        background-color: #ffffff;
        border-radius: 8px;
        overflow: hidden;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

        .table-header {
          display: grid;
          grid-template-columns: 60px 140px 1fr 150px 1fr;
          background-color: #f8f9fa;
          border-bottom: 1px solid #e9ecef;

          .table-cell {
            padding: 12px 8px;
            font-weight: 500;
            font-size: 14px;
            color: #333;
            text-align: center;
            border-right: 1px solid #e9ecef;

            &:last-child {
              border-right: none;
            }
          }

          .left-align {
            text-align: left;
            padding: 12px 28px;
          }
        }

        .table-body {
          .table-row {
            display: grid;
            grid-template-columns: 60px 140px 1fr 150px 1fr;
            border-bottom: 1px solid #f0f0f0;
            transition: background-color 0.2s;

            &:hover {
              background-color: #f8f9fa;
            }

            &:last-child {
              border-bottom: none;
            }

            .table-cell {
              padding: 12px 8px;
              font-size: 13px;
              color: #666;
              text-align: center;
              border-right: 1px solid #f0f0f0;
              display: flex;
              align-items: center;
              justify-content: center;
              word-break: break-all;

              &:last-child {
                border-right: none;
              }
            }

            .left-align {
              justify-content: left;
              padding: 0 28px;
            }
          }
        }
      }

      .loading-container {
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 20px;
        color: #666;
        gap: 8px;

        .is-loading {
          animation: rotate 1s linear infinite;
        }
      }

      .no-more-data {
        text-align: center;
        padding: 10px;
        color: #999;
        font-size: 14px;
      }

      .empty-state {
        height: calc(100% - 45px);
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        color: #999;
        gap: 12px;

        .el-icon {
          font-size: 48px;
          color: #ddd;
        }
      }
    }
  }

  @keyframes rotate {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(360deg);
    }
  }
</style>
