<template>
  <div class="ota-jobs">
    <el-alert :title="jobsHint" type="info" :closable="false" show-icon class="jobs-hint" />
    <div class="toolbar">
      <el-button size="small" :icon="Refresh" :loading="loading" @click="reload">刷新</el-button>
    </div>

    <el-table v-loading="loading" :data="jobs" size="small" height="220" highlight-current-row @current-change="onPick">
      <el-table-column prop="id" label="任务" min-width="160">
        <template #default="{ row }"><span class="mono">{{ row.id }}</span></template>
      </el-table-column>
      <el-table-column prop="kind" label="类型" width="100" />
      <el-table-column label="状态" width="100">
        <template #default="{ row }">
          <el-tag size="small" :type="statusType(row.status)">{{ row.status }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="进度" width="160">
        <template #default="{ row }">
          <el-progress
            :percentage="pct(row)"
            :status="row.status === 'failed' ? 'exception' : row.status === 'succeeded' ? 'success' : undefined"
            :stroke-width="10"
          />
        </template>
      </el-table-column>
      <el-table-column label="时间" width="160">
        <template #default="{ row }">{{ formatTs(row.createdAt) }}</template>
      </el-table-column>
      <el-table-column label="操作" width="140" fixed="right">
        <template #default="{ row }">
          <el-button
            link
            size="small"
            :disabled="!canWrite || !['pending', 'probing', 'running'].includes(row.status)"
            @click="onCancel(row)"
          >
            取消
          </el-button>
          <el-button
            link
            type="primary"
            size="small"
            :disabled="!canWrite || !row.steps?.some((s: any) => s.status === 'failed')"
            @click="onRetry(row)"
          >
            重试失败
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <div class="detail">
      <h4>步骤明细 {{ current?.id || '' }}</h4>
      <el-empty v-if="!current" description="选择任务查看进度" :image-size="56" />
      <el-table v-else :data="current.steps" size="small" max-height="240">
        <el-table-column prop="carId" label="车辆" width="120" />
        <el-table-column prop="ip" label="IP" width="120" />
        <el-table-column prop="component" label="组件" width="120" />
        <el-table-column prop="status" label="状态" width="100" />
        <el-table-column prop="error" label="错误" min-width="180" show-overflow-tooltip />
      </el-table>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'
import { Refresh } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { cancelOtaJob, listOtaJobs, retryOtaJob } from '@/api/ota'
import type { OtaJob } from '@/types/ota'
import { OTA_COPY } from './otaCopy'

defineProps<{ canWrite: boolean }>()
const jobsHint = OTA_COPY.jobsHint

const jobs = ref<OtaJob[]>([])
const current = ref<OtaJob | null>(null)
const loading = ref(false)
let timer: ReturnType<typeof setInterval> | null = null

function pct(row: OtaJob) {
  if (!row.totalSteps) return 0
  return Math.min(100, Math.round((row.doneSteps / row.totalSteps) * 100))
}

function statusType(s: string) {
  if (s === 'succeeded') return 'success'
  if (s === 'failed') return 'danger'
  if (s === 'partial') return 'warning'
  if (s === 'cancelled') return 'info'
  return undefined
}

function formatTs(v?: string) {
  if (!v) return '—'
  try {
    return new Date(v).toLocaleString()
  } catch {
    return v
  }
}

async function reload() {
  loading.value = true
  try {
    jobs.value = await listOtaJobs(80)
    if (current.value) {
      current.value = jobs.value.find((j) => j.id === current.value!.id) || current.value
    }
  } catch (e: any) {
    ElMessage.error(e?.message || '加载任务失败')
  } finally {
    loading.value = false
  }
}

function onPick(row: OtaJob | null) {
  current.value = row
}

async function onCancel(row: OtaJob) {
  try {
    await cancelOtaJob(row.id)
    ElMessage.success('已取消')
    await reload()
  } catch (e: any) {
    ElMessage.error(e?.message || '取消失败')
  }
}

async function onRetry(row: OtaJob) {
  try {
    const j = await retryOtaJob(row.id)
    ElMessage.success(`已创建重试任务 ${j.id}`)
    await reload()
  } catch (e: any) {
    ElMessage.error(e?.message || '重试失败')
  }
}

onMounted(() => {
  void reload()
  timer = setInterval(() => void reload(), 4000)
})
onUnmounted(() => {
  if (timer) clearInterval(timer)
})
</script>

<style scoped>
.jobs-hint {
  margin-bottom: 10px;
}
.toolbar {
  margin-bottom: 8px;
}
.detail {
  margin-top: 14px;
}
.detail h4 {
  margin: 0 0 8px;
  font-size: 13px;
}
.mono {
  font-family: var(--mg-font-mono);
  font-size: 12px;
}
</style>
