<script setup lang="tsx">
import { computed, ref, onMounted, reactive, nextTick, watch } from 'vue';
import { useAppStore } from '@/store/modules/app';
import { ArrowLeft20Filled } from '@vicons/fluent';
import { useMessage, NConfigProvider, darkTheme, NButton, NImage, NSpace, NTag, useNotification, NDropdown, NRow, NCol, NEllipsis } from "naive-ui"
import HeaderBanner from './modules/header-banner.vue';
import CardData from './modules/card-data.vue';
import LineChart from './modules/line-chart.vue';
import RingChart from './modules/ring-chart.vue';
import PieChart from './modules/pie-chart.vue';
import ProjectNews from './modules/project-news.vue';
import CreativityBanner from './modules/creativity-banner.vue';
import { useRouter } from 'vue-router';
import { localStg } from '@/utils/storage';
// // api_logCount api_taskCount  api_pointsCount
import { api_logCount, api_modifyAlarmLog, api_getCameraList, api_getAreaNode, api_taskCount, api_pointsCount, api_getAlarmLog } from '@/api/index.ts'
import JSMpeg from '@cycjimmy/jsmpeg-player';
import fullScreen from '@/utils/full'
// import { wx } from '@/index.vue'


const serviceUrl = import.meta.env.VITE_VIDEO_URL;
const apiUrl = import.meta.env.VITE_SERVICE_URL;
const webSocketUrl = import.meta.env.VITE_WEBSOCKET_URL;


const router = useRouter();
const appStore = useAppStore();
const message = useMessage();

// notification
const notification = useNotification();

const gap = computed(() => (appStore.isMobile ? 0 : 16));

const s = ref<[number, number]>([1183135260000, Date.now()]);

let jsmpeg = ref(false);


const tableData = ref([]);
// 获取日志
const getAlarmLog = async () => {
  const param = {
    pageNum: 1,
    pageSize: 10
  };

  await api_getAlarmLog(param).then(res => {
    if (res.data.code === 200) {
      tableData.value = res.data.data.records;
    }
  });
};

const stop = () => {
  jsmpeg.value.pause();
};

const start = () => {
  jsmpeg.value.play();
}

const cameraList = ref([]);
// 获取区域
const getCameraList = async () => {
  const params = {
    pageNum: 1,
    pageSize: 10000,
    resourceNo: '100001000000000'
  };
  await api_getCameraList(params).then(res => {
    if (res.data.code === 200) {
      cameraList.value = res.data.data.records;
      cameraList.value.length > 0 && switchVideoPalyer(cameraList.value[0].id);
    }
  });
};

const htmlStr = ref('');
const audioId = ref('');

const playAudio = async (id: string) => {
  /**
   *  1. 接口形式并非准确的资源形式形式
   *  2. 模板的形式， 特殊处理
   *  3. 动态js网络链接不上
   */


  htmlStr.value = `<audio ref="audioE"  id="aWrap" controls>
         <source  id="audio" src="${apiUrl}/v1/play/${id}" type="audio/mpeg"></source>
    </audio>`;

  nextTick(() => {
    let a = document.getElementById('aWrap');
    a?.play();
  });
};

const cId = ref('');
const cName = ref('');
const switchVideoPalyer = (id: string) => {
  cId.value = id;
  let camera = cameraList.value.filter(item => item?.id === id)[0];

  console.log("======================================= id", id, camera?.cameraAddress);

  // if (!camera?.cameraAddress?.includes('rtsp://')) {
  //   return message.error('摄像头流地址格式有误!');
  // }


  cName.value = camera.cameraName;

  jsmpeg.value && jsmpeg.value.destroy();

  nextTick(() => {
    try {
      const rtsp1 = camera.cameraAddress;
      jsmpeg.value = new JSMpeg.Player(
        `${serviceUrl}/rtsp?url=${btoa(rtsp1)}&-s=1920x1080&fps=30`,
        {
          canvas: document.getElementById('canvas-4'),
          preserveDrawingBuffer: true,
          controls: true,
          videoBufferSize: 1024 * 1024 * 2
        }
      );
    } catch (e) {
      console.log("======================================= error", e);
    }
  });
};

