<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import DataTablePage from '@/components/DataTablePage.vue'
import ModelStatusTag from '@/components/ModelStatusTag.vue'
import { useModelsStore } from '@/stores/models'
import {
  getFineTuneList,
  deleteFineTune,
  stopFineTune,
  getFineTuneProgress,
  getFineTune,
} from '@/api/modules/fineTune'
import { TRAIN_TYPE_MAP, TRAIN_METHOD_MAP } from '@/constants'
import type { FineTuneTask, TrainingProgress } from '@/types'

const router = useRouter()
const modelsStore = useModelsStore()

const loading = ref(false)
const dataList = ref<FineTuneTask[]>([])
const progressCache = ref<Record<string, TrainingProgress>>({})

// ============ 列头筛选 ============
const trainTypeOptions = Object.entries(TRAIN_TYPE_MAP).map(([value, label]) => ({ value, label }))
const trainMethodOptions = Object.entries(TRAIN_METHOD_MAP).map(([value, label]) => ({ value, label }))

const filters = ref({
  trainType: [] as string[],
  trainMethod: [] as string[],
})

/** 应用筛选后的列表 */
const filteredList = computed(() => {
  return dataList.value.filter((row) => {
    if (filters.value.trainType.length && !filters.value.trainType.includes(row.train_type)) {
      return false
    }
    if (filters.value.trainMethod.length && !filters.value.trainMethod.includes(row.train_method)) {
      return false
    }
    return true
  })
})

let progressTimer: ReturnType<typeof setInterval> | null = null

async function loadData() {
  loading.value = true
  try {
    dataList.value = (await getFineTuneList()) || []
    // 列表加载完成后，立即获取一次运行中任务的进度
    refreshProgress()
  } catch {
    // 拦截器已提示
  } finally {
    loading.value = false
  }
}

/** 刷新训练进度（仅 running/pending 任务） */
async function refreshProgress() {
  const activeTasks = dataList.value.filter(
    (t) => t.status === 'running' || t.status === 'pending',
  )
  for (const task of activeTasks) {
    try {
      const [progress, status] = await Promise.all([
        getFineTuneProgress(task.id),
        getFineTune(task.id),
      ])
      progressCache.value[task.id] = progress
      // 状态变化时更新
      if (status.status && status.status !== task.status) {
        task.status = status.status
      }
    } catch {
      // 静默
    }
  }
}

async function handleDelete(row: any) {
  await deleteFineTune(row.id)
  ElMessage.success('删除成功')
}

async function handleStop(row: any) {
  await stopFineTune(row.id)
  ElMessage.success('训练任务已停止')
  loadData()
}

function viewLog(row: any) {
  router.push(`/training-log/${row.id}`)
}

function formatDateTime(value?: string) {
  if (!value) return '-'
  return new Date(value).toLocaleString('zh-CN', { hour12: false })
}

onMounted(() => {
  modelsStore.load()
  loadData()
  progressTimer = setInterval(refreshProgress, 5000)
})

onUnmounted(() => {
  if (progressTimer) clearInterval(progressTimer)
})
</script>

