import {
  DEFAULT_AXIS_COLOR,
  DEFAULT_BARLINE_GRID,
  DEFAULT_FONT_COLOR,
  DEFAULT_FONT_FAMILY,
  DEFAULT_FONT_SIZE,
  DEFAULT_FONT_WEIGHT,
  DEFAULT_LABEL_COLOR,
  DEFAULT_LEGEND_BAR_ICON,
  DEFAULT_LEGEND_LINE_ICON,
  DEFAULT_LINE_HEIGHT,
  DEFAULT_TOOLBOX_ICON,
} from '../../constants'
import { getTooltip, stack2Map, valueMap } from './utils'

function getLegend({ metrics, labelMap, types }) {
  return {
    left: '2%',
    itemHeight: 12,
    itemWidth: 12,
    itemGap: 25,
    top: 30,
    data: metrics.map((item, index) => {
      let icon = DEFAULT_LEGEND_BAR_ICON
      if (types[index] === 'line') {
        icon = DEFAULT_LEGEND_LINE_ICON
      }
      return { name: labelMap[item] ? labelMap[item] : item, icon: icon }
    }),
  }
}

function getToolbox({ name, icon, toolboxFunction }) {
  return {
    top: 26,
    itemSize: 16,
    right: 35,
    feature: {
      myTool: {
        show: true,
        title: name,
        icon: icon ? icon : DEFAULT_TOOLBOX_ICON,
        iconStyle: {
          borderColor: 'rgba(72, 131, 251, 1)',
        },
        emphasis: {
          iconStyle: {
            textPosition: 'top',
          },
        },
        onclick: function() {
          toolboxFunction()
        },
      },
    },
  }
}

function getXAxis({ dimension, values, axisVisible, xAxisType }) {
  return dimension.map((item, index) => ({
    type: xAxisType,
    data: values.map(row => row[item]),
    show: axisVisible[0],
    axisLabel: {
      show: true,
      margin: 10,
      color: DEFAULT_FONT_COLOR,
      fontSize: DEFAULT_FONT_SIZE,
      fontFamily: DEFAULT_FONT_FAMILY,
      fontWeight: DEFAULT_FONT_WEIGHT,
      lineHeight: DEFAULT_LINE_HEIGHT,
    },
    axisLine: {
      show: true,
      lineStyle: {
        width: 1,
        type: 'solid',
        color: DEFAULT_AXIS_COLOR,
      },
    },
    axisTick: {
      show: true,
      alignWithLabel: true,
      inside: true,
      length: 6,
      lineStyle: {
        width: 1,
        type: 'solid',
      },
    },
    splitLine: {
      show: false,
    },
  }))
}

function getYAxis(yAxisAttribute, axisVisible) {
  const y = yAxisAttribute.map(({ name, unit, min, max, position }, index) => {
    let padding = []
    if ((position && position === 'left') || index === 0) {
      padding = [0, 0, 15, -65]
    } else {
      padding = [0, -45, 15, 0]
    }

    return {
      type: 'value',
      show: axisVisible[1],
      name: name + '/' + unit,
      nameTextStyle: {
        padding: padding,
      },
      splitNumber: 5,
      min: min,
      max: max,
      position: position,
      axisTick: {
        show: false,
      },
      axisLabel: {
        formatter: '{value}' + unit,
        color: DEFAULT_FONT_COLOR,
        fontSize: DEFAULT_FONT_SIZE,
        fontFamily: DEFAULT_FONT_FAMILY,
        fontWeight: DEFAULT_FONT_WEIGHT,
      },
      axisLine: {
        show: false,
      },
      splitLine: {
        show: true,
        lineStyle: {
          width: 1,
          type: 'solid',
          color: DEFAULT_AXIS_COLOR,
        },
      },
    }
  })
  return y
}

