import Layer from '../layer'
import Source from '../source'
import cloneDeep from 'lodash/cloneDeep'
import { LineLayer, PolygonLayer, Popup } from '@cgcs2000/l7'
import renderPopup from '../libs/render_popup'

class Polygon extends Layer {
  constructor(layer, scene, zIndex) {
    super(layer, scene, zIndex)
    let { visible, minZoom, maxZoom } = this.layer
    this.polygonLayer = new PolygonLayer({
      visible: visible === undefined ? true : !!visible,
      minZoom: Number(minZoom) || 0,
      maxZoom: Number(maxZoom) || 18,
      zIndex
    })
    this.lineLayer = new LineLayer({
      visible: visible === undefined ? true : !!visible,
      minZoom: Number(minZoom) || 0,
      maxZoom: Number(maxZoom) || 18,
      zIndex: zIndex + 0.1
    })
    this.setSource()
    this.polygonLayer.on('click', e => {
      const popup = new Popup({
        offsets: [0, 0],
        closeButton: true
      })
        .setLnglat(e.lngLat)
        .setHTML(renderPopup(e.feature))
      scene.addPopup(popup)
    })
  }

  render() {
    this.setAction()
    this.setShape()
    this.setStyle()
    this._scene.addLayer(this.polygonLayer)
    this._scene.addLayer(this.lineLayer)
    this.rendered = true
  }

  setShape() {
    let { shape } = this._mergeProperties()
    this.polygonLayer.shape(shape)
    this.lineLayer.shape('line')
  }

  setStyle() {
    let { style } = this._mergeProperties()
    let { color } = style
    if (typeof color === 'string') {
      this.polygonLayer.color(color)
    } else {
      let { field, type, stops } = color
      if (type === 'interval') {
        this.polygonLayer.color(field, value => {
          let st = stops.find(stop => {
            let { min, max } = stop
            min = typeof min !== 'number' ? -Infinity : min
            max = typeof max !== 'number' ? Infinity : max
            return value >= min && value <= max
          })
          if (st) {
            return st.color
          } else {
            return '#000000'
          }
        })
      } else {
        this.polygonLayer.color(field, value => {
          let st = stops.find(stop => stop.value == value)
          if (st) {
            return st.color
          } else {
            return '#000000'
          }
        })
      }
    }
    this.lineLayer
      .color(style.lineColor)
      .size(style.lineWidth)
      .style({
        lineType: style.lineType,
        dashArray: style.dashArray
      })
  }

  setSource() {
    this.off('source.load')
    let source = this.layer.source
    if (!source || Object.keys(source).length === 0) {
      return
    }
    this.sourceInstance = new Source(this.layer.id, source, this)
    this.once('source.load', ({ data }) => {
      let source = this.layer.source
      let parser = {
        type: source.type
      }
      if (source.parser) {
        parser = Object.assign(cloneDeep(source.parser), {
          type: source.type
        })
      }
      let options = { parser }
      if (!this.rendered) {
        this.polygonLayer.source(data, options)
        this.lineLayer.source(data, options)
        this.render()
      } /* else {
        this.layerInstance.setData(data, options)
      }*/
    })
  }

  setAction() {
    let { action } = this._mergeProperties()
    this.polygonLayer.active(action.hover)
    this.polygonLayer.select(action.select)
  }

  remove() {
    this._scene.removeLayer(this.polygonLayer)
    this._scene.removeLayer(this.lineLayer)
  }

  show() {
    this.polygonLayer.show()
    this.lineLayer.show()
  }

  hide() {
    this.polygonLayer.hide()
    this.lineLayer.hide()
  }

  fitBounds() {
    this.polygonLayer.fitBounds({
      padding: 100
    })
  }

  setIndex(index) {
    this.polygonLayer.setIndex(index)
    this.lineLayer.setIndex(index + 0.1)
  }
}

export default Polygon
