<template>
  <div class="kf-video-wall-container w-100 h-100 flex-column-between-start" v-show="props.show"
       :class="'vivify '+ buttonClass"

       :style="cardStyle" ref="container">
    <el-row style="width: 100%" v-if="props.showToolbar" class="kf-video-header">
      <el-col :span="10" class="flex-row-start-center">
        {{ title }}
      </el-col>
      <el-col :span="8" class="kf-video-input">
        <el-tree-select
            v-model="conditions.spaceConditions"
            :data="spaceData"
            multiple
            :render-after-expand="false"
            show-checkbox

        />
      </el-col>
      <el-col :span="6" class="kf-video-input">
        <el-input v-model="search" placeholder="请输入搜索内容"></el-input>
      </el-col>
    </el-row>
    <div class="kf-video-content">
      <div v-for="(item, index) in positions" :key="item.i" class="pr"
           :style="item">
        <div style="position: absolute; left: 0px; top:0px; background: rgba(0,0,0,0.5)">
          {{ getVideo(index).deviceName }}
        </div>
        <kf-video-item :props="getVideo(index)" style="border: 1px solid white"
                       :key="getVideo(index).deviceName"></kf-video-item>
      </div>
    </div>

    <el-row style="width: 100%" v-if="props.showToolbar" class="kf-video-header">
      <el-col :span="12">
        <el-button v-for="layout in layouts" :key="layout.name" @click="selectLayout(layout)" style="cursor: pointer">
          {{ layout.name }}
        </el-button>
      </el-col>
      <el-col :span="12" class="flex-row-end-center">
        <el-button @click="gotoFirstPage">首页</el-button>
        <el-button @click="gotoPrevPage">上一页</el-button>
        <span>{{ currPage + 1 }}/{{ pageCount }}页</span>
        <el-button @click="gotoNextPage">下一页</el-button>
        <el-button @click="gotoLastPage">末页</el-button>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import kfVideoItem from "@/components/ui/widgets/kfVideoItem.vue";
import {computed, getCurrentInstance, onMounted, ref, watch} from 'vue'
import styleManager from "../utils/style.vue";
import eventManager from "../utils/event";
import spaceModel from "@/components/ui/model/space";
import tools, {runUntil} from "@/utils/tools";
import pageModel from "../model/page";
import dataMappingService from '@/service/dataMapping'

