<template>
  <div class="container">
    <Transition
      name="custom-classes"
      enter-active-class="animate__animated animate__faster animate__fadeIn"
      leave-active-class="animate__animated animate__faster animate__fadeOut"
      mode="out-in"
    >
      <div v-if="comName === 'index'" style="width: 100%; height: 100%">
        <Breadcrumb :items="['menu.previewList.basic']" />
        <a-card class="general-card" :body-style="{ height: '100%' }">
          <a-space direction="vertical" fill>
            <a-row class="grid-demo" :gutter="24">
              <a-col :span="4">
                <a-input-search
                  v-model="searchKey"
                  style="
                    margin-bottom: 8px;
                    max-width: 100%;
                    background-color: var(--color-fill-2);
                  "
                />
                <a-alert
                  v-if="originTreeData.some((v) => v.disabled)"
                  type="warning"
                  closable
                  >{{ $t('previewList.tip3') }}</a-alert
                >
                <a-spin v-if="loading" />
                <a-tree v-else block-node :data="treeData" @select="onSelect">
                  <template #icon>
                    <icon-camera />
                  </template>
                  <template #title="nodeData">
                    <template
                      v-if="
                        ((index = getMatchIndex(nodeData?.title)), index < 0)
                      "
                      >{{ nodeData?.title }}</template
                    >
                    <span v-else>
                      {{ nodeData?.title?.substr(0, index) }}
                      <span style="color: var(--color-primary-light-4)">
                        {{
                          nodeData?.title?.substr(index, searchKey.length)
                        }} </span
                      >{{ nodeData?.title?.substr(index + searchKey.length) }}
                    </span>
                  </template>
                  <template #extra="nodeData">
                    <a-button
                      type="text"
                      size="mini"
                      @click="toView('PreviewInfo', nodeData)"
                    >
                      <icon-to-left
                        style="font-size: 12px; color: #3370ff; cursor: pointer"
                      />
                    </a-button>
                  </template>
                </a-tree>
              </a-col>
              <a-col :span="20" class="right-box">
                <a-divider direction="vertical" :size="2" />

                <div class="split-screen-btn">
                  <a-dropdown @select="handleTypeChange">
                    <a-tooltip :content="$t('previewList.msqh')">
                      <a-button>
                        <template #icon>
                          <Icon
                            icon="stash:arrows-switch"
                            width="25"
                            height="25"
                          />
                        </template>
                      </a-button>
                    </a-tooltip>
                    <template #content>
                      <a-doption
                        v-for="item in typeList"
                        :key="item.label"
                        :value="item.value"
                      >
                        <template #default>{{ item.label }}</template>
                      </a-doption>
                    </template>
                  </a-dropdown>
                  <a-dropdown @select="handleRadioChange">
                    <a-tooltip :content="$t('previewList.fp')">
                      <a-button>
                        <template #icon>
                          <Icon
                            icon="carbon:split-screen"
                            width="20"
                            height="20"
                          />
                        </template>
                      </a-button>
                    </a-tooltip>

                    <template #content>
                      <a-doption
                        v-for="item in btnList"
                        :key="item.label"
                        :value="item.value"
                      >
                        <template #default>{{ item.label }}</template>
                      </a-doption>
                    </template>
                  </a-dropdown>
                </div>
                <div class="split-screen-main">
                  <div v-if="typeActive === 1" class="split-screen-box">
                    <a-grid
                      class="grid-demo-grid"
                      :cols="radioActive"
                      :col-gap="2"
                      :row-gap="2"
                    >
                      <a-grid-item
                        v-for="(item, i) in radioActive"
                        :key="item + '' + i"
                        @click="handleScreen(i)"
                      >
                        <div
                          class="video-box"
                          :class="[
                            'demo-item',
                            screenActive === i ? 'screen-active' : '',
                          ]"
                          @mouseleave="handleMouseLeave(i)"
                          @mouseenter="handleMouseEnter(i)"
                          @dblclick="handleDoubleClick(i)"
                        >
                          <a-spin v-if="activeObj[i].loading" dot />
                          <div
                            v-if="!activeObj[i].isSignal"
                            class="video-box-tip"
                            ><span>{{ t('previewList.wxh') }}</span></div
                          >
                          <canvas
                            v-if="activeObj[i].isReset"
                            :id="'video-canvas-' + i"
                            :style="{
                              // transform: `rotateZ(${rotateZ}deg)`,
                            }"
                          ></canvas>
                          <div
                            v-if="activeObj[i].isShowTools"
                            class="video-tools"
                          >
                            <!-- 截图 录像 -->
                            <a-tooltip
                              v-for="tool in activeObj[i].tools"
                              :key="tool.type"
                              :content="tool.title"
                            >
                              <a-button
                                type="text"
                                size="mini"
                                @click="toolsClick(tool, activeObj[i])"
                              >
                                <template #icon>
                                  <Icon
                                    :icon="tool.icon"
                                    :color="tool.color"
                                    :class="[tool.iconClass]"
                                    width="24"
                                    height="24"
                                  />
                                </template>
                              </a-button>
                            </a-tooltip>
                            <!-- 关闭 -->
                            <a-tooltip :content="$t('previewList.close')">
                              <a-button
                                type="text"
                                size="mini"
                                @click="handleClose(i)"
                              >
                                <template #icon>
                                  <Icon
                                    icon="mdi:shutdown"
                                    width="24"
                                    height="24"
                                  />
                                </template>
                              </a-button>
                            </a-tooltip>
                          </div>
                        </div>
                      </a-grid-item>
                    </a-grid>
                  </div>
                  <div v-else class="split-screen-box">
                    <a-grid
                      class="grid-demo-grid"
                      :cols="gridCount"
                      :col-gap="2"
                      :row-gap="2"
                    >
                      <a-grid-item
                        v-for="(item, i) in radioActive"
                        :key="item + '' + i"
                        @click="handleScreen(i)"
                      >
                        <div
                          class="video-box"
                          :class="[
                            'demo-item',
                            screenActive === i ? 'screen-active' : '',
                          ]"
                          @mouseleave="handleMouseLeave(i)"
                          @mouseenter="handleMouseEnter(i)"
                          @dblclick="handleDoubleClick(i)"
                        >
                          <a-spin v-if="activeObj[i].loading" dot />
                          <div
                            v-if="!activeObj[i].isSignal"
                            class="video-box-tip"
                            ><span>{{ t('previewList.wxh') }}</span></div
                          >
                          <canvas
                            v-if="activeObj[i].isReset"
                            :id="'video-canvas-' + i"
                          ></canvas>
                          <div
                            v-if="activeObj[i].isShowTools"
                            class="video-tools"
                          >
                            <!-- 截图 录像 -->
                            <a-tooltip
                              v-for="tool in activeObj[i].tools"
                              :key="tool.type"
                              :content="tool.title"
                            >
                              <a-button
                                type="text"
                                size="mini"
                                @click="toolsClick(tool, activeObj[i])"
                              >
                                <template #icon>
                                  <Icon
                                    :icon="tool.icon"
                                    :color="tool.color"
                                    :class="[tool.iconClass]"
                                    width="24"
                                    height="24"
                                  />
                                </template>
                              </a-button>
                            </a-tooltip>
                            <!-- 关闭 -->
                            <a-tooltip :content="$t('previewList.close')">
                              <a-button
                                type="text"
                                size="mini"
                                @click="handleClose(i)"
                              >
                                <template #icon>
                                  <Icon
                                    icon="mdi:shutdown"
                                    width="24"
                                    height="24"
                                  />
                                </template>
                              </a-button>
                            </a-tooltip>
                          </div>
                        </div>
                      </a-grid-item>
                    </a-grid>
                  </div>
                </div>
              </a-col>
            </a-row>
          </a-space>
        </a-card>
      </div>
      <template v-else-if="comName === 'PreviewInfo'">
        <PreviewInfo :data="comData" @handle-back="handleBack" />
      </template>
    </Transition>
    <PubModal
      ref="modalRef"
      title="报警列表"
      :fullscreen="true"
      :closable="true"
    >
      <AlarmAll />
    </PubModal>
  </div>
