<script setup>
import { Refresh } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { deleteSavedModel, getSavedModels, updateSavedModel } from '@/api/trainManagement'

const router = useRouter()

const models = ref([])
const loading = ref(false)

const loadModels = async () => {
  loading.value = true
  try {
    models.value = await getSavedModels()
  } finally {
    loading.value = false
  }
}

// ── edit dialog ───────────────────────────────────────────────────────────────
const editVisible = ref(false)
const editRow = ref(null)
const editForm = reactive({ model_name: '', description: '' })
const editSaving = ref(false)

const handleEdit = (row) => {
  editRow.value = row
  editForm.model_name = row.model_name
  editForm.description = row.description || ''
  editVisible.value = true
}

const confirmEdit = async () => {
  if (!editForm.model_name.trim()) return ElMessage.warning('模型名称不能为空')
  editSaving.value = true
  try {
    await updateSavedModel(editRow.value.id, {
      model_name: editForm.model_name.trim(),
      description: editForm.description.trim(),
    })
    ElMessage.success('已更新')
    editVisible.value = false
    await loadModels()
  } catch (e) {
    ElMessage.error(e?.message || '更新失败')
  } finally {
    editSaving.value = false
  }
}

// ── evaluate shortcut ─────────────────────────────────────────────────────────
const handleEvaluate = (row) => {
  router.push({ name: 'model-evaluation', query: { model_id: row.id } })
}

// ── delete ────────────────────────────────────────────────────────────────────
const handleDelete = async (row) => {
  try {
    await ElMessageBox.confirm(`确定删除模型"${row.model_name}"吗？删除后无法恢复。`, '提示', {
      type: 'warning',
    })
    await deleteSavedModel(row.id)
    ElMessage.success('模型已删除')
    await loadModels()
  } catch {
    // user cancelled
  }
}

// ── display helpers ───────────────────────────────────────────────────────────
const formatParams = (params) => {
  if (!params) return '-'
  return [
    `序列长度 ${params.seq_len}`,
    `隐藏层 ${params.hidden_size}`,
    `层数 ${params.num_layers}`,
    `轮数 ${params.epochs}`,
    `批次 ${params.batch_size}`,
    `学习率 ${params.learning_rate}`,
  ].join(' / ')
}

const formatLoss = (row) => {
  if (row.train_loss == null) return '-'
  const train = `训练 ${Number(row.train_loss).toFixed(5)}`
  const val = row.val_loss != null ? ` / 验证 ${Number(row.val_loss).toFixed(5)}` : ''
  return train + val
}

onMounted(loadModels)
</script>

<template>
  <div class="model-list-page">
    <el-card shadow="hover" class="list-card">
      <template #header>
        <div class="card-header-row">
          <span class="card-title">已保存模型</span>
          <el-button :icon="Refresh" size="small" plain :loading="loading" @click="loadModels">
            刷新
          </el-button>
        </div>
      </template>

      <el-table :data="models" v-loading="loading" border stripe height="calc(100vh - 160px)">
        <el-table-column type="index" width="55" label="#" align="center" />

        <el-table-column prop="model_name" label="模型名称" min-width="140" show-overflow-tooltip />
        <el-table-column prop="description" label="说明" min-width="160" show-overflow-tooltip>
          <template #default="{ row }">
            <span class="desc-text">{{ row.description || '—' }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="package_name" label="训练数据包" min-width="140" show-overflow-tooltip />

        <el-table-column label="LSTM 参数" min-width="310" show-overflow-tooltip>
          <template #default="{ row }">
            <el-tooltip :content="formatParams(row.params)" placement="top">
              <span class="params-text">{{ formatParams(row.params) }}</span>
            </el-tooltip>
          </template>
        </el-table-column>

        <el-table-column label="训练损失" min-width="190" show-overflow-tooltip>
          <template #default="{ row }">
            <span class="loss-text">{{ formatLoss(row) }}</span>
          </template>
        </el-table-column>

        <el-table-column prop="created_at" label="保存时间" width="170" />

        <el-table-column label="操作" width="160" fixed="right" align="center">
          <template #default="{ row }">
            <el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
            <el-button link type="success" @click="handleEvaluate(row)">评估</el-button>
            <el-button link type="danger" @click="handleDelete(row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-empty
        v-if="!loading && models.length === 0"
        description="暂无已保存的模型，请先在模型训练页面完成训练并保存"
        style="padding: 40px 0"
      />
    </el-card>
  </div>

  <!-- ── edit dialog ──────────────────────────────────────────────── -->
  <el-dialog v-model="editVisible" title="编辑模型信息" width="480px" :close-on-click-modal="false">
    <el-form :model="editForm" label-position="top">
      <el-form-item label="模型名称" required>
        <el-input v-model="editForm.model_name" maxlength="100" show-word-limit />
      </el-form-item>
      <el-form-item label="说明">
        <el-input
          v-model="editForm.description"
          type="textarea"
          :rows="3"
          placeholder="模型用途、训练说明等"
          maxlength="500"
          show-word-limit
        />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="editVisible = false">取消</el-button>
      <el-button type="primary" :loading="editSaving" @click="confirmEdit">保存</el-button>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.model-list-page {
  height: 100%;
  overflow: hidden;
  background: var(--bg-page);
}

.list-card {
  height: 100%;
  overflow: hidden;
  border-radius: 4px;
  border: 1px solid var(--border-color);
  box-shadow: var(--shadow-card) !important;

  :deep(.el-card__header) {
    padding: 0 20px;
    height: 44px;
    display: flex;
    align-items: center;
    border-bottom: 1px solid var(--border-color);
    background: #F7F8FA;
  }

  :deep(.el-card__body) {
    padding: 16px 20px;
    height: calc(100% - 44px);
    overflow: hidden;
  }
}

.card-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
}

.card-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.params-text,
.loss-text,
.desc-text {
  font-size: 12px;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: block;
}

.loss-text {
  color: var(--primary);
  font-weight: 500;
}
</style>


