<template>
  <div
    v-if="hasPermission"
    class="bs-page-design-wrap"
  >
    <PageTopSetting
      v-show="headerShow"
      ref="PageTopSetting"
      :right-fold="rightVisiable"
      @updateRightVisiable="updateRightVisiable"
      @showPageInfo="showPageInfo"
      @empty="empty"
    />
    <div class="drag-wrap">
      <!-- 左侧面板 -->
      <LeftPanel
        :header-show="headerShow"
        :height="height"
        @openRightPanel="openRightPanel"
        @openResource="initDialog"
        @openComponent="openComponent"
        @toggleLeftSidebar="toggleLeftSidebar"
      />
      <!-- 中间组件展示面板 -->
      <div
        v-loading="pageLoading"
        class="grid-wrap-box"
        :style="{
          height: 'calc(100vh - 48px)'
        }"
        tabindex="1000"
        @keydown="designKeydown"
      >
        <SketchDesignRuler
          ref="Rules"
          :width="3000"
          :height="3000"
          :page-width="pageConfig.w"
          :page-height="pageConfig.h"
          @changeStart="changeStart"
        >
          <MouseSelect
            :offset-x="offset.x"
            :offset-y="offset.y"
            @selectArea="onSelectArea"
          >
            <Render
              ref="Render"
              :class="{
                'grid-bg': hasGrid
              }"
              @openRightPanel="openRightPanel"
            />
          </MouseSelect>
        </SketchDesignRuler>
        <div class="footer-tools-bar">
          <el-slider
            class="bs-slider-wrap"
            :value="zoom"
            :min="10"
            style="width: 200px; margin-right: 20px"
            @input="changeScreenZoom"
          />
          <span class="select-zoom-text">缩放比例</span>
          <el-select
            class="bs-el-select"
            popper-class="bs-el-select"
            :value="zoom"
            @change="changeScreenZoom"
          >
            <el-option
              v-for="(zoom,index) in zoomList"
              :key="index"
              :label="zoom.label"
              :value="zoom.value"
            />
          </el-select>
        </div>
      </div>
      <!-- 右侧折叠设置面板   -->
      <SettingPanel
        :header-show="headerShow"
        :height="height"
        :right-visiable.sync="rightVisiable"
        :page-info-visiable="pageInfoVisiable"
        @updateSetting="updateSetting"
        @updateDataSetting="updateDataSetting"
        @updatePage="updatePage"
      >
        <template #dataSetSelect="{ value }">
          <slot
            name="dataSetSelect"
            :value="value"
          />
        </template>
      </SettingPanel>
      <!-- 添加资源面板 -->
      <SourceDialog
        ref="SourceDialog"
        @getImg="setImg"
      />
      <ComponentDialog
        ref="componentDialog"
        @setComponent="setComponent"
        @setRemoteComponent="setRemoteComponent"
      />
      <iframe-dialog
        v-if="iframeDialog"
        ref="iframeDialog"
      />
    </div>
  </div>
  <NotPermission v-else-if="!hasPermission" />
