<template>
  <!--:style="{height:zRenderBoxHeight+'px'}"-->
  <div id="z-render-box" :style="{height:zRenderBoxHeight+'px'}" style="overflow:auto">
    <template v-if="portalSetting">
      <div v-for="(item) in arr" :key="item.id" class="new1">
        <component
          :is="item.name"
          v-if="item.name !=='Tab'"
          class="new2"
          :options="item.options"
          :dom-id="item.id"
          :style="{position:'absolute',top:item.top+'px',left:item.left+'px',width:item.width_new+'px',height:item.height_new+'px'}"
          :components="portalSetting.components"
          :item="item"
          :portal-setting="portalSetting"
          :xishu="xishu"
          :xishu-h="xishu_h"
        />
        <!--针对tab标签页-->
        <div v-if="item.name=='Tab'">
          <div
            :id="item.id"
            class="table-box-render"
            :style="{position:'absolute',top:item.options.top+'px',left:item.options.left+'px',width:item.options.width_new+'px',height:item.options.height_new+'px'}"
          >
            <el-tabs v-model="item.options.activeName">
              <el-tab-pane
                v-for="(item1,index1) in item.options.content.pane"
                :key="index1"
                :label="item1.label"
                :name="item1.name"
                style="width:100%;height:100%"
              >
                <div
                  class="tab-content"
                  :class="{'tab-content-border':item.options.contentStyle.border}"
                  :style="{height:item1.child_height_new+'px'}"
                >
                  <div v-for="(item2, index2) in item1.child" :key="index2">
                    <component
                      :is="item2.name"
                      class="new3"
                      :options="item2.options"
                      :dom-id="item2.key"
                      :style="{position:'absolute',top:item2.options.top+'px',left:item2.options.left+'px',width:item2.options.width_new+'px',height:item2.options.height_new+'px'}"
                      :components="portalSetting.components"
                      :item="item2"
                      :portal-setting="portalSetting"
                      :xishu="xishu"
                    />
                  </div>
                </div>
              </el-tab-pane>
            </el-tabs>
          </div>
        </div>
        <div v-show="noData" class="no-data-render">暂无数据</div>
      </div>
    </template>
  </div>
