<template>
  <div class="dataCard">
    <div class="titleStyle">错误日志统计</div>
    <div class="chart-container" ref="chartRef"></div>
    <el-dialog draggable v-model="DialogVisible" :title="`错误详情丨${curDate}`" @close="tableData = []">
      <div class="table-content">
        <el-table :data="curTableData" border style="width: 100%">
          <el-table-column width="55" label="序号" type="index" />
          <el-table-column width="150" property="spider" label="爬虫名称" />
          <el-table-column property="error" label="错误信息">
            <template #default="scope">
              {{ scope.row.error.error }}
            </template>
          </el-table-column>
          <el-table-column width="160" property="timestamp" label="记录时间" />
        </el-table>
        <div class="pagination w-full flex flex-row-reverse pr-4 m-t-4">
          <Pagination
            :total="pageObj.total"
            v-model:page="pageObj.pageNo"
            v-model:limit="pageObj.pageSize"
            @pagination="getData"
            v-model:pagerCount="pageObj.pagerCount"
          />
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { computed, reactive, ref, useTemplateRef } from "vue";
import { getErrorLogsList } from "@/api/log";
import { useChart } from "@/hooks/useChart";
import { ElMessage } from "element-plus";
import Pagination from "@/components/pagination/index.vue";

const chartRef = useTemplateRef<HTMLElement | null>("chartRef");

//详情弹窗状态
const DialogVisible = ref(false);

const pageObj = ref({
  total: 0,
  pageNo: 1,
  pageSize: 5,
  pagerCount: 5,
});

//弹窗表格数据
const tableData = ref<any[]>([]);

const curTableData = ref<any[]>([]);

//数据项定义
interface LogItem {
  date: string;
  count: number;
}

//原始数据
const rawLogList = ref<any[]>([]);

//日志列表
const logList = ref<LogItem[]>([]);

//日志数
const logCountList = computed(() => {
  return logList.value.map((item) => item.count);
});

//X轴日期列表
const dateList = ref<string[]>([]);

//Y轴最大值
const maxVal = computed(() => {
  let val = logList.value[0]?.count * 1.5;
  logList.value.forEach((item) => {
    if (item.count > val) {
      val = item.count * 1.5;
    }
  });
  return val;
});

//当前打开的详情日期
const curDate = ref("");

const getData = () => {
  curTableData.value = tableData.value.slice(
    (pageObj.value.pageNo - 1) * pageObj.value.pageSize,
    pageObj.value.pageNo * pageObj.value.pageSize
  );
};

//设置图表数据
const setChartData = async () => {
  try {
    const res = await getErrorLogsList();
    if (res.code === 0) {
      rawLogList.value = res.data.list;
      //提取日期列表
      res.data.list.forEach((item: any) => {
        const date = item.timestamp.split(" ")[0];
        if (dateList.value.includes(date)) {
          //如果该日期日志项存在，则进行+1操作
          logList.value.forEach((item) => {
            if (item.date === date) {
              item.count++;
            }
          });
        } else {
          //如果该日期日志项不存在，则初始化到数组中
          logList.value.push({ date, count: 1 });
          dateList.value.push(date);
        }
      });
    } else {
      ElMessage.error(res.message);
    }
  } catch (error: any) {
    ElMessage(error);
  }

  //初始化图表配置项
  const chartOptions = reactive({
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "shadow",
      },
    },
    grid: {
      left: "3%",
      right: "4%",
      bottom: "3%",
      containLabel: true,
    },
    xAxis: [
      {
        type: "category",
        data: dateList.value,
        name: "日期",
        nameLocation: "middle",
        nameGap: 20,
        nameTextStyle: {
          color: "#fff",
          fontSize: 12,
        },
        axisTick: {
          alignWithLabel: true,
        },
        axisLabel: {
          color: "#fff",
        },
      },
    ],
    yAxis: [
      {
        type: "value",
        name: "数量",
        nameLocation: "middle",
        nameGap: 20,
        max: maxVal.value,
        axisLabel: {
          color: "#fff",
        },
        nameTextStyle: {
          color: "#fff",
          fontSize: 12,
        },
      },
    ],
    series: [
      {
        name: "日志数量",
        type: "bar",
        barWidth: "60%",
        data: logCountList.value,
        itemStyle: {
          color: "#409EE4",
        },
      },
    ],
  });

  return chartOptions;
};

//处理用户点击柱状图事件
const handleClickChart = (params: any) => {
  DialogVisible.value = true;
  curDate.value = params.name;
  rawLogList.value.forEach((item) => {
    if (item.timestamp.split(" ")[0] === params.name) {
      tableData.value.push(item);
    }
  });
  pageObj.value.total = tableData.value.length;
  curTableData.value = tableData.value.slice(0, 5);
  console.log(curTableData.value);
};

//生成图表
useChart(chartRef, setChartData, handleClickChart);
</script>

<style scoped lang="scss">
.dataCard {
  background-image: url("@/assets/picture/box2.png");
  background-size: 100% 100%;
  background-repeat: no-repeat;
  // background: #c6ebfc;
  // border: 1.5px solid rgb(193, 188, 188);
  border-radius: 5px;
  height: 100%;
  padding: 35px;
  box-sizing: border-box;
}

/* 标题区 */
.titleStyle {
  color: #dff6ff;
  font-size: 18px;
  font-weight: 600;
  text-align: center;
  text-shadow: 0 0 8px rgba(100, 200, 255, 0.8);
  letter-spacing: 2px;
}

.chart-container {
  margin-top: 20px;
  width: 100%;
  height: 600px;
}

.cotnent {
  padding: 10px;
  display: flex;
}

.table-content {
  padding: 10px;
  margin-top: 30px;
  background: rgba(255, 255, 255, 0.03);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(78, 237, 255, 0.2);
  box-shadow: 0 0 15px rgba(78, 237, 255, 0.1);
  border-radius: 8px;
  padding: 15px;
}
</style>
