<template>
  <div>
    <el-card class="box-card box-card-h">
      <el-row justify="space-between" class="x-y-axis">
        <el-text>值轴/{{ boxName }}</el-text>
        <el-tooltip
            effect="dark"
            :content="boxName+'，数据类型必须一致！'"
            placement="bottom"
        >
          <el-icon>
            <Warning/>
          </el-icon>
        </el-tooltip>
      </el-row>
      <div class="drag-block">
        <draggable
            class="list-group"
            :list="dragList"
            itemKey="id"
            :group="group"
            @start="startDrag"
            @change="dragChartItem"
        >
          <template #item="{ element,index }">
            <div :id="element.dataType==='value'?'card_'+index:''" tabindex="1"
                 @click.stop="handleClickValueCard(element,index)">
              <el-card shadow="hover" class="cards x-y-cards"
                       :style="{borderWidth:1,borderColor:element.dataType==='value'?element.color:'#e4e7ed'}">
                <el-col :span="3">
                  <div>{{ element.label }}</div>
                </el-col>
                <el-col :span="13">
                  <div v-if="element.dataType==='value'" class="update-color">
                    <div class="update-color" @click.stop>
                      <span>图形：</span>
                      <el-color-picker v-model="element.color" :color="element.color"
                                       @change="changeEchartsColor($event,index)" @active-change="handleActiveChange"/>
                    </div>
                    <div v-if="currentChart==='line'" class="update-color" @click.stop>
                      <span>阴影：</span>
                      <el-color-picker v-model="element.lineStyle.shadowColor" :color="element.lineStyle.shadowColor"
                                       @change="changeShadowColor($event,index)" @active-change="handleActiveChange"/>
                    </div>
                    <div v-if="currentChart==='bar'" class="update-color" @click.stop>
                      <span>背景: </span>
                      <el-color-picker v-model="element.backgroundStyle.color" :color="element.backgroundStyle.color"
                                       @change="changeBackgroundColor($event,index)" @active-change="handleActiveChange"/>
                    </div>
                    <div v-if="currentChart==='bar'" class="update-color" @click.stop>
                      <span >描边: </span>
                      <el-color-picker v-model="element.backgroundStyle.borderColor" :color="element.backgroundStyle.borderColor"
                                       @change="changeBackgroundBorderColor($event,index)" @active-change="handleActiveChange"/>
                    </div>
                  </div>
                </el-col>
                <el-col :span="4">
                  <div class="cards-right">
                    <span>{{ element.dataType }}</span>
                    <el-icon size="20" color="red" @click.stop="handleCancelAxis(element,index)"
                             style="cursor: pointer">
                      <CircleClose/>
                    </el-icon>
                  </div>
                </el-col>
              </el-card>
            </div>
          </template>
        </draggable>
      </div>
    </el-card>
  </div>
</template>

<script setup>
import draggable from 'vuedraggable'

const emit = defineEmits(["editBasicSettingList"])
const props = defineProps({
  //box名字
  boxName: {
    type: String,
    default: ''
  },
  //可供拖动的选项列表
  dragOptions: {
    type: Array,
    default: []
  },
  //用于拖拽区域存放选项列表
  dragList: {
    type: Array,
    default: []
  },
  //用于X轴区域存放拖动的选项
  xAxisList: {
    type: Array,
    default: []
  },
  //用于Y轴区域存放拖动的选项
  yAxisList: {
    type: Array,
    default: []
  },
  //标记正在拖动选项的数据类型是否value
  flag: {
    type: Boolean,
    default: false
  },
  //获取正在拖动选项的数据类型
  startDataType: {
    type: String,
    default: ''
  },
  //初始化加载echarts函数
  initCharts: {
    type: Function,
    default: null
  },
  //echarts的配置属性
  chartOption: {
    type: Array,
    default: []
  },
  //当前echarts图形
  currentChart: {
    type: String,
    default: 'line'
  }
})
//基础设置列表
const lineChartBasicSettingList = ref()
const barChartBasicSettingList = ref()
//选中类型为value的item所处的list列表
const valueCardInList = ref([])
//简化代码
let xList = reactive(props.xAxisList)
let yList = reactive(props.yAxisList)
let option = reactive(props.chartOption)
//路由刷新
const reload = inject("reload")
//自定义X/Y分组的拖入拖出事件
const group = ref({
  name: 'people',
  pull: true,
  put: props.flag === true ? false : (props.boxName === 'X轴' ? () => handleGroupPut(xList, yList) : () => handleGroupPut(yList, xList))
})
//将改变的数据传到父组件
watch(() => lineChartBasicSettingList.value, (newVal) => {
  emit("getLineChartBasicSettingList", newVal)
})
//将改变的数据传到父组件
watch(() => barChartBasicSettingList.value, (newVal) => {
  emit("getBarChartBasicSettingList", newVal)
})
onMounted(() => {
  document.addEventListener('click', nullBlockClick)
})
onBeforeUnmount(() => {
  document.removeEventListener('click', nullBlockClick)
})
/**
 * 设置chart的lineStyle
 * @param sItem chartItem
 * @param opacity 透明度
 */