</template>

<script lang="ts" setup>
  import useLoading from '@/hooks/loading';
  // import { useFullscreen } from '@vueuse/core';
  import { useAppStore } from '@/store';
  import useWorker from '@/assets/js/video-lib/omnimatrix-video-player';
  import { Icon } from '@iconify/vue'; // https://iconify.design/docs/icon-components/vue/#iconify-for-vue
  import {
    ref,
    computed,
    watch,
    nextTick,
    defineAsyncComponent,
    onUnmounted,
  } from 'vue';
  import { useI18n } from 'vue-i18n';
  import { queryPolicyList, PolicyRecord, PolicyParams } from '@/api/list';
  import { getCropFullInfo } from '@/api/system';
  import { Message } from '@arco-design/web-vue';
  import { useDebounceFn } from '@vueuse/core';
  // import dayjs from 'dayjs';
  import AlarmAll from './components/alarm-all.vue';
  import PubModal from './components/pub-modal.vue';

  const modalRef = ref();

  const resizeArr: any[] = [];
  const { loading, setLoading } = useLoading(true);
  const app = useAppStore();
  const comName = ref('index');
  const comNameList = ['index'];
  const comData: any = ref({});
  const rotateZ = ref(0);

  const PreviewInfo = defineAsyncComponent(
    () => import('./children/preview-info.vue')
  );
  const toView = (path: string, data: unknown) => {
    comName.value = path;
    comNameList.push(path);
    comData.value = data;
  };
  const handleBack = () => {
    comNameList.pop();
    comName.value = comNameList[comNameList.length - 1];
  };

  interface IBtn {
    label: string;
    value: number;
  }

  const { t } = useI18n();
  const index = ref<number>(0);
  const radioActive = ref<number>(4);
  const typeActive = ref<number>(1);
  const screenActive = ref<number>(0);
  // const { isFullscreen, enter, exit, toggle } = useFullscreen(
  //   videoBoxRefs.value[screenActive.value]
  // );
  const activeObj = ref<
    {
      loading: boolean;
      isSignal: boolean;
      [key: string]: any;
    }[]
  >([]);

  // const tools = ref([
  //   {
  //     icon: 'ri:screenshot-2-line',
  //     title: t('previewList.jt'),
  //     type: 'jt',
  //     color: '#8ac5ff',
  //     iconClass: '',
  //   },
  //   {
  //     icon: 'bx:video-recording',
  //     title: t('previewList.lx'),
  //     type: 'lx',
  //     color: '#8ac5ff',
  //     iconClass: '',
  //   },
  // ]);
  const state = ref(false);
  const toolsClick = (tool: any, ao: any) => {
    if (!ao.workerObj) return;
    switch (tool.type) {
      case 'lx':
        state.value = !state.value;
        tool.icon = state.value ? 'fad:armrecording' : 'bx:video-recording';
        tool.color = state.value ? 'red' : '#8ac5ff';
        tool.iconClass = state.value ? '.fade-open' : '';
        ao.workerObj.WebSocketWork.postMessage({
          type: 'lx',
          lx: state.value,
        });
        break;
      case 'jt':
        ao.workerObj.worker.postMessage({ type: 'jt' });
        break;
      default:
        break;
    }
  };
  const gridCount = computed<number>(() => {
    let result = 4;
    switch (radioActive.value) {
      case 4:
        result = 2;
        break;
      case 9:
        result = 3;
        break;
      case 16:
        result = 4;
        break;
      default:
        result = 1;
        break;
    }
    return result;
  });
  const btnList = computed<IBtn[]>(() => [
    {
      label: t('previewList.dp'),
      value: 1,
    },
    {
      label: t('previewList.sfp'),
      value: 4,
    },
    {
      label: t('previewList.jfp'),
      value: 9,
    },
    {
      label: t('previewList.slfp'),
      value: 16,
    },
  ]);
  const typeList = computed<IBtn[]>(() => [
    {
      label: t('previewList.default'),
      value: 0,
    },
    {
      label: t('previewList.sp'),
      value: 1,
    },
  ]);

  const originTreeData = ref<any[]>([
    {
      title: 'camera 0-0',
      key: '0-0',
    },
    {
      title: 'camera 0-1',
      key: '0-1',
    },
  ]);

  // const alarmColumns = [
  //   {
  //     title: t('previewList.bjlx'),
  //     dataIndex: 'type',
  //   },
  //   {
  //     title: t('previewList.status'),
  //     dataIndex: 'status',
  //     width: 150,
  //   },
  // ];
  // const alarmLoading = ref(false);
  // const alarmData = ref<{ [key: string]: number | string | boolean }[]>([
  // {
  //   type: '行人闯入',
  //   status: 0,
  //   isRead: false,
  // },
  // ]);

  const searchKey = ref<string>('');

  function searchData(keyword: string): any[] {
    function loop<T extends { [k: string]: any }>(data: T[]): T[] {
      const result: T[] = [];
      data.forEach((item) => {
        if (item.title.toLowerCase().indexOf(keyword.toLowerCase()) > -1) {
          result.push({ ...item });
        } else if (item.children) {
          const filterData = loop(item.children);
          if (filterData.length) {
            result.push({
              ...item,
              children: filterData,
            });
          }
        }
      });
      return result;
    }

    return loop<any>(originTreeData.value);
  }
  const fetchData = async (
    params: PolicyParams = { current: 1, pageSize: 20, Status: 'All' }
  ) => {
    setLoading(true);
    try {
      const { data } = await queryPolicyList(params);
      const res = Array.isArray(data) ? data : [];
      originTreeData.value = res.map((item: any & PolicyRecord) => ({
        key: item.id,
        id: item.id,
        title: item.alias,
        port: item.port,
        status: item.status,
        disabled: !item.id,
      }));
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
      setLoading(false);
    }
  };

  const treeData = computed<any[]>(() => {
    if (!searchKey.value) return originTreeData.value;
    return searchData(searchKey.value);
  });

  function getMatchIndex(title: string) {
    if (!searchKey.value) return -1;
    return title.toLowerCase().indexOf(searchKey.value.toLowerCase());
  }

  const handleScreen = (i: number) => {
    screenActive.value = i;
  };
  fetchData();

  const handleClose = async (v: number): Promise<void> => {
    if (activeObj?.value[v]?.workerObj) {
      return new Promise((resolve) => {
        activeObj.value[v].isReset = false;
        activeObj.value[v].loading = false;
        activeObj.value[v].workerObj.close();
        resizeArr.splice(v, 1);
        setTimeout(() => {
          activeObj.value[v].isSignal = false;
          activeObj.value[v].workerObj = null;
          resolve();
        }, 50);
      });
    }
    return undefined;
  };
  const onSelect = (
    selectedKeys: Array<string | number>,
    data: {
      selected?: boolean;
      selectedNodes: any[];
      node?: any;
      e?: Event;
    }
  ): void => {
    try {
      if ((data.node as PolicyRecord).status === 'Offline') {
        Message.warning({
          content: t('previewList.tip'),
          duration: 5 * 1000,
        });
        return;
      }

      handleClose(screenActive.value).then(async () => {
        const ao = activeObj.value[screenActive.value];
        ao.isReset = true;
        ao.loading = true;
        nextTick(() => {
          const videoUrl = `${app.ip}/VideoShow/Preview/Full/Main?GUID=${
            (data.node as PolicyRecord).id
          }`;
          getCropFullInfo({ GUID: (data.node as PolicyRecord).id }).then(
            (res) => {
              rotateZ.value = res.data.Rotate;
              ao.workerObj = useWorker(
                videoUrl,
                `#video-canvas-${screenActive.value}`,
                null,
                () => {
                  ao.loading = false;
                  ao.isSignal = true;

                  setTimeout(() => {
                    const vc: any = document.querySelector(
                      `#video-canvas-${screenActive.value}`
                    );
                    resizeArr.push(vc);
                    vc.style.height = `${vc.parentNode.offsetHeight}px`;
                    vc.style.width = 'auto';
                    // eslint-disable-next-line no-use-before-define
                    resize();
                  }, 50);
                },
                JSON.stringify(res.data)
              );
            }
          );
        });
      });
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
      setLoading(false);
    }
  };

  const handleMouseEnter = (v: number) => {
    activeObj.value[v].isShowTools = true;
  };
  const handleMouseLeave = (v: number) => {
    activeObj.value[v].isShowTools = false;
  };

  const handleRadioChange = (
    v: string | number | Record<string, any> | undefined
  ) => {
    radioActive.value = typeof v === 'number' ? v : 4;
    if (typeof v === 'number') {
      screenActive.value = 0;
      // eslint-disable-next-line no-plusplus
      for (let i = 0; i < v; i++) {
        handleClose(i);
      }
    }
  };
  const handleTypeChange = (
    v: string | number | Record<string, any> | undefined
  ) => {
    typeActive.value = typeof v === 'number' ? v : 1;
  };
  let parent: any = null;
  const handleDoubleClick = (i: number) => {
    const el = document.querySelectorAll('.video-box')[i];
    const fullscreenDom: HTMLElement | null = document.querySelector(
      '#video-box-fullscreen>div'
    );
    if (fullscreenDom) {
      parent?.appendChild(fullscreenDom);
      const box = document.querySelector('#video-box-fullscreen');
      if (box) {
        document.body.removeChild(box);
      }
    } else {
      parent = el?.parentElement;
      const div: HTMLElement = document.createElement('div');
      div.id = 'video-box-fullscreen';
      div.style.position = 'fixed';
      div.style.top = '0';
      div.style.left = '0';
      div.style.width = '100%';
      div.style.height = '100%';
      div.style.zIndex = '999';
      div.appendChild(el);

      document.body.appendChild(div);
    }
    // toggle();
  };

  // let eventSource: EventSource;
  // const alarmSSE = () => {
  //   alarmLoading.value = true;
  //   eventSource = new EventSource(`${app.ip}/rpc/AiSSE?Topic=All`);
  //   eventSource.addEventListener(
  //     'open',
  //     () => {
  //       alarmData.value = [];
  //       alarmLoading.value = false;
  //     },
  //     false
  //   );
  //   eventSource.addEventListener(
  //     'message',
  //     (e) => {
  //       const data = JSON.parse(e.data);
  //       alarmData.value.unshift({
  //         type: data.AlgorithmName,
  //         status: 0,
  //         isRead: false,
  //         timeN: dayjs(+`${data.time}`.padEnd(13, '0')).format(
  //           'YYYY-MM-DD HH:mm:ss'
  //         ),
  //         ...data,
  //       });
  //     },
  //     false
  //   );
  //   eventSource.addEventListener(
  //     'error',
  //     () => {
  //       Message.warning({
  //         content: t('previewList.tip2'),
  //         duration: 5 * 1000,
  //       });
  //     },
  //     false
  //   );
  // };

  watch(
    radioActive,
    (newV) => {
      activeObj.value = [];
      // eslint-disable-next-line no-plusplus
      for (let i = 0; i < newV; i++) {
        handleClose(i);
        activeObj.value.push({
          loading: false,
          isSignal: false,
          workerObj: null,
          isShowTools: false,
          isReset: true,
          tools: ref([
            {
              icon: 'ri:screenshot-2-line',
              title: t('previewList.jt'),
              type: 'jt',
              color: '#8ac5ff',
              iconClass: '',
            },
            {
              icon: 'bx:video-recording',
              title: t('previewList.lx'),
              type: 'lx',
              color: '#8ac5ff',
              iconClass: '',
            },
          ]),
        });
      }
    },
    { immediate: true }
  );

  const resize = useDebounceFn(() => {
    resizeArr.forEach((vc) => {
      const splitScreenBox = document.querySelector('.split-screen-box');
      if (
        splitScreenBox &&
        vc.offsetHeight + 2 >= (splitScreenBox as HTMLElement).offsetHeight + 2
      ) {
        vc.style.height = '100%';
        vc.style.width = 'auto';
      } else {
        vc.style.width = '100%';
        vc.style.height = 'auto';
      }
    });
  }, 100);
  // onMounted
  watch(
    comName,
    (newV) => {
      if (newV === 'index') {
        // alarmSSE();
      } else {
        // eventSource.close();
        // for (let i = 0; i < radioActive.value; i + 1) {
        handleClose(screenActive.value);
        // }
      }
    },
    { immediate: true }
  );
  window.addEventListener('resize', resize);
  onUnmounted(() => {
    window.removeEventListener('resize', resize);
  });