function getSeries({
  dimension,
  values,
  metrics,
  area,
  stack,
  labelMap,
  label,
  itemStyle,
  lineStyle,
  areaStyle,
  chartColors,
  types,
  shadowAreas,
  lineYAxisIndex,
}) {
  const series = []
  const stackMap = stack && stack2Map(stack)
  const dataTemp = valueMap(values, metrics, dimension)

  metrics.forEach((item, index) => {
    let seriesItem = {}
    if (types[index] === 'bar') {
      seriesItem = {
        name: labelMap[item] || item,
        type: types[index],
        barWidth: 12,
        data: dataTemp[item],
      }
    } else {
      seriesItem = {
        name: labelMap[item] || item,
        type: types[index],
        yAxisIndex: lineYAxisIndex,
        data: dataTemp[item],
        smooth: true,
        itemStyle: {
          normal: {
            lineStyle: {
              width: 1,
            },
          },
        },
      }
    }
    if (stack && stackMap[item]) seriesItem.stack = stackMap[item]
    if (area) {
      seriesItem.areaStyle = {
        normal: {
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              {
                offset: 0,
                color: chartColors[index],
              },
              {
                offset: 1,
                color: '#fff',
              },
            ],
            global: false,
          },
        },
      }
    }
    if (label) seriesItem.label = label
    if (itemStyle) seriesItem.itemStyle = itemStyle
    if (lineStyle) seriesItem.lineStyle = lineStyle
    if (areaStyle) seriesItem.areaStyle = areaStyle
    series.push(seriesItem)
  })
  if (shadowAreas[1]) {
    shadowAreas.forEach((item, index) => {
      let seriesItem = {
        type: 'line',
        yAxisIndex: lineYAxisIndex,
        markArea: {
          silent: true,
          itemStyle: {
            color: DEFAULT_LABEL_COLOR,
            opacity: 0.08,
          },
          label: {
            show: true,
            color: DEFAULT_LABEL_COLOR,
          },
          data: [
            // [{ xAxis: 0, itemStyle: { color: '#ed5555' } }, { xAxis: 1 }],
            [
              {
                coord: [item.start, 100],
                name: item.name,
              },
              {
                coord: [item.end, 0],
              },
            ],
          ],
        },
      }
      series.push(seriesItem)
    })
  }
  return series
}

export const barline = (keys, values, settings, extra) => {
  keys = Array.isArray(keys) ? keys : []
  values = Array.isArray(values) ? values : []
  let types = []
  let units = {}

  let tempMetrics = keys.slice(1).map((v, i) => {
    if (Array.isArray(v)) {
      types.push(v[1])
      units[v[0]] = v[2]
      return v[0]
    }
    types.push('bar')
    units[v] = '人'
    return v
  })

  const {
    // 纬度 def:keys[0]
    dimension = [keys[0]],
    // 自定义数据项
    metrics = tempMetrics,
    //左上角的按钮属性
    toolboxAttribute = {},
    // visible slots:[xAxis, yAxis]
    axisVisible = [true, true],
    // yAxis name unit min max position(left/right)
    yAxisAttribute = [],
    // echarts axis type
    xAxisType = 'category',
    //折线图和阴影区域对应的值
    lineYAxisIndex = 1,
    // 阴影区域属性 name start end
    shadowAreas = [],
    // sort data, type: normal, asc, desc
    sortData = 'normal',
    // area flag
    area = false,
    // customize stack obj
    stack,
    // label 名称字典
    labelMap = {},
    /**
     * echarts opts
     */
    grid,
    label,
    itemStyle,
    lineStyle,
    areaStyle,
  } = settings
  const { tooltipVisible, legendVisible, tooltipFormatter, chartColors } = extra
  // if has labelMap need to add new key&val Map to units
  if (Object.keys(labelMap).length !== 0) {
    _.forEach(units, function(v, key) {
      if (labelMap[key]) units[labelMap[key]] = v
    })
  }

  const legend = legendVisible && getLegend({ metrics, labelMap, types })

  const tooltip =
    tooltipVisible &&
    getTooltip({
      triggerType: 'axis',
      tooltipFormatter,
      units,
      sortData,
    })
  const xAxis = getXAxis({
    dimension,
    values,
    axisVisible,
    xAxisType,
  })
  const yAxis = getYAxis(yAxisAttribute, axisVisible)
  const series = getSeries({
    dimension,
    values,
    metrics,
    area,
    stack,
    labelMap,
    label,
    itemStyle,
    lineStyle,
    areaStyle,
    chartColors,
    types,
    shadowAreas,
    lineYAxisIndex,
  })
  const toolbox = getToolbox(toolboxAttribute)
  const options = {
    legend,
    tooltip,
    toolbox,
    xAxis,
    yAxis,
    series,
    color: chartColors,
  }
  options.grid = grid ? grid : DEFAULT_BARLINE_GRID
  return options
}