</template>
<script>
import SourceDialog from './SourceDialog/index.vue'
import ComponentDialog from './ComponentDialog/index.vue'
import iframeDialog from 'data-room-ui/BasicComponents/LinkChart/iframeDialog'
import {
  dataConfig,
  settingConfig
} from 'data-room-ui/BasicComponents/Picture/settingConfig'
import LeftPanel from './LeftPanel.vue'
import SettingPanel from './SettingPanel.vue'
import PageTopSetting from './PageDesignTop.vue'
import Render from '../Render'
import { mapActions, mapMutations, mapState } from 'vuex'
import SketchDesignRuler from 'data-room-ui/BigScreenDesign/RulerTool/SketchRuler.vue'
import { G2 } from '@antv/g2plot'
import multipleSelectMixin from 'data-room-ui/js/mixins/multipleSelectMixin'
import { getThemeConfig, getScreenInfo } from 'data-room-ui/js/api/bigScreenApi'
import MouseSelect from './MouseSelect/index.vue'
import _ from 'lodash'
import { randomString } from '../js/utils'
import { isFirefox } from 'data-room-ui/js/utils/userAgent'
import { handleResData } from 'data-room-ui/js/store/actions.js'
import { EventBus } from 'data-room-ui/js/utils/eventBus'
import NotPermission from 'data-room-ui/NotPermission'
export default {
  name: 'BigScreenDesign',
  components: {
    PageTopSetting,
    LeftPanel,
    Render,
    SketchDesignRuler,
    MouseSelect,
    SettingPanel,
    SourceDialog,
    ComponentDialog,
    iframeDialog,
    NotPermission
  },
  mixins: [multipleSelectMixin],
  props: {
    code: {
      type: String,
      default: ''
    },
    headerShow: {
      type: Boolean,
      default: true
    },
    height: {
      type: String,
      default: 'calc(100vh - 40px)'
    }
  },
  data () {
    return {
      hasPermission: true,
      rightVisiable: false,
      pageInfoVisiable: false,
      ruleStartX: 100,
      ruleStartY: 100,
      zoomList: [
        {
          label: '自适应',
          value: 'auto'
        },
        {
          label: '100%',
          value: 100
        },
        {
          label: '80%',
          value: 80
        },
        {
          label: '50%',
          value: 50
        },
        {
          label: '20%',
          value: 20
        }
      ]
    }
  },
  watch: {
    fitZoom (zoom) {
      this.zoomList[0] = {
        label: `自适应(${zoom}%)`,
        value: zoom
      }
    }
  },
  computed: {
    ...mapState({
      pageInfo: (state) => state.bigScreen.pageInfo,
      chartList: (state) => state.bigScreen.pageInfo.chartList,
      pageConfig: (state) => state.bigScreen.pageInfo.pageConfig,
      pageLoading: (state) => state.bigScreen.pageLoading,
      hoverCode: (state) => state.bigScreen.hoverCode,
      presetLine: (state) => state.bigScreen.presetLine,
      updateKey: (state) => state.bigScreen.updateKey,
      hasGrid: (state) => state.bigScreen.hasGrid,
      zoom: (state) => state.bigScreen.zoom,
      fitZoom: (state) => state.bigScreen.fitZoom,
      iframeDialog: (state) => state.bigScreen.iframeDialog
    }),
    pageCode () {
      return this.code || this.$route.query.code
    },
    offset () {
      return {
        x: 220 + 50 - this.ruleStartX,
        y: 55 + 50 - this.ruleStartY
      }
    }
  },
  // beforeRouteEnter (to, from, next) {
  //   // 判断进入设计页面前是否有访问权限
  //   const code = to.query.code
  //   get(`/bigScreen/permission/check/${code}`).then((res) => {
  //     if (res) {
  //       next((vm) => {
  //         // 重置大屏的vuex store
  //         vm.$store.commit('bigScreen/resetStoreData')
  //       })
  //     } else {
  //       next('/notPermission')
  //     }
  //   })
  // },
  created () {
    this.changePageLoading(true)
    this.permission()
    /**
       * 以下是为了解决在火狐浏览器上推拽时弹出tab页到搜索问题
       * @param event
       */
    if (isFirefox()) {
      document.body.ondrop = function (event) {
        event.preventDefault()
        event.stopPropagation()
      }
    }
  },
  mounted () {
    EventBus.$on('closeRightPanel', () => { this.rightVisiable = false })
  },
  beforeDestroy () {
    this.clearTimeline()
    EventBus.$off('closeRightPanel')
  },
  methods: {
    ...mapActions('bigScreen', ['initLayout']),
    ...mapMutations('bigScreen', [
      'changeLayout',
      'changePageLoading',
      'resetPresetLine',
      'changeActiveCode',
      'changeActiveCodes',
      'changePageConfig',
      'changeChartConfig',
      'changeChartKey',
      'changeZoom',
      'clearTimeline',
      'saveTimeLine',
      'changeIframeDialog'
    ]),
    // 判断页面权限
    permission () {
      this.$dataRoomAxios.get(`/bigScreen/permission/check/${this.pageCode}`).then(res => {
        this.hasPermission = res
        if (res) {
          this.init()
        }
      })
    },
    // 添加资源弹窗初始化
    initDialog () {
      this.$refs.SourceDialog.init()
    },
    openComponent () {
      this.$refs.componentDialog.init()
    },
    // 从组件库添加组件模板到当前画布
    setComponent (component) {
      // 根据component获取页面详情
      getScreenInfo(component.code).then(res => {
        // 给组件库导入的组件加入统一的前缀
        const randomStr = randomString(8)
        const pageInfo = handleResData(res)
        const chartList = pageInfo.chartList.reverse()
        chartList.forEach((chart) => {
          // 如果组件存在数据联动，则将数据联动的code也加上相同的前缀
          if (chart.linkage && chart.linkage.components && chart.linkage.components.length) {
            chart.linkage.components.forEach((com) => { com.componentKey = randomStr + com.componentKey })
          }
          const newChart = {
            ...chart,
            offsetX: 0,
            group: randomStr,
            code: randomStr + chart.code
          }
          this.$refs.Render.addChart(newChart, { x: chart.x, y: chart.y }, true)
          this.updateRightVisiable(false)
        })
      })
    },
    // 添加远程组件
    setRemoteComponent (component) {
      const newChart = {
        ...component,
        offsetX: 0,
        offsetY: 0,
        code: randomString(8)
      }
      this.$refs.Render.addChart(newChart, { x: 0, y: 0 })
    },
    setImg (val) {
      this.$refs.Render.addSourceChart(
        JSON.stringify({
          title: val.originalName,
          name: val.originalName,
          icon: null,
          className:
              'com.gccloud.dataroom.core.module.chart.components.ScreenPictureChart',
          w: 300,
          h: 300,
          x: 0,
          y: 0,
          type: 'picture',
          option: {
            ..._.cloneDeep(settingConfig)
          },
          setting: {}, // 右侧面板自定义配置
          dataHandler: {}, // 数据自定义处理js脚本
          ..._.cloneDeep(dataConfig),
          customize: {
            url: val.url,
            radius: 0,
            opacity: 100
          }
        }),
        { x: 150, y: 100 }
      )
    },
    init () {
      this.changePageLoading(true)
      this.initLayout(this.pageCode)
        .then(() => {
          const themeName = this.pageConfig.customTheme
          if (!['dark', 'light', 'auto'].includes(themeName)) {
            getThemeConfig().then((res) => {
              // 初始化时如果就是自定义主题则统一注册
              const { registerTheme } = G2
              registerTheme(themeName, { ...res.chart })
              const pageConfig = this.pageConfig
              pageConfig.themeJson = res
              this.changePageConfig(pageConfig)
              this.changePageLoading(false)
            })
          } else {
            this.changePageLoading(false)
          }
        })
        .finally(() => {
          setTimeout(() => {
            this.resetPresetLine()
          }, 500)
        })
    },
    // 点击当前组件时打开右侧面板
    openRightPanel (card) {
      this.rightVisiable = true
      this.pageInfoVisiable = false
    },
    /**
       * @description: 清空页面
       */
    empty () {
      this.$confirm('确定清空页面吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
        customClass: 'bs-el-message-box'
      })
        .then(() => {
          this.changeLayout([])
          this.resetPresetLine()
          this.saveTimeLine('清空画布')
        })
        .catch(() => {})
    },
    // 自定义属性更新
    updateSetting (config) {
      if (config.type === 'map' || config.type === 'video') {
        config.key = new Date().getTime()
      }
      this.changeChartConfig(_.cloneDeep(config))
      this.$refs.Render?.$refs['RenderCard' + config.code][0]?.$refs[
        config.code
      ]?.changeStyle(_.cloneDeep(config))
    },
    // 动态属性更新
    updateDataSetting (config) {
      config.key = new Date().getTime()
      this.changeChartConfig(config)
    },
    onSelectArea (area) {
      const { startX, startY, endX, endY } = area
      // 计算所有在此区域中的组件，如果在此区域中，将其code添加到activeCodes数组中
      const activeCodes = this.chartList
        ?.filter((chart) => {
          const { x, y, w, h } = chart
          return startX <= x && x + w <= endX && startY <= y && y + h <= endY
        })
        ?.map((chart) => chart.code)
      this.changeActiveCodes(activeCodes)
    },
    changeStart ({ x, y }) {
      this.ruleStartX = x
      this.ruleStartY = y
    },
    // 保存并预览
    saveAndPreview () {
      this.$refs.PageTopSetting.execRun()
    },
    // 保存
    save () {
      this.$refs.PageTopSetting.save('saveLoading')
    },
    changeScreenZoom (zoom) {
      // 自适应
      if (zoom === 'auto') {
        this.$refs.Rules.initZoom()
      } else {
        this.changeZoom(zoom)
      }
    },
    updateRightVisiable (visiable) {
      this.rightVisiable = visiable
      this.$refs.Rules.initRuleHeight()
    },
    toggleLeftSidebar () {
      this.$refs.Rules.initRuleHeight()
    },
    showPageInfo () {
      this.pageInfoVisiable = true
      this.rightVisiable = true
      this.changeActiveCode('')
    },
    // 页面信息更改
    updatePage () {
      this.$refs.Rules.initZoom()
    }
  }
}
</script>
<style lang="scss" scoped>
  .bs-page-design-wrap {
    overflow: hidden;

    .drag-wrap {
      display: flex;
      background-color: #1d1e20;
      height: calc(100vh - 40px);
      overflow: hidden;

      .grid-wrap-box {
        flex: 1;
        overflow: hidden;
        position: relative;
        margin: 8px 0 0 8px;

        .footer-tools-bar {
          position: absolute;
          bottom: 0;
          width: 100%;
          height: 30px;
          display: flex;
          justify-content: flex-end;
          align-items: center;
          z-index: 1000;
          background-color: var(--bs-background-2);

          .bs-select-wrap {
            margin-right: 16px;
          }

          .select-zoom-text {
            color: var(--bs-el-title);
            margin-right: 16px;
          }

          ::v-deep .el-select {
            width: 150px !important;
          }
        }
      }

      ::v-deep .el-loading-mask {
        background-color: transparent !important;
      }
    }
  }
</style>