</script>

<style scoped lang="scss">
  .container {
    padding: 0 20px 20px 20px;
    height: 100%;
    .split-screen-btn {
      display: flex;
      justify-content: flex-end;
      gap: 4px;
      padding-bottom: 8px;
    }
    .general-card {
      height: calc(100% - 60px);
      :deep(.arco-space) {
        height: 100%;
        .arco-space-item:last-child {
          flex: 1;
          height: 0;
        }
      }
      .grid-demo,
      .right-box {
        height: 100%;
        position: relative;
        .screen-active {
          border: 1px solid red;
        }
        .arco-divider {
          position: absolute;
          top: 0;
          left: -15px;
          height: 100%;
        }
      }
      .split-screen-main {
        height: calc(100% - 39px);
        display: flex;
        flex-flow: column;
        gap: 15px;
        .alarm-box {
          flex: 1;
          min-height: 100px;
          max-height: 100px;
          :deep(.arco-table) {
            .arco-table-scroll-y > .arco-scrollbar {
              height: 100%;
            }
          }
        }
      }
      .split-screen-box {
        height: 0;
        flex: 1;
        display: flex;
        justify-content: center;
        align-items: center;
        & > div {
          height: 100%;
          // aspect-ratio: 16/9;
          width: 100%;
        }
        .arco-grid-item {
          position: relative;
        }
      }
    }
  }
  .video-box {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #000;
    overflow: hidden;
    .arco-spin {
      position: absolute;
    }
    &-tip {
      height: 100%;
      width: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      color: #fff;
      position: absolute;
      top: 0;
      left: 0;
    }
    .video-tools {
      position: absolute;
      right: 10px;
      top: 10px;
      z-index: 99;
      display: flex;
      gap: 8px;
    }
  }
</style>