const range = ref<[number, number]>([Date.now() - 86400000 * 30, Date.now()]);


const options = [
  {
    label: '10分钟内不在提醒！',
    key: '10',
    props: {
      onClick: () => {
        message.success('Good!')
      }
    }
  },
  {
    label: '30分钟内不在提醒！',
    key: '30',
    props: {
      onClick: () => {
        message.success('Good!')
      }
    }
  },
  {
    label: '关闭弹窗提醒',
    key: 'close',
    props: {
      onClick: () => {
        message.success('Good!')
      }
    }
  }
];
const handleSelect = (key: string) => {
  console.log(key);
};

// 变更状态
const modifyAlramStatus = async (id: string, status: string) => {
  await api_modifyAlarmLog(id, status).then(res => {
    if (res.data.code === 200) {
      message.success(res.data.msg)
    } else {
      message.error(res.data.msg)
    }
  })
};


const showTipModal = ref(false);


const logInfo = ref({
  algorithmGrade: 0,
  algorithmName: 0,
  createTime: 0,
  id: 0,
  image: '',
  remark: '',
  reminderType: "",
  status: "",
  videoName: ""
});

const toLogPage = (id: string) => {
  router.push({
    path: `/alarmcenter/alarmlog?id=${id}`,
  })
}

let showModal = ref(false);
const isDefaultPreview = ref(false);
let cLogInfo = reactive({});

// 切换视频播放源头
const switchVideoPlayer = () => {
  console.log("switchVideoPlayer ==============", "rtsp://admin:gemho10-7@192.168.0.56:554/h264/ch1/main/av_stream`")
  // nextTick(() => {
  //   try {
  //     // 临时测试
  //     const rtsp1 = 'rtsp://admin:gemho10-7@192.168.0.56:554/h264/ch1/main/av_stream';
  //     // eslint-disable-next-line no-new
  //     new JSMpeg.Player(
  //       `ws://192.168.1.147:9999/rtsp?url=${btoa(rtsp1)}&scale=640:-1&-b:v=1k&brightness=0.2&saturation=1.8`,
  //       {
  //         canvas: document.getElementById('canvas-3'),
  //         preserveDrawingBuffer: true
  //       }
  //     );
  //   } catch (e) { }
  // })
}


const devData = ref({});

const getCardData = async () => {
  await api_pointsCount().then(res => {
    if (res.data.code === 200) {
      // devData.value = res.data.data;
      (res.data.data).forEach(item => {
        if(item.status === 0){
          devData.value.online = item.count
        }else{
          devData.value.offline = item.count
        }
      })
    };
  })
};


const openCamera = (item) => {
  // e.stopPropagation();
  // e.preventDefault();
  isDefaultPreview.value = true;
  switchVideoPlayer();
  cLogInfo = item;
  showModal.value = true;
}
const full = ref(false);


// watch(full, (oldType, curType) => {
//   if (curType) {
//     nextTick(() => {
//       const el = document.getElementById('canvas-4');
//       const { clientWidth, clientHeight } = el;
//       console.log(clientWidth, clientHeight)
//       el.width = clientWidth;
//       el.height = clientHeight;
//       switchVideoPalyer();
//     })
//   }
// });

/**
 *  窗口自适应
 */
// window.addEventListener('resize', (e) => {
//   if (full.value) {

//   }
// })


