<template>
  <i class="vl-config-layer-component" /> <!-- 模板 -->
</template>

<script>
/**
 * openlayer 组件示例
 * @type {Array<import('vue').ComponentOptions>}
 */
import VlCoreMixin from '../_mixin/vl-core-mixin'
import { createLayers, getEnabledLayersConfig, isLayerGroup, layerConfigEach } from './create-layer'
import ImageArcGISRest from 'ol/source/ImageArcGISRest'
import { isBoolean } from '@/components/ol/_utils/map-layer-utils'

const CONFIG_KEY = '__layer_config__'

export default {
  name: 'VlConfigLayers',
  mixins: [VlCoreMixin], // 混入 mapInstance(地图实例对象)
  props: {
    layersConfig: {
      type: Object,
      required: true
    },
    visibleLayerIds: { // 显示的 图层id, 为 [] 不显示图层，为 undefined显示配置文件配置的图层
      type: Array,
      default: () => undefined
    }
  },
  data() {
    return {
      enabledLayersConfig: undefined,
      layerMapping: {} // key:id value:item
    }
  },
  watch: {
    'layersConfig.view'(newValue, oldValue) {
      this.initMapView(newValue)
    },
    enabledLayersConfig: {
      deep: true,
      handler: function(newValue, oldValue) {
        layerConfigEach(newValue, this.layerConfigChangeSync2Layer)
      }
    },
    visibleLayerIds(newValue, oldValue) {
      const set = new Set(newValue)
      Object.entries(this.layerMapping).forEach(([k, v]) => {
        const item = v.get(CONFIG_KEY)
        if (!item.base) {
          // v.setVisible(item.visible = set.has(k))
          // if (isLayerGroup(v)) {
          //   v.setVisible(item.visible = !!item.children.find(i => i.visible))
          // }

          v.setVisible(item.visible = isLayerGroup(v) ? !!item.children.find(i => i.visible) : set.has(k))
        }
      })
    }
  },
  created() {
    const { layers, view } = this.layersConfig
    this.initMapView(view)
    this.initEnabledLayersConfig(layers)
  },
  methods: {
    ready() {
      // 该方法将会在页面实例 挂载完(mounted) 后自动调用

      this.loadLayers(this.enabledLayersConfig)
      // 执行相关操作
      // 添加图层等  this.mapInstance.addLayer(xxx)
    },
    closure() {
      // 该方法将会在页面实例 销毁之前(beforeDestroy) 后自动调用

      // 执行相关销毁操作
      // 添加图层等  this.mapInstance.removeLayer(xxx)

      this.mapInstance.setLayers([])
    },
    initMapView(viewConfig) {
      const { center, zoom, extent, fitExtent, minZoom, maxZoom } = viewConfig
      const view = this.mapInstance.getView()
      view.setCenter(center)
      view.setZoom(zoom)
      minZoom && view.setMinZoom(minZoom)
      maxZoom && view.setMaxZoom(maxZoom)
    },
    resetMapView(fly = true) {
      const { center, zoom } = this.layersConfig.view
      if (fly) {
        const view = this.mapInstance.getView()
        view.animate({ zoom: zoom, center: center, duration: 500 })
      } else {
        this.initMapView()
      }
    },
    initEnabledLayersConfig(layersConfig = []) {
      const visibleLayerIds = this.visibleLayerIds
      const enabledLayers = getEnabledLayersConfig(layersConfig)
      if (visibleLayerIds) {
        layerConfigEach(enabledLayers, (layerConfig, isGroup) => {
          const { id: layerId, base } = layerConfig
          if (base) { // 底图不用处理
            return
          }
          if (visibleLayerIds.length) {
            // [...]
            if (isGroup) {
              layerConfig.visible = !!layerConfig.children.find(i => i.visible)
            } else {
              layerConfig.visible = !!visibleLayerIds.find(i => i === layerId)
            }
          } else { // []
            layerConfig.visible = !!base
          }
        })
      }

      this.enabledLayersConfig = enabledLayers
    },
    loadLayers(enabledLayersConfig = []) {
      const layerMapping = this.layerMapping = {}
      this.mapInstance.setLayers(createLayers(enabledLayersConfig))
      layerConfigEach(enabledLayersConfig, (layerConfig, isGroup) => {
        const { id, layer } = layerConfig
        layerMapping[id] = layer
        layer.set(CONFIG_KEY, layerConfig)

        if (isGroup) {
          const layers = layer.getLayers().getArray()
          layers.forEach(l => {
            const parent = layer
            l.on('change:visible', function(e) {
              setTimeout(() => {
                const brothers = parent.getLayers().getArray()
                const b = brothers.map(i => i.getVisible()).includes(true)
                parent.setVisible(b)
                layerConfig.visible = b
              }, 30)
            })
          })
        }
        delete layerConfig.layer // 删掉 ol layer 对象，否则 watch enabledLayersConfig 时候 Maximum call stack size exceeded
      })
      this.$emit('loaded', enabledLayersConfig, layerMapping)
    },
    // 图层配置改变时 更新到 图层
    layerConfigChangeSync2Layer(layerConfig, isGroup) {

      const { id, visible, opacity, legend, params, defs_temp } = layerConfig
      const layer = this.layerMapping[id]
      layer.setVisible(visible)
      !isBoolean(opacity) && layer.setOpacity(opacity)
      if (legend && visible) { // 图例 图层过滤
        // show:0,1 服务都是两个 layers
        let { layers, layerDefs, KFQLX } = params
        layers = layers || 'show:0,1'
        layerDefs = layerDefs || {}

        this.$set(params, 'layers', layers)
        this.$set(params, 'layerDefs', layerDefs)

        // layerDefs 处理  layers必须是 show 类型 `show:0,1` 这样的格式
        layers.split(':')[1].split(',').forEach(i => {
          if (!layerDefs[i]) {
            layerDefs[i] = '1 = 1'
          }
        })

        const { defs = {}} = legend
        // 启用的图例的 查询条件 集合
        let map = Object.values(defs).filter(i => i.enabled)
          .map(i => i.query || {})
        // 图层过滤条件 规整化
        map = map.reduce((sum, item) => {
          Object.entries(item).forEach(([k, v]) => {
            if (sum[k]) {
              Array.isArray(sum[k]) ? (sum[k].push(v)) : (sum[k] = [sum[k], v])
            } else {
              sum[k] = v
            }
          })
          return sum
        }, {})

        // 图层过滤条件 转字符串格式
        const query = Object.entries(map).map(([k, v]) => {
          if (Array.isArray(v)) {
            return `${k} in ('${v.join('\',\'')}')`
          }
          return `${k} = '${v}'`
        })
          .join(' and ')

        // 只有条件改变时 才重新设置参数
        if (legend.query !== query) {
          Object.entries(layerDefs).forEach(([k, v = '']) => {
            // 删除掉前一次的 过滤条件
            layerDefs[k] = v.replaceAll(` and ${legend.query}`, '')
            // 拼接当前 过滤条件
            layerDefs[k] += query ? ` and ${query}` : ''
          })

          // 记录当前 过滤条件
          legend.query = query
        }
        // 临时加 图层判断条件
        // if (defs_temp) {
        //   layerDefs[0] =  defs_temp
        //   layerDefs[1] =  defs_temp
        // }else{
        //   layerDefs[0]=" 1=1 "
        //   layerDefs[1]=" 1=1 "
        // }
      }



      // updateParams 要放到 图例处理 后面
      if (params && !isGroup) {
        const source = layer.getSource()
        source instanceof ImageArcGISRest && source.updateParams(params)
      }
    },
    getLayerMapping() {
      return this.layerMapping
    },
    getLayerById(id) {
      return this.layerMapping[id]
    },
    getLayerConfigById(id) {
      const element = this.layerMapping[id]
      let ele = element ? element.get(CONFIG_KEY) : undefined;
      return ele;
    }
  }
}
</script>

<style lang="scss" scoped>

</style>
