﻿<template>
  <div class="page-container-flex log-view">
    <van-nav-bar 
      title="查看日志" 
      left-text="返回"
      left-arrow
      placeholder 
      @click-left="handleBack"
    />

    <div class="scroll-content">
      <!-- 搜索和筛选 -->
      <div class="filter-section">
        <van-search
          v-model="searchKeyword"
          placeholder="输入关键词筛选日志"
          @search="handleSearch"
          @clear="handleClear"
        />
        
        <div class="filter-row">
          <van-dropdown-menu>
            <van-dropdown-item v-model="selectedLevel" :options="levelOptions" @change="handleSearch" />
            <van-dropdown-item v-model="selectedDate" :options="dateOptions" @change="handleSearch" />
          </van-dropdown-menu>
        </div>
      </div>

      <!-- 下拉刷新区域 -->
      <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
        <!-- 加载提示 -->
        <van-loading v-if="loading && !logList.length" vertical style="padding: 50px 0">
          加载中...
        </van-loading>

        <!-- 日志列表 -->
        <van-list
          v-model:loading="loading"
          :finished="finished"
          finished-text="没有更多了"
          class="log-list"
          @load="onLoad"
        >
          <div 
            v-for="(log, index) in logList" 
            :key="index"
            class="log-item"
            :class="getLevelClass(log.level)"
          >
            <div class="log-header">
              <span class="log-level">{{ log.level }}</span>
              <span class="log-time">{{ formatTime(log.timestamp) }}</span>
            </div>
            <div class="log-message">{{ log.message }}</div>
          </div>

          <!-- 空状态 -->
          <van-empty 
            v-if="!loading && !logList.length" 
            description="暂无日志"
            image="search"
          />
        </van-list>

        <!-- 底部安全距离 -->
        <div style="height: 20px"></div>
      </van-pull-refresh>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { showToast } from 'vant'
import { getLogList, getAvailableDates } from '@/api/log'

const router = useRouter()

// 数据状态
const logList = ref([])
const loading = ref(false)
const finished = ref(false)
const refreshing = ref(false)
const fetching = ref(false)

// 分页参数
const pageIndex = ref(1)
const pageSize = ref(100)
const total = ref(0)

// 筛选参数
const searchKeyword = ref('')
const selectedLevel = ref('')
const selectedDate = ref('')

// 日志级别选项
const levelOptions = ref([
  { text: '全部级别', value: '' },
  { text: 'VRB', value: 'VRB' },
  { text: 'DBG', value: 'DBG' },
  { text: 'INF', value: 'INF' },
  { text: 'WRN', value: 'WRN' },
  { text: 'ERR', value: 'ERR' },
  { text: 'FTL', value: 'FTL' }
])

// 日期选项
const dateOptions = ref([
  { text: '全部日期', value: '' }
])

/**
 * 返回上一页
 */
const handleBack = () => {
  router.back()
}

/**
 * 获取日志级别对应的样式类
 */
const getLevelClass = (level) => {
  const levelMap = {
    'ERR': 'level-error',
    'FTL': 'level-fatal',
    'WRN': 'level-warning',
    'INF': 'level-info',
    'DBG': 'level-debug',
    'VRB': 'level-verbose'
  }
  return levelMap[level] || 'level-default'
}

/**
 * 格式化时间显示
 */
const formatTime = (timestamp) => {
  // 提取时间部分，去掉时区
  const match = timestamp.match(/(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\.\d{3})/)
  return match ? match[1] : timestamp
}

/**
 * 加载日志数据
 */
const loadLogs = async (reset = false) => {
  if (fetching.value) return

  fetching.value = true

  try {
    if (reset) {
      pageIndex.value = 1
      logList.value = []
      finished.value = false
    }

    const params = {
      pageIndex: pageIndex.value,
      pageSize: pageSize.value
    }

    if (searchKeyword.value) {
      params.searchKeyword = searchKeyword.value
    }
    if (selectedLevel.value) {
      params.logLevel = selectedLevel.value
    }
    if (selectedDate.value) {
      params.date = selectedDate.value
    }

    const response = await getLogList(params)

    if (response.success) {
      const newLogs = response.data || []
      
      if (reset) {
        logList.value = newLogs
      } else {
        logList.value = [...logList.value, ...newLogs]
      }

      total.value = response.total

      // 判断是否还有更多数据
      // total = -1 表示总数未知，此时只根据返回数据量判断
      if (total.value === -1) {
        // 如果返回的数据少于请求的数量，说明没有更多了
        finished.value = newLogs.length < pageSize.value
      } else {
        // 如果有明确的总数，则判断是否已加载完全部数据
        if (logList.value.length >= total.value || newLogs.length < pageSize.value) {
          finished.value = true
        } else {
          finished.value = false
        }
      }
    } else {
      showToast(response.message || '获取日志失败')
      finished.value = true
    }
  } catch (error) {
    console.error('加载日志失败:', error)
    showToast('加载日志失败')
    finished.value = true
  } finally {
    fetching.value = false
    loading.value = false
    refreshing.value = false
  }
}