onMounted(() => {
  getAlarmLog();
  getCameraList();
  getCardData();

  // =============================================================== Demo | S
  try {

    let ws = new WebSocket(`${webSocketUrl}/ws/${localStg.get('id')}`);

    ws.onopen = function () {
      console.log('WebSocket connected --------------------------------------------------------------------------');
      ws.send('Hello, Server! ------------------------- ');
    };

    ws.onmessage = function (event) {
      console.log('---------------------- WebSocket received message:', JSON.parse(event.data));
      let data = JSON.parse(event.data);
      data.algorithmId && playAudio(data.algorithmId);

      if (data.reminderType === 1) {
        window.$notification?.create({
          duration: 5000,
          title: () => <div>
            <NSpace justify='space-between'>
              <NSpace align='center' >
                {
                  data.algorithmGrade === 0 ? (
                    <NTag type="error">一级</NTag>
                  ) : data.algorithmGrade === 1 ? (
                    <NTag type="warning">二级</NTag>
                  ) : data.algorithmGrade === 2 ? (
                    <NTag type="info">三级</NTag>
                  ) : data.algorithmGrade === 3 ? (
                    <NTag type="success">四级</NTag>
                  ) : (
                    <NTag>五级</NTag>
                  )
                }
                {data.algorithmName}
                {data.id}
              </NSpace>
              {/* <NDropdown trigger="hover" options={options} onSelect={handleSelect}>
              <NButton secondary size="small" text >暂停提醒</NButton>
            </NDropdown> */}
            </NSpace>
            {/* 提醒 ================================= E */}
            <NRow gutter={10} style={{ marginTop: '10px' }}>
              <NCol span="12">
                <img
                  style={{ height: "100px", width: '200px' }}
                  src={data.image}
                />
              </NCol>
              <NCol span="12">
                {/* <div> */}
                <n-space vertical justify="space-between" >
                  <div>
                    <n-button quaternary round>
                      {data.cameraName}
                    </n-button>
                    <div style={{ fontSize: '14px' }} >
                      <n-button quaternary round type="info" onClick={toLogPage}>
                        查看详情
                      </n-button>
                    </div>
                  </div>
                  <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: "20px" }}>
                    <NButton strong secondary size="small" onClick={() => modifyAlramStatus(data.id, '1')}>正确报警</NButton>
                    <NButton strong secondary style={{ marginLeft: '20px' }} size="small" onClick={() => modifyAlramStatus(data.id, '2')} >错误报警</NButton>
                  </div>
                  {/* </div> */}
                </n-space>
              </NCol>
            </NRow>
          </div>
        });
      } else {
        logInfo.value = data;
        showTipModal.value = true;
      }
    };

    ws.onclose = function () {
      console.log('WebSocket closed');
    };

    ws.onerror = function (error) {
      console.error('WebSocket error:', error);
    };

  } catch (e) {
    console.log("error", e)
  }


  /**
   *
   *  默认全屏后， 游览器默认行为， 优先征用 keyup / keydown ， 全屏后， 第一次 esc 不会被触发，存在优先级。
   *  1. fullscreenchange 事件， hack 处理
   */
  document.addEventListener('fullscreenchange', (e) => {
    if (!document.fullscreenElement) {
      full.value = false
    }
  });
});




</script>

