<template>
  <div class="tabs-container">
    <el-form :model="queryParams"
      inline>
      <el-form-item label="直播间">
        <el-select v-model="queryParams.brandList"
          multiple
          clearable
          collapse-tags
          collapse-tags-tooltip
          @change="queryChangeFn">
          <el-option v-for="str in brandList"
            :label="str"
            :value="str">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="数据类型">
        <el-select v-model="queryParams.typeList"
          multiple
          clearable
          collapse-tags
          collapse-tags-tooltip
          @change="queryChangeFn">
          <el-option v-for="str in typeList"
            :label="str"
            :value="str">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="日期选择">
        <el-date-picker v-model="queryParams.date"
          type="daterange"
          :clearable="false"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          :shortcuts="pickerOptions"
          @change="queryChangeFn('date')">
        </el-date-picker>
      </el-form-item>
    </el-form>
    <div class="chart_wrap"
      v-loading="loading">
      <template v-if="queryParams.brandList.length > 0 && queryParams.typeList.length > 0">
        <group-legend :legendData="chartData.legend"
          @click-item="legendChangeFn"></group-legend>
        <line-charts :chartData="chartData"></line-charts>
      </template>
      <no-data v-else-if="!loading"></no-data>
    </div>
    <levitated-sphere>
      <el-button type="danger"
        @click="reset">重置本页</el-button>
    </levitated-sphere>
  </div>
</template>

<script setup>
import LineCharts from './LineAndBar.vue'
import { getCmmListAPI } from '@/api'
import { generatorDayList, parseTime, getAdditionalColor, resetObjValue } from '@/utils'
import { useDatePickerOptions } from '@/hooks'

// 静态数据
const loading = ref(true)
const brandList = ref([]) // 直播间列表
const typeList = ref(['销售额', '观看人次']) // 数据类型列表
const { pickerOptions, nowMouth } = useDatePickerOptions() // 日期快捷方式

const queryParams = reactive({ // 查询表单
  brandList: [],
  date: [],
  typeList: []
})

const allChartData = reactive({ // 图表所有数据
  xAxis: [],
  legend: [],
  series: []
})
const chartData = reactive({ // 图表使用数据
  xAxis: [],
  legend: [],
  series: []
})

// 获取数据
const getList = async () => {
  loading.value = true
  // 重置数据源
  resetObjValue(allChartData)
  // 请求数据
  const { data } = await getCmmListAPI({
    startDate: parseTime(queryParams.date[0], '{y}-{m}-{d}'),
    endDate: parseTime(queryParams.date[1], '{y}-{m}-{d}')
  })
  // 获取 x 轴时间
  allChartData.xAxis = generatorDayList(queryParams.date[0], queryParams.date[1])
  // 获取 legend 和 series 数据
  data.map((list, index) => {
    // list：每个直播间
    // 按索引拿到颜色
    let color = getAdditionalColor(index)
    // 每个系列对象
    const saleObj = {
      name: list[0]?.name + '-销售额',
      type: 'bar',
      data: [],
      itemStyle: {
        color
      },
      color,
      yAxisIndex: 0
    }
    const gkrcObj = {
      name: list[0]?.name + '-观看人次',
      type: 'line',
      data: [],
      showSymbol: false,
      symbol: 'none',
      lineStyle: {
        width: 2, // 设置折线的宽度
        type: 'solid', // 设置折线的类型
        color
      },
      color,
      yAxisIndex: 1,
    }
    // 按照日期归并数据
    const listMap = new Map()
    list.forEach(o => {
      listMap.set(o.date.split('-').slice(1).join('-'), o)
    })
    allChartData.xAxis.forEach(date => {
      const findObj = listMap.get(date)
      if (findObj) {
        saleObj.data.push(findObj.saleSumTotal)
        gkrcObj.data.push(findObj.gkrcNumTotal)
      } else {
        saleObj.data.push(0)
        gkrcObj.data.push(0)
      }
    })
    // 添加系列数据
    allChartData.series.push(saleObj)
    allChartData.series.push(gkrcObj)

    // 添加图例数据
    allChartData.legend.push({
      data: [{
        name: saleObj.name,
        type: 'bar',
        color: color,
        effective: true,
        show: true,
      }, {
        name: gkrcObj.name,
        type: 'line',
        color: color,
        effective: true,
        show: true
      }],
      orient: 'verticalAlign'
    })
  })
  loading.value = false
  return data
}

// 筛选数据
const filterData = () => {
  let series = allChartData.series
  let legend = allChartData.legend
  // 直播间筛选
  if (queryParams.brandList.length > 0) {
    series = series.filter(obj => {
      return queryParams.brandList.find(nameStr => obj.name.split('-')[0] === nameStr)
    })
    legend = legend.filter(obj => {
      return queryParams.brandList.find(nameStr => obj.data.find(o => o.name.split('-')[0] === nameStr))
    })
  }
  // 数据类型筛选
  if (queryParams.typeList.length > 0) {
    series = series.filter(obj => {
      return queryParams.typeList.find(str => obj.name.split('-')[1] === str)
    })
    // 图例组件数据源不变，只是显示/隐藏
    legend.filter(obj => {
      obj.data.forEach((o, index) => {
        const isHave = queryParams.typeList.includes(o.name.split('-')[1])
        // 设置图例组件显示/隐藏
        if (!isHave) o.show = false
        else o.show = true
      })
    })
  } else {
    // 数据类型都没选
    legend.forEach(obj => {
      obj.data.forEach(o => {
        o.show = true
      })
    })
  }
  // 据图例状态，筛选数据显示
  series = series.filter(sObj => {
    let nowSeries = true
    legend.forEach(obj => {
      const now = obj.data.find(o => {
        return o.name === sObj.name
      })
      // now 图例对象无效，则当前 sObj 对象无效
      if (now?.effective === false) {
        nowSeries = false
      }
    })
    return nowSeries
  })
  // 最后赋予给要展示的部分
  chartData.legend = legend
  chartData.series = series
  chartData.xAxis = allChartData.xAxis
}

const init = async function () {
  // 初始化参数
  queryParams.date = nowMouth
  queryParams.typeList = [typeList.value[0]]
  // 请求数据
  const data = await getList()
  // 初始化直播间列表
  brandList.value = data.map(list => list[0].name)
  // 默认显示第一个
  queryParams.brandList = [brandList.value[0]]
  // 筛选图表数据
  filterData()
}
init()

// 筛选条件改变了
const queryChangeFn = async (arg) => {
  // 日期改变需要后台重新获取，其他改因为数据都给前台了，自己筛选
  if (arg === 'date' && queryParams.date) {
    await getList()
  }
  filterData()
}
// 图例点击改变了
const legendChangeFn = () => {
  filterData()
}
// 重置
const reset = async () => {
  // 重置查询参数
  queryParams.brandList = []
  queryParams.date = []
  queryParams.typeList = []
  init()
}
</script>