import Graphics from '../Graphics'
import Utils from '../../utils/Utils'

export default class Helpers {
  constructor(lgCtx) {
    this.w = lgCtx.w
    this.lgCtx = lgCtx
  }

  getLegendStyles() {
    let stylesheet = document.createElement('style')
    stylesheet.setAttribute('type', 'text/css')

    const text = `	
    	
      .apexcharts-legend {	
        display: flex;	
        overflow: auto;	
        padding: 0 10px;	
      }	
      .apexcharts-legend.apx-legend-position-bottom, .apexcharts-legend.apx-legend-position-top {	
        flex-wrap: wrap	
      }	
      .apexcharts-legend.apx-legend-position-right, .apexcharts-legend.apx-legend-position-left {	
        flex-direction: column;	
        bottom: 0;	
      }	
      .apexcharts-legend.apx-legend-position-bottom.apexcharts-align-left, .apexcharts-legend.apx-legend-position-top.apexcharts-align-left, .apexcharts-legend.apx-legend-position-right, .apexcharts-legend.apx-legend-position-left {	
        justify-content: flex-start;	
      }	
      .apexcharts-legend.apx-legend-position-bottom.apexcharts-align-center, .apexcharts-legend.apx-legend-position-top.apexcharts-align-center {	
        justify-content: center;  	
      }	
      .apexcharts-legend.apx-legend-position-bottom.apexcharts-align-right, .apexcharts-legend.apx-legend-position-top.apexcharts-align-right {	
        justify-content: flex-end;	
      }	
      .apexcharts-legend-series {	
        cursor: pointer;	
        line-height: normal;	
      }	
      .apexcharts-legend.apx-legend-position-bottom .apexcharts-legend-series, .apexcharts-legend.apx-legend-position-top .apexcharts-legend-series{	
        display: flex;	
        align-items: center;	
      }	
      .apexcharts-legend-text {	
        position: relative;	
        font-size: 14px;	
      }	
      .apexcharts-legend-text *, .apexcharts-legend-marker * {	
        pointer-events: none;	
      }	
      .apexcharts-legend-marker {	
        position: relative;	
        display: inline-block;	
        cursor: pointer;	
        margin-right: 3px;	
        border-style: solid;
      }	
      	
      .apexcharts-legend.apexcharts-align-right .apexcharts-legend-series, .apexcharts-legend.apexcharts-align-left .apexcharts-legend-series{	
        display: inline-block;	
      }	
      .apexcharts-legend-series.apexcharts-no-click {	
        cursor: auto;	
      }	
      .apexcharts-legend .apexcharts-hidden-zero-series, .apexcharts-legend .apexcharts-hidden-null-series {	
        display: none !important;	
      }	
      .apexcharts-inactive-legend {	
        opacity: 0.45;	
      }`

    let rules = document.createTextNode(text)

    stylesheet.appendChild(rules)

    return stylesheet
  }

  getLegendBBox() {
    const w = this.w
    let currLegendsWrap = w.globals.dom.baseEl.querySelector(
      '.apexcharts-legend'
    )
    let currLegendsWrapRect = currLegendsWrap.getBoundingClientRect()

    let currLegendsWrapWidth = currLegendsWrapRect.width
    let currLegendsWrapHeight = currLegendsWrapRect.height

    return {
      clwh: currLegendsWrapHeight,
      clww: currLegendsWrapWidth
    }
  }

  appendToForeignObject() {
    const gl = this.w.globals

    gl.dom.elLegendForeign.appendChild(this.getLegendStyles())
  }

  toggleDataSeries(seriesCnt, isHidden) {
    const w = this.w
    if (w.globals.axisCharts || w.config.chart.type === 'radialBar') {
      w.globals.resized = true // we don't want initial animations again

      let seriesEl = null

      let realIndex = null

      // yes, make it null. 1 series will rise at a time
      w.globals.risingSeries = []

      if (w.globals.axisCharts) {
        seriesEl = w.globals.dom.baseEl.querySelector(
          `.apexcharts-series[data\\:realIndex='${seriesCnt}']`
        )
        realIndex = parseInt(seriesEl.getAttribute('data:realIndex'), 10)
      } else {
        seriesEl = w.globals.dom.baseEl.querySelector(
          `.apexcharts-series[rel='${seriesCnt + 1}']`
        )
        realIndex = parseInt(seriesEl.getAttribute('rel'), 10) - 1
      }

      if (isHidden) {
        const seriesToMakeVisible = [
          {
            cs: w.globals.collapsedSeries,
            csi: w.globals.collapsedSeriesIndices
          },
          {
            cs: w.globals.ancillaryCollapsedSeries,
            csi: w.globals.ancillaryCollapsedSeriesIndices
          }
        ]
        seriesToMakeVisible.forEach((r) => {
          this.riseCollapsedSeries(r.cs, r.csi, realIndex)
        })
      } else {
        this.hideSeries({ seriesEl, realIndex })
      }
    } else {
      // for non-axis charts i.e pie / donuts
      let seriesEl = w.globals.dom.Paper.select(
        ` .apexcharts-series[rel='${seriesCnt + 1}'] path`
      )

      const type = w.config.chart.type
      if (type === 'pie' || type === 'polarArea' || type === 'donut') {
        let dataLabels = w.config.plotOptions.pie.donut.labels

        const graphics = new Graphics(this.lgCtx.ctx)
        graphics.pathMouseDown(seriesEl.members[0], null)
        this.lgCtx.ctx.pie.printDataLabelsInner(
          seriesEl.members[0].node,
          dataLabels
        )
      }

      seriesEl.fire('click')
    }
  }

