<template>
  <div class="tracking-charts">
    <el-row :gutter="20" style="margin-bottom: 20px">
      <el-col :span="4">
        <el-card shadow="never">
          <div style="font-size: 14px; color: #909399">当前上报总数</div>
          <div style="font-size: 24px; font-weight: bold; color: #303133; margin-top: 5px">{{ list.length }}</div>
        </el-card>
      </el-col>
      <el-col :span="4">
        <el-card shadow="never">
          <div style="font-size: 14px; color: #909399">用户数</div>
          <div style="font-size: 24px; font-weight: bold; color: #303133; margin-top: 5px">{{ userOptions.length }}</div>
        </el-card>
      </el-col>
    </el-row>

    <el-card class="filter-card" shadow="never">
      <el-form :inline="true" :model="queryForm" size="small" @submit.native.prevent>
        <el-form-item label="App">
          <el-select v-model="queryForm.appId" filterable>
            <el-option v-for="(label, value) in appMap" :key="value" :label="label" :value="value">
              <span style="float: left">{{ label }}</span>
              <span style="float: right; color: #8492a6; font-size: 13px">{{ value }}</span>
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="User ID">
          <el-select v-model="queryForm.userId" allow-create clearable default-first-option filterable placeholder="请输入或选择User ID">
            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value">
              <span style="float: left">{{ item.label }}</span>
              <span v-if="item.value !== item.label" style="float: right; color: #8492a6; font-size: 13px; margin-left: 20px">
                {{ item.value }}
              </span>
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="事件名称">
          <el-select v-model="queryForm.eventName" clearable filterable placeholder="全部事件">
            <el-option v-for="(label, value) in eventNameMap" :key="value" :label="label" :value="value">
              <span style="float: left">{{ label }}</span>
              <span style="float: right; color: #8492a6; font-size: 13px">{{ value }}</span>
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="事件类型">
          <el-select v-model="queryForm.eventType" clearable placeholder="全部类型">
            <el-option v-for="(label, value) in eventTypeMap" :key="value" :label="label" :value="value" />
          </el-select>
        </el-form-item>
        <el-form-item label="时间范围">
          <el-date-picker
            v-model="queryForm.dateRange"
            :default-time="['00:00:00', '23:59:59']"
            end-placeholder="结束日期"
            :picker-options="pickerOptions"
            range-separator="至"
            start-placeholder="开始日期"
            type="datetimerange"
            value-format="yyyy-MM-dd HH:mm:ss"
          />
        </el-form-item>
        <el-form-item>
          <el-button icon="el-icon-search" type="primary" @click="handleQuery">查询</el-button>
          <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <div v-loading="loading" class="charts-container">
      <el-row :gutter="20">
        <el-col :span="24">
          <el-card class="chart-card" shadow="never">
            <div slot="header"><span>时段趋势</span></div>
            <v-chart autoresize class="chart" :option="trendOption" />
          </el-card>
        </el-col>
      </el-row>

      <el-row :gutter="20" style="margin-top: 20px">
        <el-col :span="12">
          <el-card class="chart-card" shadow="never">
            <div slot="header"><span>事件名称分布</span></div>
            <v-chart autoresize class="chart" :option="eventNameOption" @click="handleEventNameClick" />
          </el-card>
        </el-col>
        <el-col :span="12">
          <el-card class="chart-card" shadow="never">
            <div slot="header"><span>事件类型分布</span></div>
            <v-chart autoresize class="chart" :option="eventTypeOption" @click="handleEventTypeClick" />
          </el-card>
        </el-col>
      </el-row>

      <el-row :gutter="20" style="margin-top: 20px">
        <el-col :span="24">
          <el-card class="chart-card" shadow="never">
            <div slot="header"><span>页面访问排行</span></div>
            <v-chart autoresize class="chart" :option="pageOption" />
          </el-card>
        </el-col>
      </el-row>

      <el-row :gutter="20" style="margin-top: 20px">
        <el-col :span="24">
          <el-card shadow="never">
            <div slot="header" style="display: flex; justify-content: space-between; align-items: center">
              <span>
                详细日志列表
                <span v-if="filterText" style="font-size: 12px; color: #666">({{ filterText }})</span>
              </span>
              <el-button v-if="isFiltered" size="mini" type="text" @click="clearFilter">清除筛选</el-button>
            </div>
            <el-table :data="paginatedList" style="width: 100%">
              <el-table-column label="时间" prop="createdAt" width="160">
                <template slot-scope="{ row }">
                  {{ formatTime(row.createdAt) }}
                </template>
              </el-table-column>
              <el-table-column label="事件名称" prop="eventName" show-overflow-tooltip>
                <template slot-scope="{ row }">
                  {{ eventNameMap[row.eventName] || row.eventName }}
                </template>
              </el-table-column>
              <el-table-column label="事件类型" prop="eventType" show-overflow-tooltip>
                <template slot-scope="{ row }">
                  {{ eventTypeMap[row.eventType] || row.eventType }}
                </template>
              </el-table-column>
              <el-table-column label="页面" prop="page" show-overflow-tooltip />
              <el-table-column label="元素ID" prop="elementId" show-overflow-tooltip />
              <el-table-column label="访问地址" prop="address" show-overflow-tooltip />
              <el-table-column label="元素内容" prop="elementContent" show-overflow-tooltip />
              <el-table-column label="User ID" prop="userId" show-overflow-tooltip>
                <template slot-scope="{ row }">
                  <el-link type="primary" :underline="false" @click="goToUser(row.userId)">{{ row.userId }}</el-link>
                </template>
              </el-table-column>
            </el-table>
            <el-pagination
              background
              :current-page="currentPage"
              layout="total, sizes, prev, pager, next, jumper"
              :page-size="pageSize"
              :page-sizes="[10, 20, 50, 100]"
              style="margin-top: 20px; text-align: right"
              :total="total"
              @current-change="handleCurrentChange"
              @size-change="handleSizeChange"
            />
          </el-card>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script>
  import { getTrackingLogsList } from '@/api/system'
  import { use } from 'echarts/core'
  import { CanvasRenderer } from 'echarts/renderers'
  import { LineChart, PieChart, BarChart } from 'echarts/charts'
  import { GridComponent, TooltipComponent, LegendComponent, TitleComponent } from 'echarts/components'
  import VChart from 'vue-echarts'
  import dayjs from 'dayjs'
  import { groupBy, countBy } from 'lodash'
  import { eventNameMap, eventTypeMap, appMap, userMap } from '../utils'

  use([CanvasRenderer, LineChart, PieChart, BarChart, GridComponent, TooltipComponent, LegendComponent, TitleComponent])

  export default {
    name: 'TrackingCharts',
    components: {
      VChart,
    },
    data() {
      return {
        eventNameMap,
        eventTypeMap,
        appMap,
        userMap,
        loading: false,
        queryForm: {
          appId: '69665538a49b8ae3be50fe5d',
          userId: '',
          eventName: '',
          eventType: '',
          dateRange: [],
        },
        userOptions: [],
        pickerOptions: {
          shortcuts: [
            {
              text: '今天',
              onClick(picker) {
                const end = new Date()
                const start = new Date()
                start.setHours(0, 0, 0, 0)
                end.setHours(23, 59, 59, 999)
                picker.$emit('pick', [start, end])
              },
            },
            {
              text: '昨天',
              onClick(picker) {
                const end = new Date()
                const start = new Date()
                start.setTime(start.getTime() - 3600 * 1000 * 24)
                start.setHours(0, 0, 0, 0)
                end.setTime(end.getTime() - 3600 * 1000 * 24)
                end.setHours(23, 59, 59, 999)
                picker.$emit('pick', [start, end])
              },
            },
            {
              text: '最近一周',
              onClick(picker) {
                const end = new Date()
                const start = new Date()
                start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
                picker.$emit('pick', [start, end])
              },
            },
          ],
        },
        list: [],
        filteredList: [],
        currentPage: 1,
        pageSize: 10,
        isFiltered: false,
        filterText: '',
        trendOption: {},
        eventNameOption: {},
        eventTypeOption: {},
        pageOption: {},
      }
    },
    computed: {
      total() {
        return this.filteredList.length
      },
      paginatedList() {
        const start = (this.currentPage - 1) * this.pageSize
        const end = start + this.pageSize
        return this.filteredList.slice(start, end)
      },
    },
    created() {
      // 默认选中今天
      const end = new Date()
      const start = new Date()
      start.setHours(0, 0, 0, 0)
      end.setHours(23, 59, 59, 999)
      this.queryForm.dateRange = [dayjs(start).format('YYYY-MM-DD HH:mm:ss'), dayjs(end).format('YYYY-MM-DD HH:mm:ss')]

      this.fetchData()
    },
    methods: {
      formatTime(time) {
        return dayjs(time).format('YYYY-MM-DD HH:mm:ss')
      },
      async fetchData() {
        this.loading = true
        try {
          const params = {
            appId: this.queryForm.appId,
            userId: this.queryForm.userId || undefined,
            eventName: this.queryForm.eventName || undefined,
            eventType: this.queryForm.eventType || undefined,
            startTime: this.queryForm.dateRange ? this.queryForm.dateRange[0] : undefined,
            endTime: this.queryForm.dateRange ? this.queryForm.dateRange[1] : undefined,
            pageNo: 1,
            pageSize: 10000, // 获取足够多的数据进行前端统计，或者应该依赖后端聚合接口
          }

          const { data } = await getTrackingLogsList(params)
          this.list = data.list || []

          // 如果没有筛选用户，则更新用户选项列表
          if (!this.queryForm.userId) {
            const userIds = this.list.map((item) => item.userId).filter(Boolean)
            const uniqueUsers = [...new Set(userIds)]
            this.userOptions = uniqueUsers.map((id) => ({ value: id, label: this.userMap[id] || id }))
          }

          this.filteredList = [...this.list]
          this.isFiltered = false
          this.filterText = ''
          this.currentPage = 1
          this.processData()
        } catch (error) {
          console.error(error)
          this.$baseMessage('获取数据失败', 'error')
        } finally {
          this.loading = false
        }
      },
      handleQuery() {
        this.fetchData()
      },
      resetQuery() {
        this.queryForm.appId = '69665538a49b8ae3be50fe5d'
        this.queryForm.userId = ''
        this.queryForm.eventName = ''
        this.queryForm.eventType = ''
        const end = new Date()
        const start = new Date()
        start.setHours(0, 0, 0, 0)
        end.setHours(23, 59, 59, 999)
        this.queryForm.dateRange = [dayjs(start).format('YYYY-MM-DD HH:mm:ss'), dayjs(end).format('YYYY-MM-DD HH:mm:ss')]
        this.fetchData()
      },
      handleSizeChange(val) {
        this.pageSize = val
        this.currentPage = 1
      },
      handleCurrentChange(val) {
        this.currentPage = val
      },
      clearFilter() {
        this.filteredList = [...this.list]
        this.isFiltered = false
        this.filterText = ''
        this.currentPage = 1
      },
      goToUser(userId) {
        if (!userId) return
        this.$router.push({
          path: '/spring/user/user',
          query: { userId },
        })
      },
      handleEventNameClick(params) {
        const name = params.name
        // name 可能是中文映射名，需要反向查找 key，或者在 processData 时把 key 存入
        // 简单起见，processData 中 name 已经是中文名或者 key 了。
        // 如果我们用中文名展示，过滤时比较麻烦。
        // 最好在 processData 中让 echarts data item 包含原始 key。

        // 重新检查 processData
        // const eventNameData = Object.keys(eventNameCounts).map((key) => ({
        //   name: this.eventNameMap[key] || key,
        //   value: eventNameCounts[key],
        //   key: key // 添加原始 key
        // }))

        const key = params.data.key || params.name // 如果没有 key 属性，回退到 name
        this.filteredList = this.list.filter((item) => {
          const itemKey = item.eventName
          const itemName = this.eventNameMap[itemKey] || itemKey
          // 如果 params.data.key 存在，则精确匹配 key
          if (params.data.key) {
            return item.eventName === params.data.key
          }
          return itemName === name
        })
        this.isFiltered = true
        this.filterText = `筛选事件: ${name}`
        this.currentPage = 1
      },
      handleEventTypeClick(params) {
        const name = params.name
        const key = params.data.key || params.name
        this.filteredList = this.list.filter((item) => {
          if (params.data.key) {
            return item.eventType === params.data.key
          }
          const itemKey = item.eventType
          const itemName = this.eventTypeMap[itemKey] || itemKey
          return itemName === name
        })
        this.isFiltered = true
        this.filterText = `筛选类型: ${name}`
        this.currentPage = 1
      },
      processData() {
        // 1. 时段趋势
        const logsByHour = groupBy(this.list, (item) => dayjs(item.createdAt).format('HH:00'))
        const hours = []
        const counts = []
        for (let i = 0; i < 24; i++) {
          const hour = `${String(i).padStart(2, '0')}:00`
          hours.push(hour)
          counts.push(logsByHour[hour] ? logsByHour[hour].length : 0)
        }
        this.trendOption = {
          tooltip: {
            trigger: 'axis',
          },
          xAxis: {
            type: 'category',
            data: hours,
          },
          yAxis: {
            type: 'value',
          },
          series: [
            {
              data: counts,
              type: 'line',
              smooth: true,
              areaStyle: {},
            },
          ],
        }

        // 2. 事件名称分布
        const eventNameCounts = countBy(this.list, 'eventName')
        const eventNameData = Object.keys(eventNameCounts).map((key) => ({
          name: this.eventNameMap[key] || key,
          value: eventNameCounts[key],
          key: key, // 保存原始key
        }))
        this.eventNameOption = {
          tooltip: {
            trigger: 'item',
            formatter: '{b}: {c} ({d}%)',
          },
          legend: {
            orient: 'vertical',
            left: 'left',
          },
          series: [
            {
              name: '事件名称',
              type: 'pie',
              radius: '50%',
              data: eventNameData,
              emphasis: {
                itemStyle: {
                  shadowBlur: 10,
                  shadowOffsetX: 0,
                  shadowColor: 'rgba(0, 0, 0, 0.5)',
                },
              },
            },
          ],
        }

        // 3. 事件类型分布
        const eventTypeCounts = countBy(this.list, 'eventType')
        const eventTypeData = Object.keys(eventTypeCounts).map((key) => ({
          name: this.eventTypeMap[key] || key,
          value: eventTypeCounts[key],
          key: key, // 保存原始key
        }))
        this.eventTypeOption = {
          tooltip: {
            trigger: 'item',
            formatter: '{b}: {c} ({d}%)',
          },
          legend: {
            orient: 'vertical',
            left: 'left',
          },
          series: [
            {
              name: '事件类型',
              type: 'pie',
              radius: '50%',
              data: eventTypeData,
              emphasis: {
                itemStyle: {
                  shadowBlur: 10,
                  shadowOffsetX: 0,
                  shadowColor: 'rgba(0, 0, 0, 0.5)',
                },
              },
            },
          ],
        }

        // 4. 页面访问排行
        const pageCounts = countBy(this.list, 'page')
        // 排序并取前10
        const sortedPages = Object.keys(pageCounts)
          .sort((a, b) => pageCounts[b] - pageCounts[a])
          .slice(0, 10)
        const pageData = sortedPages.map((key) => pageCounts[key])

        this.pageOption = {
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              type: 'shadow',
            },
          },
          grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true,
          },
          xAxis: {
            type: 'value',
            boundaryGap: [0, 0.01],
          },
          yAxis: {
            type: 'category',
            data: sortedPages,
          },
          series: [
            {
              name: '访问次数',
              type: 'bar',
              data: pageData,
            },
          ],
        }
      },
    },
  }
</script>

<style scoped>
  .tracking-charts {
    padding: 20px;
  }
  .filter-card {
    margin-bottom: 20px;
  }
  .chart-card {
    height: 400px;
  }
  .chart {
    height: 300px;
  }
</style>