<template>
  <div id="HomePage">

    <!-- <canvas height="1080" width="1920" id="canvas-4"></canvas> -->

    <!-- =================================== 弹窗 | S -->
    <NModal v-model:show="showModal">
      <NCard v-if="isDefaultPreview" style="width: 800px;" @close="showModal = false" closable>
        <template #header>
          <NFlex justify=" space-between">
            <NFlex justify="start" align="center">
              <NTag size="small" v-if="cLogInfo.algorithmGrade === 0" type="error"> 一 级 </NTag>
              <NTag size="small" v-else-if="cLogInfo.algorithmGrade === 1" type="warning"> 二 级 </NTag>
              <NTag size="small" v-else-if="cLogInfo.algorithmGrade === 2" type="info"> 三 级 </NTag>
              <NTag size="small" v-else-if="cLogInfo.algorithmGrade === 3" type="success"> 四 级 </NTag>
              <NTag size="small" v-else>五级</NTag>
              <NSpace style="font-size: 14px;">
                <span>{{ cLogInfo.videoName }}</span>
                <span>{{ cLogInfo.cameraName }}</span>
                <span>{{ cLogInfo.createTime }}</span>
              </NSpace>
            </NFlex>
            <NButton @click.stop="() => {
              isDefaultPreview = false;

            }" strong type="info" size="small">
              <template #icon>
                <icon-ic:baseline-slow-motion-video class="text-icon" />
              </template>
              回放
            </NButton>
          </NFlex>
        </template>
        <!-- 图片区域 -->
        <div style="width: 100%; height: 400px; box-shadow: 0 0 10px rgba(255, 255, 255, 0.2);">
          <NImage :src="cLogInfo?.image" />
        </div>
        <!-- 操作区域 -->
        <template #footer>
          <NFlex justify="center">
            <NSpace>
              <n-button size="small" quaternary round type="primary"
                @click.stop="() => modifyAlramStatus(cLogInfo?.id, '1')">正确报警</n-button>
              <n-button size="small" quaternary round type="error"
                @click.stop="() => modifyAlramStatus(cLogInfo?.id, '2')">错误报警</n-button>
            </NSpace>
          </NFlex>
        </template>
      </NCard>

      <NCard v-else style="width: 800px;" @close="showModal = false" closable>
        <template #header>
          <span @click="() => {
            switchVideoPlayer();
            isDefaultPreview = true;
          }
            ">
            <NIcon size="25" style="position: relative; top: 2px;">
              <ArrowLeft20Filled />
            </NIcon>
            <span style="position: relative; top: -1px;  margin-left: 5px"></span>
          </span>
          <NDivider vertical />
          {{ cLogInfo.cameraName }}
        </template>
        <!-- 视频回放 -->
        <div style="width: 100%; height: 400px; padding-bottom: 10px;">
          <!-- MP4 切换视频 -->
          <video controls style="width: 100%; height: 100%; box-shadow: 0 0 10px rgba(255, 255, 255, 0.1);">
            <source :src="`${apiUrl}/v1/playVideo/${cLogInfo.remark}`" type="audio/mpeg">
            </source>
          </video>
        </div>
      </NCard>
    </NModal>
    <!-- =================================== 弹窗 | E -->

    <div style="border: 1px solid red; position: fixed; top: -1000px" v-html="htmlStr"></div>

    <NSpace vertical :size="16">
      <NModal v-model:show="showTipModal">
        <NCard style="width: 800px" :bordered="false" @close="showTipModal = false" closable>
          <template #header>
            <NSpace align="center">
              <NTag size="large" v-if="logInfo.algorithmGrade === 0" type="error"> 一 级 </NTag>
              <NTag size="large" v-else-if="logInfo.algorithmGrade === 1" type="warning"> 二 级 </NTag>
              <NTag size="large" v-else-if="logInfo.algorithmGrade === 2" type="info"> 三 级 </NTag>
              <NTag size="large" v-else-if="logInfo.algorithmGrade === 3" type="success"> 四 级 </NTag>
              <NTag size="large" v-else>五级</NTag>
              {{ logInfo?.algorithmName || '张三' }}

              <!-- 视频文件 -->
              <n-button quaternary round>
                {{ logInfo?.videoName }}
              </n-button>

              <!-- 查看详情 -->
              <n-button quaternary round @click="toLogPage">
                查看详情
              </n-button>
            </NSpace>
          </template>
          <div style="width: 100%; height: 400px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);">
            <NImage :src="logInfo?.image" />
          </div>

          <template #footer>
            <NFlex justify="center">
              <NSpace>
                <n-button quaternary round type="primary"
                  @click.stop="() => modifyAlramStatus(logInfo?.id, '1')">正确报警</n-button>
                <n-button quaternary round type="error"
                  @click.stop="() => modifyAlramStatus(logInfo?.id, '2')">错误报警</n-button>
              </NSpace>
            </NFlex>
          </template>
        </NCard>
      </NModal>
      <!-- <HeaderBanner /> -->

      <!-- ========================= 实时监控 | S -->
      <NRow :gutter="15">
        <NCol :span="18" class="text-focus-in">
          <NRow :gutter="15">
            <NCol :span="6">
              <NCard>
                <template #header>
                  点位状态
                </template>
                <!-- <CardData /> -->
                <div style="height: 100px; display: flex; justify-content: space-between; align-items: center;">
                  <div style="flex: 1;  text-align: center;">
                    <div style="display: inline-block; font-size: 40px; font-weight: 500;">
                      {{ devData.online || 0 }}
                    </div>
                    <br />
                    <div style="display: inline-block;margin-top: 10px; margin-bottom: 20px;">
                      <img src="../../assets/z_03.jpg" alt="">
                    </div>
                  </div>
                  <div style="flex: 1;  text-align: center;">
                    <div style="display: inline-block;font-size: 40px; font-weight: 500;">
                      {{ devData.offline || 0 }}
                    </div>
                    <br />
                    <div style="display: inline-block; margin-top: 10px; margin-bottom: 20px;">
                      <img src="../../assets/z_05.jpg" alt="">
                    </div>
                  </div>
                </div>
              </NCard>
              <!-- 回放 -->
              <NCard style="margin-top: 10px; height: 300px">
                <template #header>
                  视频分析任务启动状态
                </template>
                <RingChart></RingChart>
              </NCard>
            </NCol>
            <NCol :span="18" style="height: 500px">
              <NCard :bordered="false">
                <!-- 标题 -->
                <template #header>
                  <span v-if="cName">{{ `${cName}` }}<span
                      style="margin-left: 10px; font-size: 14px;">正在查看</span></span>
                  <span v-else>{{ `实时监控` }}</span>
                </template>

                <template #header-extra>
                  <div style="width: 200px;">
                    <NSelect @update:value="val => switchVideoPalyer(val)" placeholder="请选择" label-field="cameraName"
                      value-field="id" :options="cameraList"></NSelect>
                  </div>
                </template>

                <!-- 实时监控 | S -->
                <!-- height: 450px;  -->
                <!-- /**
                .video-player {
                  border: 1px solid #ccc;
                  padding: 2px;
                  border: #ccc;
                  position: fixed;
                  top: 0;
                  left: 0;
                  width: 100vw;
                  height: 100vh;
                  z-index: 99999;
                };


                /* ============================= 推理平台 | S */
                .video-player-old {
                  padding: 2px;
                  border: #ccc;
                  height: 420px !important;
                  /* height: 100% !important; */
                  border: 1px solid #ccc;
                  border: 10px solid red !important;
                };
                */ -->
                <!-- :class="[full ? 'video-player' : 'video-player-old']" -->
                <div :style="full ? {
                  border: '1px solid #ccc',
                  padding: '2px',
                  position: 'fixed',
                  top: 0,
                  left: 0,
                  width: '100vw',
                  height: '100vh',
                  zIndex: '99999'

                } : {
                  padding: '2px',
                  height: '410px !important',
                  border: ' 1px solid #ccc',
                  position: 'relative'
                }">
                  <div
                    style="position: absolute; bottom: 20px; right: 30px; width: 40px; height: 40px; cursor: pointer; ">
                    <icon-gridicons-fullscreen-exit v-if="full" color="#1872F0" font-size="30"
                      @click="full = fullScreen(full)" />
                    <icon-gridicons-fullscreen v-else font-size="30" color="#1872F0" @click="full = fullScreen(full)" />
                  </div>
                  <canvas style="width: 100%; height: 100%;" width="800" height="600" id="canvas-4"></canvas>
                </div>
              </NCard>
            </NCol>
          </NRow>

          <NGrid style="padding-top: 20px" :x-gap="gap" :y-gap="16" responsive="screen" item-responsiv>
            <NGi span="24 s:24 m:24">
              <NCard :bordered="false" title="统计分析  (条/天)" class="card-wrapper">
                <template #header-extra>
                  <n-date-picker v-model:value="range" type="daterange" clearable />
                </template>
                <div style="height: 400px">
                  <LineChart :date="range" />
                </div>
              </NCard>
            </NGi>
          </NGrid>
        </NCol>

        <NCol :span="6">
          <NCard class="text-focus-in" :bordered="false" title="实时报警" :padding="0">
            <n-infinite-scroll class="aralm-scroll" :style="{
              height: '970px',
              padding: '0 10px',
              '--n-scrollbar-color': 'transparent'
            }" :distance="10">
              <NRow v-for="item in tableData" :gutter="20"
                style="margin-top: 10px; border-radius: 7px; overflow: hidden; padding: 10px 10px; position: relative; display: flex; justify-content: center; cursor: pointer; align-items: center;">
                <NCol :span="12">
                  <n-space justify="space-around" size="large" vertical @click="(e) => {
                    e.stopPropagation();
                    e.preventDefault();
                    openCamera(item);
                  }">
                    <div>
                      <NSpace>
                        <NTag v-if="item.algorithmGrade === 0" type="error"> 一 级 </NTag>
                        <NTag v-else-if="item.algorithmGrade === 1" type="warning"> 二 级 </NTag>
                        <NTag v-else-if="item.algorithmGrade === 2" type="info"> 三 级 </NTag>
                        <NTag v-else-if="item.algorithmGrade === 3" type="success"> 四 级 </NTag>
                        <NTag v-else>五级</NTag>
                        <h1> {{ item.algorithmName }}</h1>
                      </NSpace>
                    </div>
                    <div>{{ item.cameraName }}</div>
                    <div>{{ item.createTime }}</div>
                  </n-space>
                </NCol>
                <!-- image -->
                <NCol :span="12">
                  <img style="height: 100px; width: 100%; box-shadow: 0 0 10px rgba(0,0,0,.3);" :src="item.image">
                  </img>
                </NCol>
              </NRow>
            </n-infinite-scroll>
          </NCard>
        </NCol>
      </NRow>
      <!-- ========================= 实时监控 | E -->
    </NSpace>
  </div>