const handleChangeLineStyle = (sItem, opacity) => {
  sItem.lineStyle = {
    shadowColor: sItem.lineStyle.shadowColor,
    shadowBlur: sItem.lineStyle.shadowBlur,
    opacity: opacity
  }
}
/**
 * 用于取消charts选中透明度
 */
const handleChangeOpacity = (type, item) => {
  if (props.currentChart === 'line') {
    option.series.forEach((sItem) => {
      if (type === 'more') {
        if (sItem.name === item.label) {
          handleChangeLineStyle(sItem, 1)
        } else {
          handleChangeLineStyle(sItem, 0.2)
        }
      } else if (type === 'single') {
        handleChangeLineStyle(sItem, 1)
      } else {
        if (sItem.name !== item.label) {
          handleChangeLineStyle(sItem, 1)
        }
      }
    })
  }
}
/**
 * 点击空白处, 清除选项选中状态
 */
const nullBlockClick = () => {
  if (valueCardInList.value.length === 0) return;
  valueCardInList.value.forEach((aItem, aIndex) => {
    const card = document.getElementById('card_' + aIndex)
    card.classList.remove('card-active')
  })
  clearBasicSetting()
  //加载echarts
  props.initCharts()
}
/**
 * 封装自定义X/Y分组的拖入事件
 * @param aType 传入x/y区域数组
 * @param bType 传入x/y区域数组
 * @returns {boolean} 返回 true/false
 */
const handleGroupPut = (aType, bType) => {
  let flag = false
  let aLen = aType.length
  let bLen = bType.length
  if (aLen === 0 && bLen === 0) {
    flag = props.startDataType === 'key';
  } else if (aLen === 0 && bLen !== 0) {
    flag = bType[0].dataType === 'key';
  } else if (aLen !== 0 && bLen !== 0) {
    const dragType = localStorage.getItem('dragType')
    flag = props.startDataType === aType[0].dataType;
    if (dragType === 'key') {
      flag = aType[0].dataType !== 'value';
    }
  }
  return flag
}
/**
 * 封装切换坐标轴数据类型为Category
 * @param item 拖动的项
 * @param label 坐标轴名称
 * @param type 切换x/y轴
 */
const changeTypeToCategory = (item, label, type) => {
  let axis
  if (type === 'xAxis') {
    axis = option.xAxis
  } else {
    axis = option.yAxis
  }
  axis.type = 'category'
  axis.name = label
  axis.data = item.data
}

/**
 * 封装清除坐标轴数据
 * @param type 标志清除x/y轴
 */
const clearAxisData = (type) => {
  let axis
  if (type === 'xAxis') {
    axis = option.xAxis
  } else {
    axis = option.yAxis
  }
  axis.name = ''
  axis.data = []
}
/**
 * 封装key拖入左侧时的重置事件
 * @param aList x/yList
 * @param type x/yAxis
 * @param item 选项item
 * @param label 选项名
 */
