<template>
  <div>
    <el-form :model="queryParams"
      inline>
      <el-form-item label="商品">
        <el-select v-model="queryParams.prdList"
          class="prd-select"
          @change="queryChangeFn"
          filterable
          multiple
          clearable
          collapse-tags
          collapse-tags-tooltip>
          <el-option v-for="obj in prdList"
            :label="obj.prdName"
            :value="obj.prdId">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="数据类型">
        <el-select v-model="queryParams.typeList"
          @change="queryChangeFn"
          multiple
          clearable
          collapse-tags>
          <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"
          unlink-panels
          :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.prdList.length > 0 && queryParams.typeList.length > 0 && !loading">
        <template v-if="showType === 'charts'">
          <group-legend :legendData="chartData.legend"
            @click-item="legendChangeFn"></group-legend>
          <gradient-area :chartData="chartData"
            @changeType="changeType"></gradient-area>
        </template>
        <template v-else-if="showType === 'table'">
          <table-list :column="queryParams.typeList"
            :data="tableList"
            @changeType="changeType"
            @queryTable="getList"
            @dateMergeFn="dateMergeFn"></table-list>
        </template>
      </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 GradientArea from './GradientArea.vue';
import TableList from './TableList.vue';
import { getComPrdListAPI, getSycmListAPI } from '@/api'
import { generatorDayList, parseTime, getAdditionalColor, resetObjValue } from '@/utils'
import { useDatePickerOptions } from '@/hooks'

// 静态数据
const dateList = [new Date().setDate((new Date().getDate() - 30)), new Date().setDate((new Date().getDate() - 1))] // 最近 30 日日期数组
const dataTypeList = ['支付买家数', '交易增速', '独立访客范围', '流量增速'] // 数据类型

// 本页数据
const loading = ref(true)
const prdList = ref([]) // 商品列表
const typeList = ref(dataTypeList) // 数据类型
const { pickerOptions } = useDatePickerOptions()
const showType = ref('charts') // 展示类型（'charts' / 'table')
const dateMerge = ref(false) // 表格中日期是否合并

const queryParams = reactive({ // 查询表单
  prdList: [],
  typeList: [typeList.value[0]],
  date: dateList
})

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

const allTableList = ref([])
const tableList = ref([])


// 获取竞品列表
const getPrdList = async () => {
  const { data } = await getComPrdListAPI()
  prdList.value = data
  // 初始化筛选条件（默认请求第一个店铺的第一类型数据）
  queryParams.prdList = [data[0]?.prdId]
}

// 初始化图表数据
const initChartsData = (data) => {
  resetObjValue(allChartData)
  allChartData.xAxis = generatorDayList(queryParams.date[0], queryParams.date[1])
  // 图表数据
  data.forEach((list, index) => {
    index = index * 4
    // list: 每个商品数据集合
    // 公共的配置
    let commonObj = {
      type: 'line',
      // stack: 'Total',
      smooth: true,
      // stackStrategy: 'all',
      lineStyle: {
        width: 0
      },
      showSymbol: false,
      emphasis: {
        focus: 'series'
      }
    }
    let jyzsObj = {
      ...commonObj,
      itemStyle: {
        color: getAdditionalColor(index)
      },
      areaStyle: {
        opacity: 0.8,
        color: getAdditionalColor(index)
      },
      name: list[0]?.platformStore + '-交易增速',
      data: []
    }
    let llzsObj = {
      ...commonObj,
      itemStyle: {
        color: getAdditionalColor(index + 1)
      },
      areaStyle: {
        opacity: 0.8,
        color: getAdditionalColor(index + 1)
      },
      name: list[0]?.platformStore + '-流量增速',
      data: [],
    }
    let uvObj = {
      ...commonObj,
      itemStyle: {
        color: getAdditionalColor(index + 2)
      },
      areaStyle: {
        opacity: 0.8,
        color: getAdditionalColor(index + 2)
      },
      name: list[0]?.platformStore + '-独立访客范围',
      data: []
    }
    let zfmjObj = {
      ...commonObj,
      itemStyle: {
        color: getAdditionalColor(index + 3)
      },
      areaStyle: {
        opacity: 0.8,
        color: getAdditionalColor(index + 3)
      },
      name: list[0]?.platformStore + '-支付买家数',
      data: []
    }
    // list: 循环每一天的数据
    // 按照日期添加数据
    allChartData.xAxis.forEach(date => {
      const findObj = list.find(o => o.date.includes(date))
      if (findObj) {
        jyzsObj.data.push((findObj.jyzsPeak + findObj.jyzsUnder) / 2)
        llzsObj.data.push((findObj.llzsPeak + findObj.llzsUnder) / 2)
        uvObj.data.push((findObj.uvPeak + findObj.uvUnder) / 2)
        zfmjObj.data.push((findObj.zfmjPeak + findObj.zfmjUnder) / 2)
      } else {
        jyzsObj.data.push(0)
        llzsObj.data.push(0)
        uvObj.data.push(0)
        zfmjObj.data.push(0)
      }
    })

    allChartData.legend.push({
      data: [{
        name: jyzsObj.name,
        type: 'circle',
        color: getAdditionalColor(index),
        effective: true,
        show: true,
      }, {
        name: llzsObj.name,
        type: 'circle',
        color: getAdditionalColor(index + 1),
        effective: true,
        show: true
      }, {
        name: uvObj.name,
        type: 'circle',
        color: getAdditionalColor(index + 2),
        effective: true,
        show: true
      }, {
        name: zfmjObj.name,
        type: 'circle',
        color: getAdditionalColor(index + 3),
        effective: true,
        show: true
      }],
      orient: 'verticalAlign'
    })
    allChartData.series.push(jyzsObj, llzsObj, uvObj, zfmjObj)
  })
}
// 初始化表格数据
const initTableData = (data) => {
  // 表格数据
  allTableList.value = data
}