</template>

<style scoped lang="scss">
/**
  报警 - 滚动条
*/
#HomePage::global(.n-scrollbar) {
  --n-scrollbar-color: transparent !important;
}


.text-focus-in {
  /* http://192.168.1.171:9527/demo: text-focus-in 1s cubic-bezier(0.550, 0.085, 0.680, 0.530) both; */
}

/* ----------------------------------------------
 * Generated by Animista on 2024-10-29 15:10:15
 * Licensed under FreeBSD License.
 * See http://animista.net/license for more info.
 * w: http://animista.net, t: @cssanimista
 * ---------------------------------------------- */

/**
 * ----------------------------------------
 * animation text-focus-in
 * ----------------------------------------
 */
@-webkit-keyframes text-focus-in {
  0% {
    -webkit-filter: blur(12px);
    filter: blur(12px);
    opacity: 0;
  }

  100% {
    -webkit-filter: blur(0px);
    filter: blur(0px);
    opacity: 1;
  }
}

@keyframes text-focus-in {
  0% {
    -webkit-filter: blur(12px);
    filter: blur(12px);
    opacity: 0;
  }

  100% {
    -webkit-filter: blur(0px);
    filter: blur(0px);
    opacity: 1;
  }
}

#canvas-4 {
  width: 100%;
  height: calc(100% - 20px);
}