const restoreChart = (aList, type,item,label) => {
  let axis
  if (type === 'xAxis') {
    axis = option.xAxis
  } else {
    axis = option.yAxis
  }
  if (aList[0].dataType === 'value') {
    aList.map((item) => {
      props.dragOptions.unshift(item)
      option.legend.selected[item.label] = false
    })
    aList.splice(0, aList.length)
    option.legend.data.splice(0, option.legend.data.length)
    option.series.splice(0, option.series.length)
    axis.name = ''
    option.xAxis.type = 'category'
    option.yAxis.type = 'value'
  } else {
    changeTypeToCategory(item, label, type)
  }
}

/**
 * 拖拽类型为key的选项事件
 * @param item 选项item
 * @param label 选项名
 */
const dragTypeToKey = (item, label) => {
  if (xList.length !== 0 && yList.length === 0) {
    restoreChart(xList, 'xAxis',item,label)
    clearAxisData('yAxis')
  } else if (xList.length === 0 && yList.length !== 0) {
    restoreChart(yList, 'yAxis',item,label)
    clearAxisData('xAxis')
  } else if (xList.length === 0 && yList.length === 0) {
    //移入左侧待选列表
    clearAxisData('xAxis')
    clearAxisData('yAxis')
  }
}
/**
 * 拖拽类型为value的选项事件
 * @param label 选项名
 */
const dragTypeToValue = (label) => {
  //删除选中选项的图例
  const legendIndex = option.legend.data.findIndex(object => object === label);
  option.legend.data.splice(legendIndex, 1)
  //删除echarts配置项series中符合该拖拽选项的item
  const objectIndex = option.series.findIndex(object => object.name === label);
  option.legend.selected[label] = false
  option.series.splice(objectIndex, 1)
  if (xList.length === 0) {
    option.xAxis.name = ''
  } else if (yList.length === 0) {
    option.yAxis.name = ''
  }
  clearBasicSetting()
  handleDeleteClassName(xList, yList)
}
/**
 * 封装清空基本设置
 */
const clearBasicSetting=()=>{
  if(props.currentChart==='line'){
    lineChartBasicSettingList.value = []
    handleChangeOpacity('single')
  }else if(props.currentChart==='bar'){
    barChartBasicSettingList.value=[]
  }
}

/**
 * 开始拖拽事件
 * @param event event事件
 */
const startDrag = (event) => {
  localStorage.setItem('dragType', event.item._underlying_vm_.dataType)
}

/**
 * 从X轴/Y轴区域移动选项到左/右侧结束事件
 * @param event event事件
 */
const dragChartItem = (event) => {
  if (event.removed === undefined) return;
  let item = event.removed.element
  let label = item.label
  //拖动key的选项
  if (item.dataType === "key") {
    dragTypeToKey(item, label)
  } else {
    dragTypeToValue(label)
  }
  props.initCharts()
  localStorage.removeItem('dragType')
}

/**
 * 选中数据类型为value的点击事件
 * @param item 点击的选项item
 * @param index 点击选项的下标
 */
const handleClickValueCard = (item, index) => {
  document.addEventListener('click', nullBlockClick)
  if (item.dataType === 'value' ) {
    if(props.currentChart === 'line'){
      changeCardActive(props.dragList, item)
      lineChartBasicSettingList.value = [item]
    }else  if(props.currentChart === 'bar'){
      changeCardActive(props.dragList, item)
      barChartBasicSettingList.value = [item]
    }
  }
  props.initCharts()
}

/**
 * 封装选中类型为value的数据高亮
 * @param list x/y区域list
 * @param item 点击选项的item
 */
const changeCardActive = (list, item) => {
  valueCardInList.value = list
  emit('getCardActiveList',list)
  if (list.length !== 0 && list[0].dataType === 'value') {
    handleChangeOpacity('more', item)
    list.forEach((aItem, aIndex) => {
      const card = document.getElementById('card_' + aIndex)
      if (aItem.label === item.label) {
        card.classList.add('card-active')
      } else {
        card.classList.remove('card-active')
      }
    })
  }
}

/**
 * 基础设置: 修改echarts数据颜色
 * @param val 修改的标记大小
 * @param index 修改的chart项下标
 */