<template>
  <DataTablePage
    title="模型微调"
    :data="filteredList"
    :loading="loading"
    searchable
    :search-fields="['name']"
    create-text="创建训练任务"
    create-to="/fine-tune/create"
    row-key="id"
    :page-size="10"
    @refresh="loadData"
  >
    <template #columns>
      <el-table-column
        label="任务名称"
        prop="name"
        align="center"
        width="180"
        show-overflow-tooltip
      />
      <el-table-column label="任务状态" align="center" width="110">
        <template #default="{ row }">
          <ModelStatusTag :status="row.status" />
        </template>
      </el-table-column>
      <el-table-column align="center" width="140">
        <template #header>
          <div class="filter-header">
            <span>训练方式</span>
            <el-popover trigger="click" placement="bottom" :width="160">
              <template #reference>
                <el-badge :is-dot="filters.trainType.length > 0" class="filter-badge">
                  <i
                    class="fa fa-filter filter-icon"
                    :class="{ active: filters.trainType.length > 0 }"
                  />
                </el-badge>
              </template>
              <el-checkbox-group v-model="filters.trainType" class="filter-options">
                <el-checkbox v-for="opt in trainTypeOptions" :key="opt.value" :value="opt.value">
                  {{ opt.label }}
                </el-checkbox>
              </el-checkbox-group>
              <div class="filter-actions">
                <el-button size="small" link @click="filters.trainType = []">清除</el-button>
              </div>
            </el-popover>
          </div>
        </template>
        <template #default="{ row }">
          {{ TRAIN_TYPE_MAP[row.train_type] || '-' }}
        </template>
      </el-table-column>
      <el-table-column align="center" width="120">
        <template #header>
          <div class="filter-header">
            <span>训练方法</span>
            <el-popover trigger="click" placement="bottom" :width="160">
              <template #reference>
                <el-badge :is-dot="filters.trainMethod.length > 0" class="filter-badge">
                  <i
                    class="fa fa-filter filter-icon"
                    :class="{ active: filters.trainMethod.length > 0 }"
                  />
                </el-badge>
              </template>
              <el-checkbox-group v-model="filters.trainMethod" class="filter-options">
                <el-checkbox v-for="opt in trainMethodOptions" :key="opt.value" :value="opt.value">
                  {{ opt.label }}
                </el-checkbox>
              </el-checkbox-group>
              <div class="filter-actions">
                <el-button size="small" link @click="filters.trainMethod = []">清除</el-button>
              </div>
            </el-popover>
          </div>
        </template>
        <template #default="{ row }">{{ row.train_method || '-' }}</template>
      </el-table-column>
      <el-table-column label="基座模型" align="center" width="190" show-overflow-tooltip>
        <template #default="{ row }">{{ modelsStore.getModelName(row.base_model) }}</template>
      </el-table-column>
      <el-table-column label="训练开始时间" align="center" width="190">
        <template #default="{ row }">{{ formatDateTime(row.create_time) }}</template>
      </el-table-column>
      <el-table-column label="训练时长" align="center" width="130">
        <template #default="{ row }">{{ row.train_duration || '-' }}</template>
      </el-table-column>
      <el-table-column
        label="进度"
        align="center"
        width="140"
      >
        <template #default="{ row }">
          <span class="progress-value">
            {{ progressCache[row.id]?.progress ?? row.progress ?? 0 }}%
          </span>
        </template>
      </el-table-column>
    </template>

    <template #actions="{ row }">
      <div class="action-buttons">
        <el-button
          v-if="row.status === 'running'"
          type="warning"
          link
          size="small"
          @click="handleStop(row)"
        >
          <i class="fa fa-stop-circle-o" style="margin-right: 4px" /> 停止
        </el-button>
        <el-button type="primary" link size="small" @click="viewLog(row)">
          <i class="fa fa-file-text-o" style="margin-right: 4px" /> 日志
        </el-button>
        <el-button type="danger" link size="small" @click="handleDelete(row)">
          <i class="fa fa-trash-o" style="margin-right: 4px" /> 删除
        </el-button>
      </div>
    </template>
  </DataTablePage>
</template>

<style scoped>
.progress-value {
  color: var(--primary-color);
  font-weight: 600;
}

/* 列头筛选 */
.filter-header {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.filter-badge {
  line-height: 1;
}

.filter-icon {
  cursor: pointer;
  font-size: 12px;
  color: #c0c4cc;
  transition: color 0.2s;
}

.filter-icon:hover {
  color: #1890ff;
}

.filter-icon.active {
  color: #1890ff;
}

.filter-options {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 240px;
  overflow-y: auto;
}

.filter-actions {
  text-align: right;
  margin-top: 8px;
  border-top: 1px solid #ebeef5;
  padding-top: 8px;
}
</style>
