<template>
  <div class="task-page">
    <el-card class="task-card">
      <!-- 工具栏 -->
      <div class="toolbar" ref="toolbarRef">
        <!-- 你的筛选表单（保持不变） -->
        <el-form :inline="true" :model="filters" label-width="90px" @keyup.enter.native="onSearch">
          <el-form-item label="ID">
            <el-input v-model.number="filters.id" placeholder="精确 ID" clearable />
          </el-form-item>
          <el-form-item label="日期">
            <el-date-picker v-model="filters.date_string" type="date" value-format="YYYY-MM-DD" placeholder="YYYY-MM-DD" clearable />
          </el-form-item>
          <el-form-item label="Trace ID">
            <el-input v-model="filters.trace_id" placeholder="模糊匹配" clearable />
          </el-form-item>
          <el-form-item label="状态">
            <el-select v-model="filters.task_status" placeholder="全部" clearable style="width: 160px">
              <el-option v-for="s in statusOptions" :key="s.value" :label="s.label" :value="s.value" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="onSearch">查询</el-button>
            <el-button @click="onReset">重置</el-button>
          </el-form-item>
          <el-form-item>
            <el-switch v-model="autoRefresh" @change="toggleAutoRefresh" />
            <span class="ml-8">自动刷新（5s）</span>
          </el-form-item>
        </el-form>
      </div>

      <!-- 表格 -->
      <div class="table-wrapper">
        <el-table
          :data="rows"
          border
          stripe
          :height="tableHeight"
          @sort-change="onSortChange"
          class="custom-table"
          v-loading="loading"
          element-loading-text="加载中…"
        >
          <el-table-column prop="id" label="ID" sortable="custom" width="100" />
          <el-table-column prop="date_string" label="日期" sortable="custom" width="140" />
          <el-table-column prop="task_name" label="任务名称" min-width="200" :show-overflow-tooltip="true" />
          <el-table-column prop="task_status" label="状态" sortable="custom" width="140">
            <template #default="{ row }">
              <el-tag :type="statusType(row.task_status)">{{ row.status_text || row.task_status }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="start_timestamp" label="开始时间" sortable="custom" width="180">
            <template #default="{ row }">{{ formatTs(row.start_timestamp) }}</template>
          </el-table-column>
          <el-table-column prop="finish_timestamp" label="结束时间" sortable="custom" width="180">
            <template #default="{ row }">{{ formatTs(row.finish_timestamp) }}</template>
          </el-table-column>
          <el-table-column prop="trace_id" label="Trace ID" min-width="220" :show-overflow-tooltip="true" />
          <el-table-column label="操作" fixed="right" width="240">
            <template #default="{ row }">
              <el-button size="small" @click="openDetail(row)">详情</el-button>
              <el-button size="small" type="warning" @click="onRetry(row)" :disabled="row.task_status === 1">重试</el-button>
              <el-button size="small" type="danger" @click="onCancel(row)" :disabled="row.task_status === 2">取消</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <!-- 分页 -->
      <div class="pager" ref="pagerRef">
        <el-pagination
          background
          layout="total, sizes, prev, pager, next, jumper"
          :page-sizes="[10, 20, 50, 100]"
          :page-size="query.page_size"
          :total="total"
          :current-page="query.page"
          @current-change="(p:number)=>{query.page=p; load()}"
          @size-change="(s:number)=>{query.page_size=s; query.page=1; load()}"
        />
      </div>
    </el-card>

    <!-- 详情 -->
    <el-drawer v-model="detailOpen" size="52%" title="任务详情">
      <div class="detail">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="ID">{{ detail?.id }}</el-descriptions-item>
          <el-descriptions-item label="日期">{{ detail?.date_string }}</el-descriptions-item>
          <el-descriptions-item label="状态">{{ detail?.task_status }}（{{ detail?.status_text }}）</el-descriptions-item>
          <el-descriptions-item label="Trace ID">{{ detail?.trace_id }}</el-descriptions-item>
          <el-descriptions-item label="开始">{{ formatTs(detail?.start_timestamp) }}</el-descriptions-item>
          <el-descriptions-item label="结束">{{ formatTs(detail?.finish_timestamp) }}</el-descriptions-item>
          <el-descriptions-item label="任务名" :span="2">{{ detail?.task_name }}</el-descriptions-item>
        </el-descriptions>

        <h4 class="block-title">请求参数（data）</h4>
        <pre class="code-block">{{ pretty(detail?.data_json || detail?.data) }}</pre>
      </div>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { onMounted, onBeforeUnmount, reactive, ref, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { fetchTasks, fetchTaskDetail, retryTask, cancelTask, type TaskItem } from '../api/task'

const statusOptions = [
  { label: '初始化(0)', value: 0 },
  { label: '处理中(1)', value: 1 },
  { label: '完成(2)', value: 2 },
  { label: '失败(99)', value: 99 },
]

const filters = reactive<{ id: number | null; date_string: string | null; trace_id: string; task_status: number | null }>({
  id: null,
  date_string: null,
  trace_id: '',
  task_status: null,
})

const query = reactive({ page: 1, page_size: 20, sort_by: 'id', sort_dir: 'desc' as 'asc' | 'desc' })
const rows = ref<TaskItem[]>([])
const total = ref(0)
const loading = ref(false)

/* 自动刷新 */
let timer: ReturnType<typeof setInterval> | null = null
const autoRefresh = ref(false)
const toggleAutoRefresh = () => {
  if (autoRefresh.value) {
    timer = setInterval(load, 5000)
  } else if (timer) {
    clearInterval(timer)
    timer = null
  }
}

/* 精准表格高度计算 */
const toolbarRef = ref<HTMLElement | null>(null)
const pagerRef = ref<HTMLElement | null>(null)
const tableHeight = ref(400)
const calcTableHeight = () => {
  const winH = window.innerHeight
  const toolbarH = toolbarRef.value?.offsetHeight ?? 0
  const pagerH = pagerRef.value?.offsetHeight ?? 0
  const outerPadding = 16 * 2         // .task-page 上下 padding
  const cardPadding = 20 * 2          // el-card 内部上下 padding（大约值）
  const gap = 12 + 12                 // toolbar 下方间距 + pager 上方 padding
  tableHeight.value = Math.max(
    260,
    winH - (outerPadding + cardPadding + toolbarH + pagerH + gap)
  )
}

/* 加载列表（POST） */
const load = async () => {
  loading.value = true
  try {
    const params: any = { ...query }
    if (filters.id) params.id = filters.id
    if (filters.date_string) params.date_string = filters.date_string
    if (filters.trace_id) params.trace_id = filters.trace_id
    if (filters.task_status !== null && filters.task_status !== undefined) params.task_status = filters.task_status

    const resp = await fetchTasks(params)
    rows.value = resp.items
    total.value = resp.total
    await nextTick()
    calcTableHeight()
  } finally {
    loading.value = false
  }
}

/* 交互 */
const onSearch = () => { query.page = 1; load() }
const onReset = () => {
  Object.assign(filters, { id: null, date_string: null, trace_id: '', task_status: null })
  query.page = 1
  load()
}
const onSortChange = (e: any) => {
  query.sort_by = e.prop || 'id'
  query.sort_dir = e.order === 'ascending' ? 'asc' : 'desc'
  load()
}

/* 工具 */
const statusType = (s: number) => (s === 0 ? 'info' : s === 1 ? 'warning' : s === 2 ? 'success' : s === 99 ? 'danger' : '')
const formatTs = (ts?: number | null) => (!ts ? '-' : new Date(ts * 1000).toLocaleString())
const pretty = (v: any) => { try { return typeof v === 'string' ? v : JSON.stringify(v, null, 2) } catch { return String(v) } }

/* 详情 */
const detailOpen = ref(false)
const detail = ref<TaskItem | null>(null)
const openDetail = async (row: TaskItem) => {
  const d = await fetchTaskDetail(row.id)
  detail.value = { ...row, ...d }
  detailOpen.value = true
}

/* 行操作 */
const onRetry = async (row: TaskItem) => {
  await ElMessageBox.confirm(`确认将任务 #${row.id} 置为初始化并重试？`, '重试确认', { type: 'warning' })
  await retryTask(row.id)
  ElMessage.success('已触发重试')
  load()
}
const onCancel = async (row: TaskItem) => {
  await ElMessageBox.confirm(`确认取消任务 #${row.id}（置为失败）？`, '取消确认', { type: 'warning' })
  await cancelTask(row.id)
  ElMessage.success('已取消')
  load()
}

/* 生命周期 */
onMounted(() => {
  load()
  window.addEventListener('resize', calcTableHeight)
})
onBeforeUnmount(() => {
  window.removeEventListener('resize', calcTableHeight)
  if (timer) clearInterval(timer)
})
</script>

<style scoped>
.task-page {
  padding: 16px;
  background: #f5f6fa;
  height: 100vh;          /* 让页面可用高度=视口高度 */
  box-sizing: border-box;
}
.task-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  box-shadow: 0 6px 18px rgba(0,0,0,0.06);
  border-radius: 10px;
}
.toolbar { margin-bottom: 12px; }
.table-wrapper { flex: 1; overflow: hidden; }
.custom-table { border-radius: 8px; overflow: hidden; }
.pager {
  display: flex;
  justify-content: flex-end;
  padding: 12px 0 0 0;   /* 顶部 12px，底部 0，避免留白 */
  background: #fff;
  border-top: 1px solid #f0f2f5;
  margin: 0;             /* 清除可能的外边距 */
}
.detail { padding: 8px 0; }
.block-title { margin: 14px 0 8px; font-weight: 600; }
.code-block {
  background: #0b1021; color: #d1e7ff; padding: 12px;
  border-radius: 8px; overflow: auto; line-height: 1.5;
}
.ml-8 { margin-left: 8px; }
</style>
