<script setup lang="ts">
import { onMounted, ref } from 'vue'
import {
  cancelPipelineRun,
  createPipelineRun,
  fetchPipelineRun,
  fetchPipelineRuns,
  resumePipelineRun,
} from '../api/pipeline'
import PipelineRunActions from '../components/pipeline/PipelineRunActions.vue'
import PipelineStatusCard from '../components/pipeline/PipelineStatusCard.vue'
import PipelineStepTimeline from '../components/pipeline/PipelineStepTimeline.vue'
import type { PipelineRun } from '../types/pipeline'

const runs = ref<PipelineRun[]>([])
const selected = ref<PipelineRun | null>(null)
const loading = ref(false)
const busy = ref(false)
const error = ref('')
const bizDt = ref(new Intl.DateTimeFormat('sv-SE', {
  timeZone: 'Asia/Shanghai',
  year: 'numeric',
  month: '2-digit',
  day: '2-digit',
}).format(new Date()).replaceAll('-', ''))

async function loadRuns() {
  loading.value = true
  error.value = ''
  try {
    runs.value = (await fetchPipelineRuns()).items
    if (!selected.value && runs.value[0]) await selectRun(runs.value[0].run_id)
  } catch (cause) {
    error.value = cause instanceof Error ? cause.message : String(cause)
  } finally {
    loading.value = false
  }
}

async function selectRun(runId: string) {
  selected.value = await fetchPipelineRun(runId)
}

async function submit() {
  busy.value = true
  try {
    const result = await createPipelineRun(bizDt.value)
    await loadRuns()
    await selectRun(result.run_id)
  } finally {
    busy.value = false
  }
}

async function resume() {
  if (!selected.value) return
  busy.value = true
  try {
    await resumePipelineRun(selected.value.run_id)
    await selectRun(selected.value.run_id)
  } finally {
    busy.value = false
  }
}

async function cancel() {
  if (!selected.value) return
  busy.value = true
  try {
    await cancelPipelineRun(selected.value.run_id)
    await selectRun(selected.value.run_id)
  } finally {
    busy.value = false
  }
}

onMounted(loadRuns)
</script>

<template>
  <main class="pipeline-runs">
    <header>
      <div>
        <span>PIPELINE CONTROL CENTER</span>
        <h1>定时任务运行中心</h1>
        <p>MySQL 持久化状态 · 严格门禁 · AIGC dry-run</p>
      </div>
      <form @submit.prevent="submit">
        <input v-model="bizDt" pattern="\d{8}" aria-label="业务日" />
        <button :disabled="busy">创建批次</button>
      </form>
    </header>

    <p v-if="error" class="error">{{ error }}</p>
    <div class="layout">
      <aside>
        <p v-if="loading">加载中…</p>
        <button v-for="run in runs" :key="run.run_id" class="run-item" @click="selectRun(run.run_id)">
          <PipelineStatusCard :run="run" />
        </button>
      </aside>
      <section v-if="selected" class="detail">
        <div class="detail-head">
          <div>
            <h2>{{ selected.biz_dt }} · {{ selected.status }}</h2>
            <code>{{ selected.run_id }}</code>
          </div>
          <PipelineRunActions :run="selected" :busy="busy" @resume="resume" @cancel="cancel" />
        </div>
        <PipelineStepTimeline :steps="selected.steps || []" />
      </section>
    </div>
  </main>
</template>

<style scoped>
.pipeline-runs { max-width: 1240px; margin: 0 auto; padding: 32px 24px 72px; }
header, .detail-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; }
header span { font-size: 12px; letter-spacing: .12em; color: #667085; }
h1 { margin: 6px 0; }
form { display: flex; gap: 8px; }
input, form button { border: 1px solid #cbd2df; border-radius: 8px; padding: 9px 12px; }
.layout { display: grid; grid-template-columns: 320px 1fr; gap: 24px; margin-top: 28px; }
aside { display: grid; gap: 10px; align-content: start; }
.run-item { text-align: left; border: 0; background: transparent; padding: 0; cursor: pointer; }
.detail { border: 1px solid #d9dee8; border-radius: 14px; padding: 20px; }
.detail-head { margin-bottom: 20px; }
.error { color: #b42335; }
@media (max-width: 800px) { .layout { grid-template-columns: 1fr; } header { flex-direction: column; } }
</style>
