<script setup lang="ts">
import { NButton, NSpin, useDialog } from 'naive-ui'
import { computed, onUnmounted, ref } from 'vue'

import { deleteTask, listTasks, runTask, updateTask } from '@/api/tasks'
import EmptyCard from '@/components/EmptyCard.vue'
import TaskCard from '@/components/task/TaskCard.vue'
import TaskFormModal from '@/components/task/TaskFormModal.vue'
import { parseSnatch } from '@/components/task/taskDisplay'
import { useAsync } from '@/composables/useAsync'
import { useScopeStore } from '@/stores/scope'
import type { Task } from '@/types/api'
import { useToast } from '@/composables/useToast'

const message = useToast()
const dialog = useDialog()
const scope = useScopeStore()

const tasks = useAsync(listTasks)
const showCreate = ref(false)
const editingTask = ref<Task | null>(null)

// 每 5 秒静默刷新（不闪 loading）
const refreshTimer = setInterval(() => void tasks.run({ silent: true }), 5000)
onUnmounted(() => clearInterval(refreshTimer))

const cfgAliasById = computed(
  () => new Map((scope.configs.data ?? []).map((c) => [c.id, c.alias])),
)

function aliasFor(task: Task): string | undefined {
  const s = parseSnatch(task)
  return s ? cfgAliasById.value.get(s.cfgId) : undefined
}

function openEdit(task: Task) {
  editingTask.value = task
  showCreate.value = true
}

function openCreate() {
  editingTask.value = null
  showCreate.value = true
}

async function act(fn: () => Promise<unknown>, ok: string) {
  try {
    await fn()
    message.success(ok)
    void tasks.run({ silent: true })
  } catch (e) {
    message.error(e instanceof Error ? e.message : '操作失败')
  }
}

/** active ↔ paused 切换；failed（熔断停止）同走恢复交互重新启用 */
function toggle(task: Task) {
  const resume = task.status !== 'active'
  void act(
    () => updateTask(task.id, { status: resume ? 'active' : 'paused' }),
    resume ? (task.status === 'failed' ? '已重新启用' : '已恢复调度') : '已暂停',
  )
}

function confirmRemove(task: Task) {
  dialog.warning({
    title: '删除任务',
    content: `删除任务「${task.name}」及其全部日志？`,
    positiveText: '删除',
    negativeText: '取消',
    onPositiveClick: () => act(() => deleteTask(task.id), '已删除任务及其日志'),
  })
}
</script>

<template>
  <div class="flex flex-col gap-4 p-6 pb-8 max-md:p-3">
    <div class="flex flex-wrap items-center justify-between gap-2">
      <div class="flex flex-wrap items-baseline gap-2.5">
        <h1 class="page-title">任务</h1>
        <span class="text-[13px] text-ink-3">
          {{ tasks.data.value?.length ?? '…' }} 个任务 · cron 为服务器本地时区
        </span>
      </div>
      <NButton size="small" type="primary" @click="openCreate">新建任务</NButton>
    </div>

    <div
      v-if="tasks.loading.value && !tasks.data.value"
      class="panel flex items-center justify-center py-20"
    >
      <NSpin size="small" />
    </div>
    <div v-else class="flex flex-col gap-3">
      <TaskCard
        v-for="task in tasks.data.value ?? []"
        :key="task.id"
        :task="task"
        :cfg-alias="aliasFor(task)"
        @run="act(() => runTask(task.id), `已触发执行：${task.name}`)"
        @toggle="toggle(task)"
        @edit="openEdit(task)"
        @remove="confirmRemove(task)"
      />
      <EmptyCard
        v-if="tasks.data.value && !tasks.data.value.length"
        title="暂无任务"
        note="点击右上角「新建任务」创建测活 / 抢机 / 成本任务"
      />
    </div>

    <TaskFormModal v-model:show="showCreate" :task="editingTask" @created="tasks.run()" />
  </div>
</template>