  hideSeries({ seriesEl, realIndex }) {
    const w = this.w

    let series = Utils.clone(w.config.series)

    if (w.globals.axisCharts) {
      let shouldNotHideYAxis = false

      if (
        w.config.yaxis[realIndex] &&
        w.config.yaxis[realIndex].show &&
        w.config.yaxis[realIndex].showAlways
      ) {
        shouldNotHideYAxis = true
        if (w.globals.ancillaryCollapsedSeriesIndices.indexOf(realIndex) < 0) {
          w.globals.ancillaryCollapsedSeries.push({
            index: realIndex,
            data: series[realIndex].data.slice(),
            type: seriesEl.parentNode.className.baseVal.split('-')[1]
          })
          w.globals.ancillaryCollapsedSeriesIndices.push(realIndex)
        }
      }

      if (!shouldNotHideYAxis) {
        w.globals.collapsedSeries.push({
          index: realIndex,
          data: series[realIndex].data.slice(),
          type: seriesEl.parentNode.className.baseVal.split('-')[1]
        })
        w.globals.collapsedSeriesIndices.push(realIndex)

        let removeIndexOfRising = w.globals.risingSeries.indexOf(realIndex)

        w.globals.risingSeries.splice(removeIndexOfRising, 1)
      }
    } else {
      w.globals.collapsedSeries.push({
        index: realIndex,
        data: series[realIndex]
      })
      w.globals.collapsedSeriesIndices.push(realIndex)
    }

    let seriesChildren = seriesEl.childNodes
    for (let sc = 0; sc < seriesChildren.length; sc++) {
      if (
        seriesChildren[sc].classList.contains('apexcharts-series-markers-wrap')
      ) {
        if (seriesChildren[sc].classList.contains('apexcharts-hide')) {
          seriesChildren[sc].classList.remove('apexcharts-hide')
        } else {
          seriesChildren[sc].classList.add('apexcharts-hide')
        }
      }
    }

    w.globals.allSeriesCollapsed =
      w.globals.collapsedSeries.length === w.config.series.length

    series = this._getSeriesBasedOnCollapsedState(series)
    this.lgCtx.ctx.updateHelpers._updateSeries(
      series,
      w.config.chart.animations.dynamicAnimation.enabled
    )
  }

  riseCollapsedSeries(collapsedSeries, seriesIndices, realIndex) {
    const w = this.w
    let series = Utils.clone(w.config.series)

    if (collapsedSeries.length > 0) {
      for (let c = 0; c < collapsedSeries.length; c++) {
        if (collapsedSeries[c].index === realIndex) {
          if (w.globals.axisCharts) {
            series[realIndex].data = collapsedSeries[c].data.slice()
            collapsedSeries.splice(c, 1)
            seriesIndices.splice(c, 1)
            w.globals.risingSeries.push(realIndex)
          } else {
            series[realIndex] = collapsedSeries[c].data
            collapsedSeries.splice(c, 1)
            seriesIndices.splice(c, 1)
            w.globals.risingSeries.push(realIndex)
          }
        }
      }

      series = this._getSeriesBasedOnCollapsedState(series)

      this.lgCtx.ctx.updateHelpers._updateSeries(
        series,
        w.config.chart.animations.dynamicAnimation.enabled
      )
    }
  }

  _getSeriesBasedOnCollapsedState(series) {
    const w = this.w

    if (w.globals.axisCharts) {
      series.forEach((s, sI) => {
        if (w.globals.collapsedSeriesIndices.indexOf(sI) > -1) {
          series[sI].data = []
        }
      })
    } else {
      series.forEach((s, sI) => {
        if (w.globals.collapsedSeriesIndices.indexOf(sI) > -1) {
          series[sI] = 0
        }
      })
    }

    return series
  }
}
