<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import PageCard from '@/components/PageCard.vue'
import { useCountdown } from '@/composables/useCountdown'
import { usePolling } from '@/composables/usePolling'
import {
  getLogFiles,
  getLogContent,
  getTrainingLogFiles,
  getTrainingLogContent,
} from '@/api/modules/log'
import type { LogFile } from '@/types'

const activeTab = ref<'system' | 'training'>('system')

// 系统日志
const sysDate = ref(new Date().toISOString().split('T')[0])
const sysFiles = ref<LogFile[]>([])
const sysSelected = ref('')
const sysContent = ref('')

// 训练日志
const trainFiles = ref<LogFile[]>([])
const trainSelected = ref('')
const trainContent = ref('')

// 搜索
const keyword = ref('')
const fullContent = ref('')

// 自动刷新
const refreshInterval = ref(10)
const { remaining, start: startCountdown, stop: stopCountdown } = useCountdown(10)

const filteredLog = computed(() => {
  if (!keyword.value.trim()) return { content: fullContent.value, count: 0 }
  const kw = keyword.value.toLowerCase().trim()
  const lines = fullContent.value
    .split('\n')
    .filter((line) => line.toLowerCase().includes(kw))
  return { content: lines.join('\n'), count: lines.length }
})

const filteredContent = computed(() => filteredLog.value.content)
const matchCount = computed(() => filteredLog.value.count)

async function loadSysFiles() {
  try {
    sysFiles.value = (await getLogFiles(sysDate.value)) || []
    if (sysFiles.value.length > 0) {
      const firstFile = sysFiles.value[0].file
      if (sysSelected.value === firstFile) void loadSysContent()
      else sysSelected.value = firstFile
    } else {
      sysContent.value = '该日期暂无日志文件'
    }
  } catch {
    sysFiles.value = []
  }
}

async function loadSysContent() {
  if (!sysSelected.value) return
  try {
    const res = await getLogContent(sysSelected.value)
    fullContent.value = res.content || ''
    sysContent.value = fullContent.value
  } catch {
    // ignore
  }
}

async function loadTrainFiles() {
  try {
    trainFiles.value = (await getTrainingLogFiles()) || []
    if (trainFiles.value.length > 0) {
      const firstFile = trainFiles.value[0].file
      if (trainSelected.value === firstFile) void loadTrainContent()
      else trainSelected.value = firstFile
    } else {
      trainContent.value = '暂无训练日志'
    }
  } catch {
    trainFiles.value = []
  }
}

async function loadTrainContent() {
  if (!trainSelected.value) return
  try {
    const res = await getTrainingLogContent(trainSelected.value)
    fullContent.value = res.content || ''
    trainContent.value = fullContent.value
  } catch {
    // ignore
  }
}

async function refresh() {
  if (activeTab.value === 'system') {
    await loadSysContent()
  } else {
    await loadTrainContent()
  }
}

const { start: startPolling, stop: stopPolling } = usePolling(
  refresh,
  () => refreshInterval.value * 1000,
  { immediate: false },
)

function startAutoRefresh() {
  stopPolling()
  if (refreshInterval.value === 0) {
    stopCountdown()
    return
  }
  startCountdown()
  startPolling()
}

watch(refreshInterval, startAutoRefresh)
watch(activeTab, () => {
  keyword.value = ''
  if (activeTab.value === 'system') loadSysFiles()
  else loadTrainFiles()
})
watch(sysSelected, loadSysContent)
watch(trainSelected, loadTrainContent)

onMounted(() => {
  loadSysFiles()
  startAutoRefresh()
})
</script>

<template>
  <PageCard title="查看日志">
    <!-- Tab 切换 -->
    <el-tabs v-model="activeTab" style="margin-bottom: 16px">
      <el-tab-pane label="系统日志" name="system" />
      <el-tab-pane label="训练日志" name="training" />
    </el-tabs>

    <!-- 系统日志选项 -->
    <div v-if="activeTab === 'system'" class="log-options">
      <div class="option-group">
        <span class="option-label">选择日期:</span>
        <el-date-picker v-model="sysDate" type="date" value-format="YYYY-MM-DD" style="width: 160px" @change="loadSysFiles" />
      </div>
    </div>

    <div class="option-group">
      <span class="option-label">日志类型:</span>
      <el-select v-if="activeTab === 'system'" v-model="sysSelected" placeholder="请选择日志文件" style="width: 320px">
        <el-option v-for="f in sysFiles" :key="f.file" :label="`${f.name} (${f.size})`" :value="f.file" />
      </el-select>
      <el-select v-else v-model="trainSelected" placeholder="请选择训练日志" style="width: 320px">
        <el-option v-for="f in trainFiles" :key="f.file" :label="`${f.name} (PID: ${f.pid})`" :value="f.file" />
      </el-select>
    </div>

    <div class="option-group">
      <span class="option-label">自动刷新:</span>
      <el-select v-model="refreshInterval" style="width: 100px">
        <el-option :value="0" label="关闭" />
        <el-option :value="5" label="5秒" />
        <el-option :value="10" label="10秒" />
        <el-option :value="30" label="30秒" />
        <el-option :value="60" label="60秒" />
      </el-select>
      <span v-if="refreshInterval > 0" class="countdown">下次刷新: {{ remaining }}秒</span>
      <el-button @click="refresh">立即刷新</el-button>
    </div>

    <!-- 日志内容 -->
    <div class="log-content-box">
      <div class="log-toolbar">
        <el-input v-model="keyword" placeholder="搜索日志..." size="small" clearable style="width: 240px">
          <template #prefix><i class="fa fa-search" /></template>
        </el-input>
        <span v-if="keyword" class="match-count">{{ matchCount }} 条匹配</span>
      </div>
      <pre class="log-pre">{{ filteredContent || (activeTab === 'system' ? sysContent : trainContent) || '日志内容将在这里显示...' }}</pre>
    </div>
  </PageCard>
</template>

<style scoped lang="scss">
.log-options {
  margin-bottom: 16px;
}

.option-group {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;

  .option-label {
    font-size: 13px;
    color: #606266;
    white-space: nowrap;
  }

  .countdown {
    font-size: 12px;
    color: #909399;
  }
}

.log-content-box {
  border: 1px solid #ebeef5;
  border-radius: 6px;
  overflow: hidden;
}

.log-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 16px;
  background: #f5f7fa;
  border-bottom: 1px solid #ebeef5;

  .match-count {
    font-size: 12px;
    color: #909399;
  }
}

.log-pre {
  margin: 0;
  padding: 16px;
  background: #1e1e1e;
  color: #d4d4d4;
  font-family: 'SFMono-Regular', Consolas, monospace;
  font-size: 12px;
  line-height: 1.6;
  max-height: 600px;
  overflow: auto;
  white-space: pre-wrap;
  word-wrap: break-word;
}
</style>