.blinking-red {
  box-shadow: inset 0 0 10px rgba(239, 108, 108, .9);
  animation: blink 3s linear infinite;
  border-radius: 7px !important;
  overflow: hidden !important;
  cursor: pointer;
}

@keyframes blink {
  0% {
    box-shadow: inset 0 0 30px rgba(239, 108, 108, .9);
  }

  25% {
    box-shadow: inset 0 0 50px rgba(239, 108, 108, .9);
    border: 1px solid rgba(239, 108, 108, .9);
  }


  50% {
    /* opacity: 0; */
    box-shadow: inset 0 0 10px rgba(239, 108, 108, .9);
    translate: scaale(1.05)
  }

  75% {
    box-shadow: inset 0 0 30px rgba(239, 108, 108, .9);
  }

  100% {
    box-shadow: inset 0 0 50px rgba(239, 108, 108, .9);
    border: 1px solid rgba(239, 108, 108, .9);
  }
}

blinking-red::after {
  content: " 张三";
  /* display: ; */
}

.video-player {
  border: 1px solid #ccc;
  padding: 2px;
  border: #ccc;
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 99999;
}

;


/* ============================= 推理平台 | S */
.video-player-old {
  padding: 2px;
  border: #ccc;
  height: 420px !important;
  /* height: 100% !important; */
  border: 1px solid #ccc;
  border: 10px solid red !important;
}

;
</style>