</template>
<script>
import Vue from 'vue'
export default {
  name: 'Box',
  props: {
    portalSetting: {
      type: Object,
      default: () => {}
    },
    noData: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      chart: null,
      ownComponents: [], // 自定义组件的数据
      customComponents: [],
      arr: [],
      zRenderBoxHeight: 0,
      xishu: 1,
      xishu_h: 1,
      cacheResizeFunc: null,
      originPortalSetting: null
    }
  },

  watch: {},
  mounted() {
    this.originPortalSetting = JSON.parse(JSON.stringify(this.portalSetting))
    let xishu = 1
    let xishu_h = 1
    const have_tab = document.getElementsByClassName('multi-tab').length
    let tab_height = 1
    if (have_tab > 0) {
      tab_height = document.getElementsByClassName('multi-tab')[0].clientHeight
    } else {
      tab_height = 0
    }
    const zRenderBoxWidth = document.getElementById('z-render-box').clientWidth
    // const zRenderBoxHeight = (zRenderBoxWidth / this.portalSetting.width * 1) * this.portalSetting.height * 1
    const zRenderBoxHeight = window.innerHeight
    this.zRenderBoxHeight = zRenderBoxHeight
    // 小--大

    xishu = zRenderBoxWidth / this.portalSetting.width// >0
    xishu_h = 1
    if (have_tab > 0) {
      xishu_h = (this.zRenderBoxHeight - tab_height - 10) / this.portalSetting.height
    } else {
      xishu_h = this.zRenderBoxHeight / this.portalSetting.height
    }

    this.xishu = xishu
    this.xishu_h = xishu_h
    this.normalizePosition()

    this.arr = this.portalSetting.components
    // 自定义组件的加载逻辑开始
    for (let i = 0; i < this.arr.length; i++) {
      // 不是空字符的时候说明是自定义组件
      if (this.arr[i].componentAddr) {
        this.ownComponents.push(this.arr[i])
      }
      if (this.arr[i].name === 'Tab') {
        for (let j = 0; j < this.arr[i].options.content.pane.length; j++) {
          for (let k = 0; k < this.arr[i].options.content.pane[j].child.length; k++) {
            if (this.arr[i].options.content.pane[j].child[k].componentAddr) {
              this.ownComponents.push(this.arr[i].options.content.pane[j].child[k])
            }
          }
        }
      }
    }

    this.arr = []
    this.ownComponents.forEach(item => {
      item.top = item.options.top
      item.left = item.options.left
      item.width_new = item.options.width_new
      item.height_new = item.options.height_new
      this.arr.push(item)
    })

    const _this = this
    window.chajian = []
    window.Vue = Vue
    // 去重
    this.ownComponents = this.Unique(this.ownComponents)
    this.ownComponents.forEach(item => {
      const { name, componentAddr } = item
      Vue.component(name, function(resolve, reject) {
        var XML = new XMLHttpRequest()
        XML.open('GET', componentAddr, false)
        XML.send()
        if (XML.status === 200) {
          // 执行以下js chajian这个数组里面就会把这个对象给push进去
          eval(XML.responseText)
          resolve(window.chajian[window.chajian.length - 1])
          for (let i = 0; i < window.chajian.length; i++) {
            _this.customComponents.push(window.chajian[i].data().chart_new)
          }
          _this.customComponents.forEach(item2 => {
            item2.componentAddr = item.componentAddr
          })
          _this.customComponents = _this.Unique(_this.customComponents)
        }
      })
    })
    if (this.arr.length !== 0) {
      for (let i = 0; i < this.arr.length; i++) {
        if (this.arr[i].name === 'Tab') {
          if (this.arr[i].options.content) {
            for (let j = 0; j < this.arr[i].options.content.pane.length; j++) {
              this.arr[i].options.content.pane[j].child_height_new = this.arr[i].options.content.pane[j].child_height * xishu
              for (let k = 0; k < this.arr[i].options.content.pane[j].child.length; k++) {
                this.arr[i].options.content.pane[j].child[k].options.left = this.arr[i].options.content.pane[j].child[k].options.x * xishu
                this.arr[i].options.content.pane[j].child[k].options.top = this.arr[i].options.content.pane[j].child[k].options.y * xishu
                this.arr[i].options.content.pane[j].child[k].options.width_new = this.arr[i].options.content.pane[j].child[k].options.width * xishu
                this.arr[i].options.content.pane[j].child[k].options.height_new = this.arr[i].options.content.pane[j].child[k].options.height * xishu
              }
            }
          }
        }
      }
    }

    this.monitWindow()
  },
  methods: {
    changeData(parmas) {
      this.portalSetting.components = parmas
    },
    Unique(arr) {
      const res = new Map()
      return arr.filter(a => !res.has(a.name) && res.set(a.name, 1))
    },
    monitWindow() {
      this.cacheResizeFunc = window.onresize
      this.$once('hook:beforeDestroy', () => {
        if (this.cacheResizeFunc) {
          window.onresize = this.cacheResizeFunc
          this.cacheResizeFunc = null
        }
      })
      window.onresize = () => {
        this.resizeComponents()
      }
    },
    // 对宽高、位置进行容错处理
    normalizePosition() {
      // 中间部分内容宽度，正常情况下不会进行缩放，左右留白，能适配大部分屏幕
      let middleContentWidth = 0
      // const renderHeight = this.portalSetting.height
      const renderWidth = this.portalSetting.width
      const clientWidth = document.getElementById('z-render-box').clientWidth

      const DELTA = 5
      let minContentX = renderWidth / 2
      let maxContentX = renderWidth / 2

      let maxRenderHeight = 0

      this.portalSetting.components.forEach((componentItem) => {
        const positionY = componentItem.options.y + componentItem.options.height
        if (positionY > maxRenderHeight) {
          maxRenderHeight = positionY
        }
        if (componentItem.options.x > DELTA && componentItem.options.x < minContentX) {
          minContentX = componentItem.options.x
        }
        const rightX = componentItem.options.x + componentItem.options.width
        const deltaX = rightX - renderWidth
        if (Math.abs(deltaX) > DELTA && rightX > maxContentX) {
          maxContentX = rightX
        }
      })
      this.zRenderBoxHeight = maxRenderHeight.toFixed(0)
      middleContentWidth = maxContentX - minContentX
      // 中间部分内容宽度大于屏幕宽度，按照参数布局即可
      if (middleContentWidth > clientWidth) {
        this.portalSetting.components.forEach((componentItem) => {
        // 屏幕边界值的处理
          if (componentItem.options.x < DELTA) {
            componentItem.options.x = 0
          }
          if (componentItem.options.y < DELTA) {
            componentItem.options.y = 0
          }
          // 全屏的处理
          if (Math.abs(renderWidth - componentItem.options.width) < DELTA) {
            componentItem.options.width = renderWidth
          }

          componentItem.options.left = componentItem.options.x
          componentItem.options.top = componentItem.options.y
          componentItem.options.width_new = componentItem.options.width
          componentItem.options.height_new = componentItem.options.height
        })
        return
      }
      const spaceWidth = (clientWidth - middleContentWidth) / 2
      const realSpace = minContentX - spaceWidth
      this.portalSetting.components.forEach((componentItem) => {
        // 屏幕边界值的处理
        if (componentItem.options.x < DELTA) {
          componentItem.options.x = 0
        }
        if (componentItem.options.y < DELTA) {
          componentItem.options.y = 0
        }
        // 全屏的处理
        if (Math.abs(renderWidth - componentItem.options.width) < DELTA) {
          componentItem.options.width = clientWidth
        }
        // componentItem.options.left = componentItem.options.x * this.xishu
        if (componentItem.options.x > 0) {
          componentItem.options.left = componentItem.options.x - realSpace
        } else {
          componentItem.options.left = componentItem.options.x
        }
        componentItem.options.top = componentItem.options.y
        componentItem.options.width_new = componentItem.options.width
        componentItem.options.height_new = componentItem.options.height
      })
    },
    // 重新布局组件
    resizeComponents() {
      if (!this.originPortalSetting) {
        return
      }
      const tmpSetting = JSON.parse(JSON.stringify(this.originPortalSetting))
      // 中间部分内容宽度，正常情况下不会进行缩放，左右留白，能适配大部分屏幕
      let middleContentWidth = 0
      // const renderHeight = this.portalSetting.height
      const renderWidth = tmpSetting.width
      const clientWidth = document.getElementById('z-render-box').clientWidth
      const DELTA = 5
      let minContentX = renderWidth / 2
      let maxContentX = renderWidth / 2
      tmpSetting.components.forEach((componentItem) => {
        if (componentItem.options.x > DELTA && componentItem.options.x < minContentX) {
          minContentX = componentItem.options.x
        }
        const rightX = componentItem.options.x + componentItem.options.width
        const deltaX = rightX - renderWidth
        if (Math.abs(deltaX) > DELTA && rightX > maxContentX) {
          maxContentX = rightX
        }
      })
      middleContentWidth = maxContentX - minContentX
      // 中间部分内容宽度大于屏幕宽度，按照参数布局即可
      if (middleContentWidth > clientWidth) {
        tmpSetting.components.forEach((componentItem) => {
        // 屏幕边界值的处理
          if (componentItem.options.x < DELTA) {
            componentItem.options.x = 0
          }
          if (componentItem.options.y < DELTA) {
            componentItem.options.y = 0
          }
          // 全屏的处理
          if (Math.abs(renderWidth - componentItem.options.width) < DELTA) {
            componentItem.options.width = renderWidth
          }

          componentItem.options.left = componentItem.options.x
          componentItem.options.top = componentItem.options.y
          componentItem.options.width_new = componentItem.options.width
          componentItem.options.height_new = componentItem.options.height
        })
        return
      }
      const spaceWidth = (clientWidth - middleContentWidth) / 2
      const realSpace = minContentX - spaceWidth
      tmpSetting.components.forEach((componentItem, index) => {
        // 屏幕边界值的处理
        if (componentItem.options.x < DELTA) {
          componentItem.options.x = 0
        }
        if (componentItem.options.y < DELTA) {
          componentItem.options.y = 0
        }
        // 全屏的处理
        if (Math.abs(renderWidth - componentItem.options.width) < DELTA) {
          componentItem.options.width = clientWidth
        }
        // componentItem.options.left = componentItem.options.x * this.xishu
        if (componentItem.options.x > 0) {
          componentItem.options.left = componentItem.options.x - realSpace
        } else {
          componentItem.options.left = componentItem.options.x
        }
        componentItem.options.top = componentItem.options.y
        componentItem.options.width_new = componentItem.options.width
        componentItem.options.height_new = componentItem.options.height
        this.arr[index].x = componentItem.options.x
        this.arr[index].y = componentItem.options.y
        this.arr[index].width = componentItem.options.width
        this.arr[index].left = componentItem.options.left
        this.arr[index].top = componentItem.options.top
        this.arr[index].width_new = componentItem.options.width_new
        this.arr[index].height_new = componentItem.options.height_new
        this.$set(this.arr, index, this.arr[index])
      })
    }
  }
}
</script>
<style lang="scss">
#z-render-box{
  width:100%;
  height: 100%;
  box-sizing: border-box;
  //border: 1px solid #f00;
}
#portal-render-box {
  box-sizing: border-box;
  margin: 0 auto;
  position: absolute;
  border: 1px solid #f00;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
}
.no-data-render {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  // border: 1px solid #f00;
  width: 300px;
  margin: auto;
  height: 30px;
  text-align: center;
}
.new2{
  //border:1px solid #f00
}
//////tab

.table-box-render {
  width: 100%;
  height: 100%;
  background: #fff;
}
.table-content-box {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  overflow: auto;
}
.table-content {
  width: 100%;
  height: 100%;
}
.tab-card-box {
  width: 100%;
  height: 100%;
  background: #fff;
}

.tab-card-item-box {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  //border: 1px solid greenyellow;
  padding: 10px 0;
  display: flex;
  align-items: center;
  justify-content: space-around;
}
.tab-card-item {
  flex: 1;
  height: 100%;
  box-sizing: border-box;
  border: 1px solid #ddd;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 5px;
  cursor: pointer;
}
.el-tabs__nav-wrap {
    padding: 0 10px !important;
}
</style>