const changeEchartsColor = (val, index) => {
  document.addEventListener('click', nullBlockClick)
  option.series[index].color = val
  props.initCharts()
}
/**
 * 当选择颜色时移除空白点击事件
 */
const handleActiveChange = () => {
  document.removeEventListener('click', nullBlockClick)
}

/**
 * 基础设置: 修改echarts数据颜色
 * @param val 修改的标记大小
 * @param index 修改的chart项下标
 */
const changeShadowColor = (val, index) => {
  option.series[index].lineStyle.shadowColor = val
  props.initCharts()
}
/**
 * 基础设置:修改柱条背景颜色
 * @param val 柱条颜色
 * @param index 修改的chart项下标
 */
const changeBackgroundColor = (val, index) => {
  option.series[index].backgroundStyle.color = val
  props.initCharts()
}
/**
 * 基础设置:修改柱条描边颜色
 * @param val 柱条描边颜色
 * @param index 修改的chart项下标
 */
const changeBackgroundBorderColor = (val, index) => {
  option.series[index].backgroundStyle.borderColor = val
  props.initCharts()
}
/**
 * 封装从右侧区域拖出事件
 * @param element 获取点击该拖出的选项事件
 * @param index 点击该拖出选项的索引
 * @param aList x/y区域的值
 * @param bList x/y区域的值
 * @param aAxis echarts配置项的x/y轴
 * @param bAxis echarts配置项的x/y轴
 */
const handleCancel = (element, index, aList, bList, aAxis, bAxis) => {
  aList.splice(index, 1)
  props.dragOptions.push(element)
  if (element.dataType === "key") {
    aAxis.name = ''
    aAxis.data = []
    bAxis.name=''
    bList.map((item) => {
      props.dragOptions.unshift(item)
      option.legend.selected[item.label] = false
    })
    bList.splice(0, bList.length)
    option.legend.data.splice(0, option.legend.data.length)
    option.series.splice(0, option.series.length)
    // reload
    props.initCharts()
  } else {
    if (bList.length !== 0 && aList.length === 0) {
      if (bList[0].dataType === 'key') {
        aAxis.name = ''
      } else {
        bAxis.name = ''
      }
    }

    option.legend.data.splice(index, 1)
    const objectIndex = option.series.findIndex(object => object.name === element.label);
    option.legend.selected[element.label] = false
    option.series.splice(objectIndex, 1)
    props.initCharts()
  }
  if(props.currentChart==='line'){
    handleChangeOpacity('not', element)
    if (lineChartBasicSettingList.value === undefined) return;
    lineChartBasicSettingList.value.splice(0, 1)
  }else if(props.currentChart==='bar'){
    if (barChartBasicSettingList.value === undefined) return;
    barChartBasicSettingList.value.splice(0, 1)
  }
  //   const basicIndex = lineChartBasicSettingList.value.findIndex(object => object.label === element.label)
  //   if (basicIndex !== -1) {
  //     lineChartBasicSettingList.value.splice(basicIndex, 1)
  //   }
  handleDeleteClassName(aList, bList)
  props.initCharts()
}
/**
 * 拖拽选项后,清除选中选项阴影
 * @param aList x/y list
 * @param bList x/y list
 */
const handleDeleteClassName = (aList, bList) => {
  let axis = []
  if (aList.length !== 0 && aList[0].dataType === 'value') {
    axis = aList
  } else if (bList.length !== 0 && bList[0].dataType === 'value') {
    axis = bList
  }
  axis.forEach((aItem, aIndex) => {
    const card = document.getElementById('card_' + aIndex)
    card.classList.remove('card-active')
  })
}
/**
 * 从右侧x/y轴区域取消选项
 * @param element 该取消的项
 * @param index 该取消项的下标
 */
const handleCancelAxis = (element, index) => {
  if (props.boxName === 'X轴') {
    handleCancel(element, index, xList, yList, option.xAxis, option.yAxis)
  } else {
    handleCancel(element, index, yList, xList, option.yAxis, option.xAxis)
  }
}
</script>