export default {
  name: "kfVideoWall",
  props: {
    props: {
      type: Object,
      default: () => {
      }
    },
    eventList: {
      type: Array,
      default: () => []
    },
    eventScript: {
      type: String
    }
  },
  widgetConfig: {
    parent: "base",
    rank: 10,
    label: {
      zh: "视频墙"
    },
    category: "业务",
    component: "kfVideoWall",
    display: true,
    version: 1,
    icon: "icon-anniu",
    defaultSize: {
      x: 650,
      y: 400
    },
    minSize:{
        width: 650,
        height: 350
    },
    imgName: 'kfVideoWall',
    state: {
      isAdd: false,
      isCondition: false
    },
  },
  components: [kfVideoItem],
  setup(props) {
    let cardStyle = ref({})
    const {proxy} = getCurrentInstance();
    let defaultHandler = ref({})
    const container = ref();

    onMounted(() => {
      refreshEvents()
      cardStyle.value = styleManager.updateStyle(proxy);
      buttonClass.value = styleManager.updateClass(proxy)
    })

    const refreshEvents = function () {
      eventManager.registerEvent(proxy);
    }

    const eventHandler = computed(() => {
      return eventManager.loadEventHandler(defaultHandler, undefined, props.props.pageName)
    });

    const layouts = [
      {
        name: "1",
        label: "1",
        row: 1,
        col: 1,
        recordCount: 1,
      },
      {
        name: "4",
        label: "4",
        row: 2,
        col: 2,
        recordCount: 4,
      },
      {
        name: "6",
        label: "6",
        row: 3,
        col: 3,
        matrix: [
          {x: 0, y: 0, w: 2, h: 2, i: '0'},
          {x: 2, y: 0, w: 1, h: 1, i: '1'},
          {x: 2, y: 1, w: 1, h: 1, i: '2'},
          {x: 0, y: 2, w: 1, h: 1, i: '3'},
          {x: 1, y: 2, w: 1, h: 1, i: '4'},
          {x: 2, y: 2, w: 1, h: 1, i: '5'}
        ],
        recordCount: 6,
      },
      {
        name: "8",
        label: "8",
        row: 2,
        col: 4,
        recordCount: 8,
      },
      {
        name: "9",
        label: "9",
        row: 3,
        col: 3,
        recordCount: 9,
      },
      {
        name: "16",
        label: "16",
        row: 4,
        col: 4,
        recordCount: 16,
      }
    ];

    const currLayout = ref();

    onMounted(() => {
      updateLayout();
    })

    let buttonClass = ref('')

    const updateLayout = function () {
      if (props.props.layout) {
        currLayout.value = layouts.find(item => item.name === props.props.layout);
      } else {
        currLayout.value = layouts[0];
      }
    }

    pageModel.watchProps(props, watch, proxy, (changes) => {
      refreshEvents();
      if (styleManager.styleChanged("kfVideoWall", changes)) {
        cardStyle.value = styleManager.updateStyle(proxy)
      }
      if (styleManager.classChanged("kfVideoWall", changes)) {
        buttonClass.value = styleManager.updateClass(proxy)
      }
      if (changes && changes['layout']) {
        updateLayout()
      }
    })

    const selectLayout = function (layout) {
      currLayout.value = layout;
    }

    const positions = computed(() => {
      let matrix = currLayout.value?.matrix || [];

      if (container.value) {
        let box = container.value.getBoundingClientRect();
        let cellPadding = 2;
        if (matrix.length === 0) {
          for (let i = 0; i < currLayout.value.row; i++) {
            for (let j = 0; j < currLayout.value.col; j++) {
              matrix.push({
                x: j,
                y: i,
                w: 0,
                h: 0,
                i: `${i * currLayout.value.col + j}`,
              })
            }
          }
        }

        let _width = props.props.width;
        let _height = props.props.height - 60;
        let headerHieght = props.props.showToolbar ? 30 : 0
        matrix = matrix.map(item => {
          if (item.w == 0 && item.h == 0) {
            return {
              width: 'calc(100% / ' + currLayout.value.col + ')',
              height: 'calc(100% / ' + currLayout.value.row + ')',
              i: item.i
            }
          } else {
            return {
              position: "absolute",
              left: item.x * (_width / currLayout.value.col) + cellPadding + "px",
              top: item.y * (_height / currLayout.value.row) + cellPadding + headerHieght + "px",
              width: item.w * (_width / currLayout.value.col) - cellPadding * 2 + "px",
              height: item.h * (_height / currLayout.value.row) - cellPadding * 2 + "px",
              i: item.i
            }
          }
        })
      }
      return matrix;
    })

    const conditions = ref({
      spaceConditions: [],
      category: props.props.category,
      deviceTypes: props.props.deviceTypes,
    })

    const videoList = ref([]);

    watch(conditions, () => {
      queryDevices();
    })

    const queryDevices = () => {
      dataMappingService.getDataMapSourceInitList({projectId: pageModel.currProject.value.uuid}).then(res=>{
        let videos = [];
        if (res) {
          videos = res.dataConnectorList.filter(device=>{
            return device.deviceTypeCode === 'camera';
          })
          let index = 0;
          videos.map(video=>{
            if (!video.data?.url || video.data.url.indexOf("://") === -1) {
              //video.data.url = `rtsp://admin:Ventu2048SHA!@192.168.1.64:554/h264/ch1/main/av_stream`;
              video.data.group = "分组" + (index % 4);
              index++;
            }
            if (video.data.url && (video.data.url.startsWith("rtsp://") || video.data.url.startsWith("rtmp://"))){
              video.data.server = pageModel.currProject.value.settings?.streamServer;
            }
          })

          videoList.value = videos;
        }
      })
    }

    runUntil(()=>{
      return pageModel.currProject.value.uuid != null;
    }, queryDevices);

    const search = ref("");

    const currPage = ref(0);

    const filterVideoList = computed(() => {
      return videoList.value.filter(item => {
        let groupMatch = props.props.group ? item.data.group === props.props.group : true;
        return groupMatch && (tools.pinyinMatch(item.deviceName, search.value) || tools.pinyinMatch(item.deviceId, search.value));
      })
    })

    const pageCount = computed(() => {
      return Math.ceil(filterVideoList.value.length / currLayout.value?.recordCount);
    })

    const currPageVideoList = computed(() => {
      let start = currPage.value * currLayout.value.recordCount;
      let end = (currPage.value + 1) * currLayout.value.recordCount;
      return filterVideoList.value.slice(start, end);
    })

    const selectedVideo = ref();

    const title = computed(() => {
      return selectedVideo.value?.deviceName ? selectedVideo.value.deviceName : props.props.title;
    })

    const gotoFirstPage = function () {
      currPage.value = 0;
    }

    const gotoPrevPage = function () {
      if (currPage.value > 0) {
        currPage.value--;
      }
    }

    const gotoNextPage = function () {
      if (currPage.value < pageCount.value - 1) {
        currPage.value++;
      }
    }

    const gotoLastPage = function () {
      currPage.value = pageCount.value > 0 ? pageCount.value - 1 : 0;
    }

    const getVideo = function (index) {
      return currPageVideoList.value.length > index ? currPageVideoList.value[index] : {};
    }

    const spaceData = computed(() => {
      let result = [];

      spaceModel.buildings.value.map(building => {
        let buildingNode = {
          value: building.buildingId,
          label: building.name,
          children: []
        }
        result.push(buildingNode);
        if (building.floors) {
          building.floors.map(floor => {
            let floorNode = {
              value: floor.uuid,
              label: floor.name,
              children: []
            }
            buildingNode.children.push(floorNode);
          })
        }
      })

      return result;
    })

    const selectVideo = function (video) {
      selectedVideo.value = video;
    }

    return {
      selectVideo,
      layouts,
      selectLayout,
      cardStyle,
      eventHandler,
      currLayout,
      positions,
      conditions,
      videoList,
      search,
      filterVideoList,
      pageCount,
      currPage,
      currPageVideoList,
      container,
      selectedVideo,
      title,
      gotoFirstPage,
      gotoPrevPage,
      gotoNextPage,
      gotoLastPage,
      getVideo,
      spaceData,
      buttonClass
    }
  }
}
</script>