/**
 * 下拉刷新
 */
const onRefresh = async () => {
  await loadLogs(true)
}

/**
 * 加载更多
 */
const onLoad = async () => {
  if (finished.value || fetching.value) return
  
  // 如果是第一次加载
  if (pageIndex.value === 1 && logList.value.length === 0) {
    await loadLogs(false)
  } else {
    // 后续分页加载
    pageIndex.value++
    await loadLogs(false)
  }
}

/**
 * 搜索处理
 */
const handleSearch = () => {
  loadLogs(true)
}

/**
 * 清空搜索
 */
const handleClear = () => {
  searchKeyword.value = ''
  handleSearch()
}

/**
 * 加载可用日期列表
 */
const loadAvailableDates = async () => {
  try {
    const response = await getAvailableDates()
    if (response.success && response.data) {
      const dates = response.data.map(date => ({
        text: formatDate(date),
        value: date
      }))
      dateOptions.value = [
        { text: '全部日期', value: '' },
        ...dates
      ]
    }
  } catch (error) {
    console.error('加载日期列表失败:', error)
  }
}

/**
 * 格式化日期显示
 */
const formatDate = (dateStr) => {
  // dateStr 格式: 20251229
  if (dateStr.length === 8) {
    return `${dateStr.substring(0, 4)}-${dateStr.substring(4, 6)}-${dateStr.substring(6, 8)}`
  }
  return dateStr
}

// 组件挂载时加载数据
onMounted(() => {
  loadAvailableDates()
  // 不在这里调用 loadLogs，让 van-list 的 @load 事件自动触发
})
</script>

<style scoped>
.log-view {
  height: 100vh;
  background-color: #f5f5f5;
}

@media (prefers-color-scheme: dark) {
  .log-view {
    background-color: #1a1a1a;
  }
}

.filter-section {
  background-color: #ffffff;
  position: sticky;
  top: 0;
  z-index: 10;
}

@media (prefers-color-scheme: dark) {
  .filter-section {
    background-color: #2c2c2c;
  }
}

.filter-row {
  padding: 0;
}

.log-list {
  padding: 4px 12px;
}

.log-item {
  background-color: #ffffff;
  border-left: 3px solid #1989fa;
  margin-bottom: 4px;
  padding: 6px 10px;
  border-radius: 3px;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 12px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
  transition: all 0.2s;
}

.log-item:hover {
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

@media (prefers-color-scheme: dark) {
  .log-item {
    background-color: #2c2c2c;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  }

  .log-item:hover {
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
  }
}

.log-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 4px;
  font-size: 11px;
}

.log-level {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 2px;
  font-weight: bold;
  color: #ffffff;
  min-width: 36px;
  text-align: center;
  font-size: 10px;
}

.log-time {
  color: #969799;
  font-size: 10px;
}

@media (prefers-color-scheme: dark) {
  .log-time {
    color: #858585;
  }
}

.log-message {
  color: #323233;
  line-height: 1.4;
  word-break: break-word;
  white-space: pre-wrap;
}

@media (prefers-color-scheme: dark) {
  .log-message {
    color: #e0e0e0;
  }
}

/* 不同日志级别的颜色 */
.level-verbose .log-level {
  background-color: #b0b0b0;
}

.level-debug .log-level {
  background-color: #1989fa;
}

.level-info .log-level {
  background-color: #07c160;
}

.level-warning .log-level {
  background-color: #ff976a;
  border-left-color: #ff976a;
}

.level-error .log-level {
  background-color: #ee0a24;
}

.level-fatal .log-level {
  background-color: #8b0000;
}

.level-default .log-level {
  background-color: #646566;
}

.level-verbose {
  border-left-color: #b0b0b0;
}

.level-debug {
  border-left-color: #1989fa;
}

.level-info {
  border-left-color: #07c160;
}

.level-warning {
  border-left-color: #ff976a;
}

.level-error {
  border-left-color: #ee0a24;
}

.level-fatal {
  border-left-color: #8b0000;
}

.level-default {
  border-left-color: #646566;
}

/* 优化下拉菜单样式 */
:deep(.van-dropdown-menu) {
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}

@media (prefers-color-scheme: dark) {
  :deep(.van-dropdown-menu) {
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
  }
}
</style>