// 筛选图表数据
const filterChartsData = () => {
  let legend = allChartData.legend
  let series = allChartData.series

  // 选择了数据类型，筛选
  if (queryParams.typeList.length > 0) {
    series = series.filter(item => {
      return queryParams.typeList.find(o => o === item.name.split('-')[1])
    })
    // // 图例组件数据源不变，只是显示/隐藏
    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 filterTableData = () => {
  // 没有日期合并
  if (dateMerge.value) {
    tableList.value = allTableList.value.map(o => {
      const platformStore = o[0].platformStore
      const zfmj = (o.reduce((sum, obj) => {
        return sum += ((obj.zfmjPeak + obj.zfmjUnder) / 2)
      }, 0) / o.length).toFixed(2)
      const jyzs = (o.reduce((sum, obj) => {
        return sum += ((obj.jyzsPeak + obj.jyzsUnder) / 2)
      }, 0) / o.length).toFixed(2)
      const uv = (o.reduce((sum, obj) => {
        return sum += ((obj.uvPeak + obj.uvUnder) / 2)
      }, 0) / o.length).toFixed(2)
      const llzs = (o.reduce((sum, obj) => {
        return sum += ((obj.llzsPeak + obj.llzsUnder) / 2)
      }, 0) / o.length).toFixed(2)
      return {
        platformStore, zfmj, jyzs, uv, llzs
      }
    })

  } else {
    tableList.value = allTableList.value.flat().map(o => {
      return {
        ...o,
        zfmj: (o.zfmjPeak + o.zfmjUnder) / 2,
        jyzs: (o.jyzsPeak + o.jyzsUnder) / 2,
        uv: (o.uvPeak + o.uvUnder) / 2,
        llzs: (o.llzsPeak + o.llzsUnder) / 2,
      }
    })
  }

}

// 获取数据
const getList = async () => {
  loading.value = true
  const { data } = await getSycmListAPI({
    startDate: parseTime(queryParams.date[0], '{y}-{m}-{d}'),
    endDate: parseTime(queryParams.date[1], '{y}-{m}-{d}'),
    prdId: queryParams.prdList.join(','),
    dataType: queryParams.typeList.join(',')
  })

  if (showType.value === 'charts') {
    initChartsData(data)
    filterChartsData()
  }
  else if (showType.value === 'table') {
    initTableData(data)
    filterTableData()
  }

  loading.value = false
  return data
}

// 表格数据合并
const dateMergeFn = () => {
  dateMerge.value = !dateMerge.value
  filterTableData()
}

// 默认打开页面请求一次所有数据，并保存在数据源
async function init() {
  await getPrdList()
  await getList()
};

onMounted(() => {
  init()
})

// 图例点击直接过滤数据
const legendChangeFn = () => {
  filterChartsData()
}

// 图表/表格类型切换
const changeType = (val) => {
  showType.value = val
  getList()
}

// 查询条件改变
const queryChangeFn = async (arg) => {
  getList()
}

// 重置
const reset = async () => {
  // 重置查询参数
  loading.value = true
  queryParams.brandList = []
  queryParams.date = dateList
  queryParams.typeList = [dataTypeList[0]]
  init()
}
</script>

<style scoped
  lang="scss">
  .prd-select {
    width: 550px;
  }
</style>