<style lang="scss">
::v-deep(.vue-core-video-player-layers) {
  z-index: 0;
}

.kf-video-wall-container {
  padding: 0;
  flex-direction: column;
  align-items: center;

  border-radius: inherit;

}

.kf-video-content {
  width: 100%;
  display: flex;
  flex-direction: row;
  height: calc(100% - 60px);
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: flex-start;
}

.kf-video-input {
  .el-select {
    width: 100%;

    .select-trigger {
      width: 100%;
      outline: none;

    }
  }

  .el-input {
    width: 100%;

    .el-input__wrapper {
      width: calc(100% - 4px);
      margin-left: 1px;
      padding: 0;
      outline: none;
      background: #282828;
      box-shadow: none;

      .el-input__inner {
        background: transparent;
        box-shadow: none;
        border: none;
        outline: none;
      }
    }
  }
}
.kf-video-header{
  width: 100%;
  height: 35px;
}
.kf-video-header {
  .el-col{
    height: 100%;
    .el-input{
      line-height: 100%;
      height: 100%;
      .el-input__wrapper{
        line-height: 100%;
        height: 100%;
        .el-input__inner{
          line-height: 100%;
          height: 100%;
        }

      }
    }
    .el-select{
      line-height: 100%;
      height: 100%;
      .select-trigger {
        line-height: 100%;
        height: 100%;
        .el-input{
          line-height: 100%;
          height: 100%;
          .el-input__wrapper{
            line-height: 100%;
            height: 100%;
            .el-input__inner{
              line-height: 100%;
              height: 100%;
            }

          }
        }
      }
    }
  }
}
</style>