<template>
  <div class="page-shell">
    <section class="page-card table-fill">
      <div class="page-toolbar">
        <h2 class="page-toolbar-title">OpenAPI</h2>
        <div class="page-toolbar-actions">
          <n-button :loading="loading" @click="load">
            <template #icon><n-icon :component="RefreshCw" /></template>
            刷新
          </n-button>
        </div>
      </div>

      <div class="queue-summary">
        <div class="metric">
          <span>数电账号</span>
          <strong>{{ rows.length }}</strong>
        </div>
        <div class="metric">
          <span>待处理</span>
          <strong>{{ totals.pending }}</strong>
        </div>
        <div class="metric">
          <span>处理中</span>
          <strong>{{ totals.processing }}</strong>
        </div>
        <div class="metric">
          <span>需认证</span>
          <strong>{{ totals.waitingAuth }}</strong>
        </div>
      </div>

      <div class="card-body card-body-fill table-fill">
        <n-data-table
          flex-height
          size="small"
          :columns="columns"
          :data="rows"
          :loading="loading"
          :pagination="{ pageSize: 12 }"
          :row-key="(row: OpenInvoiceTaskOverviewItem) => row.digitalAccountId"
          :row-props="rowProps"
          :scroll-x="1160"
        />
      </div>
    </section>

    <n-drawer v-model:show="drawerVisible" :width="980">
      <n-drawer-content :title="drawerTitle" closable>
        <div class="drawer-toolbar">
          <n-select
            v-model:value="taskStatus"
            clearable
            size="small"
            placeholder="全部状态"
            :options="statusOptions"
            class="task-filter"
            @update:value="loadTasks(1)"
          />
          <n-select
            v-model:value="taskSourceType"
            clearable
            size="small"
            placeholder="全部来源"
            :options="sourceTypeOptions"
            class="task-filter"
            @update:value="loadTasks(1)"
          />
          <n-button size="small" :loading="taskLoading" @click="loadTasks(taskPage)">
            <template #icon><n-icon :component="RefreshCw" /></template>
            刷新
          </n-button>
        </div>

        <n-data-table
          size="small"
          :columns="taskColumns"
          :data="tasks"
          :loading="taskLoading"
          :pagination="taskPagination"
          :scroll-x="1280"
          remote
          @update:page="loadTasks"
          @update:page-size="changeTaskPageSize"
        />
      </n-drawer-content>
    </n-drawer>
  </div>
</template>

<script setup lang="ts">
import { computed, h, onMounted, reactive, ref } from 'vue'
import type { DataTableColumns, PaginationProps } from 'naive-ui'
import { NButton, NDataTable, NDrawer, NDrawerContent, NIcon, NSelect, NTag } from 'naive-ui'
import { ListTree, Pause, Play, RefreshCw } from 'lucide-vue-next'
import {
  openInvoiceTaskOverviewApi,
  openInvoiceTaskPageApi,
  pauseOpenInvoiceTaskQueueApi,
  resumeOpenInvoiceTaskQueueApi
} from '@/api/piaotong'
import type { OpenInvoiceTaskItem, OpenInvoiceTaskOverviewItem } from '@/api/piaotong'
import { appMessage } from '@/utils/message'

const loading = ref(false)
const rows = ref<OpenInvoiceTaskOverviewItem[]>([])
const selected = ref<OpenInvoiceTaskOverviewItem | null>(null)
const drawerVisible = ref(false)
const taskLoading = ref(false)
const tasks = ref<OpenInvoiceTaskItem[]>([])
const taskPage = ref(1)
const taskPageSize = ref(20)
const taskTotal = ref(0)
const taskStatus = ref<string | null>(null)
const taskSourceType = ref<string | null>(null)

const statusOptions = [
  { label: '待处理', value: 'PENDING' },
  { label: '处理中', value: 'PROCESSING' },
  { label: '成功', value: 'SUCCESS' },
  { label: '失败', value: 'FAILED' },
  { label: '需认证', value: 'WAITING_AUTH' }
]

const sourceTypeOptions = [
  { label: '单笔', value: 'SINGLE' },
  { label: '批量', value: 'BATCH' }
]

const queueStatusLabelMap: Record<string, string> = {
  RUNNING: '运行中',
  PAUSED: '已暂停'
}

const taskStatusLabelMap: Record<string, string> = {
  PENDING: '待处理',
  PROCESSING: '处理中',
  SUCCESS: '成功',
  FAILED: '失败',
  WAITING_AUTH: '需认证'
}

const taskTypeLabelMap: Record<string, string> = {
  ISSUE_BLUE: '蓝票开具',
  QUERY_BLUE: '蓝票查询'
}

const sourceTypeLabelMap: Record<string, string> = {
  SINGLE: '单笔',
  BATCH: '批量'
}

function labelOf(map: Record<string, string>, value?: string | null) {
  return value ? map[value] || value : '-'
}

const totals = computed(() =>
  rows.value.reduce(
    (acc, row) => {
      acc.pending += row.pending
      acc.processing += row.processing
      acc.waitingAuth += row.waitingAuth
      return acc
    },
    { pending: 0, processing: 0, waitingAuth: 0 }
  )
)

const drawerTitle = computed(() => {
  const row = selected.value
  if (!row) return '任务明细'
  return `${row.account || row.digitalAccountId} 任务明细`
})

const statusTagType = (status: string) => {
  if (status === 'RUNNING' || status === 'SUCCESS') return 'success'
  if (status === 'PAUSED' || status === 'WAITING_AUTH') return 'warning'
  if (status === 'FAILED') return 'error'
  if (status === 'PROCESSING') return 'info'
  return 'default'
}

const columns: DataTableColumns<OpenInvoiceTaskOverviewItem> = [
  { title: '数电账号', key: 'account', minWidth: 160, render: (row) => row.account || '-' },
  { title: '数电账号ID', key: 'digitalAccountId', minWidth: 220 },
  {
    title: '队列',
    key: 'status',
    width: 110,
    render: (row) =>
      h(
        NTag,
        { type: statusTagType(row.status), size: 'small' },
        { default: () => labelOf(queueStatusLabelMap, row.status) }
      )
  },
  { title: '待处理', key: 'pending', width: 90 },
  { title: '处理中', key: 'processing', width: 90 },
  {
    title: '需认证',
    key: 'waitingAuth',
    width: 90,
    render: (row) =>
      h(
        NTag,
        { type: row.waitingAuth > 0 ? 'warning' : 'default', size: 'small' },
        { default: () => row.waitingAuth }
      )
  },
  { title: '成功', key: 'success', width: 90 },
  {
    title: '失败',
    key: 'failed',
    width: 90,
    render: (row) =>
      h(
        NTag,
        { type: row.failed > 0 ? 'error' : 'default', size: 'small' },
        { default: () => row.failed }
      )
  },
  { title: '总数', key: 'total', width: 90 },
  { title: '最近任务', key: 'lastCreatedAt', minWidth: 150 },
  {
    title: '操作',
    key: 'actions',
    width: 168,
    align: 'center',
    render: (row) =>
      h(
        'div',
        { class: 'action-buttons' },
        [
          h(
            NButton,
            {
              size: 'small',
              secondary: true,
              title: '查看任务详情',
              onClick: (event: MouseEvent) => {
                event.stopPropagation()
                openDrawer(row)
              }
            },
            {
              icon: () => h(NIcon, { component: ListTree }),
              default: () => '详情'
            }
          ),
          h(
            NButton,
            {
              size: 'small',
              secondary: true,
              type: row.status === 'PAUSED' ? 'success' : 'warning',
              title: row.status === 'PAUSED' ? '恢复队列' : '暂停队列',
              onClick: (event: MouseEvent) => {
                event.stopPropagation()
                row.status === 'PAUSED' ? resume(row) : pause(row)
              }
            },
            {
              icon: () => h(NIcon, { component: row.status === 'PAUSED' ? Play : Pause }),
              default: () => (row.status === 'PAUSED' ? '恢复' : '暂停')
            }
          )
        ]
      )
  }
]

function rowProps(row: OpenInvoiceTaskOverviewItem) {
  return {
    style: 'cursor: pointer;',
    onClick: () => {
      openDrawer(row)
    }
  }
}

const taskColumns: DataTableColumns<OpenInvoiceTaskItem> = [
  { title: '票号', key: 'invoiceReqSerialNo', minWidth: 170 },
  { title: '任务', key: 'taskType', width: 120, render: (row) => labelOf(taskTypeLabelMap, row.taskType) },
  { title: '来源', key: 'sourceType', width: 90, render: (row) => labelOf(sourceTypeLabelMap, row.sourceType) },
  {
    title: '状态',
    key: 'status',
    width: 110,
    render: (row) =>
      h(
        NTag,
        { type: statusTagType(row.status), size: 'small' },
        { default: () => labelOf(taskStatusLabelMap, row.status) }
      )
  },
  { title: 'PT码', key: 'ptCode', width: 90 },
  { title: '错误', key: 'errorMessage', minWidth: 260, ellipsis: { tooltip: true } },
  { title: '查询次数', key: 'pollCount', width: 90, render: (row) => `${row.pollCount}/${row.maxPollCount}` },
  { title: '重试', key: 'attemptCount', width: 90, render: (row) => `${row.attemptCount}/${row.maxAttemptCount}` },
  { title: '下次执行', key: 'nextRunAt', minWidth: 150 }
]

const taskPagination = reactive<PaginationProps>({
  page: taskPage.value,
  pageSize: taskPageSize.value,
  itemCount: taskTotal.value,
  showSizePicker: true,
  pageSizes: [10, 20, 50]
})

async function load() {
  loading.value = true
  try {
    rows.value = await openInvoiceTaskOverviewApi()
  } finally {
    loading.value = false
  }
}

async function loadTasks(page = 1) {
  if (!selected.value) return
  taskLoading.value = true
  try {
    const result = await openInvoiceTaskPageApi({
      digitalAccountId: selected.value.digitalAccountId,
      status: taskStatus.value,
      sourceType: taskSourceType.value,
      page,
      pageSize: taskPageSize.value
    })
    tasks.value = result.items
    taskPage.value = result.page
    taskTotal.value = result.total
    taskPagination.page = result.page
    taskPagination.itemCount = result.total
  } finally {
    taskLoading.value = false
  }
}

function openDrawer(row: OpenInvoiceTaskOverviewItem) {
  selected.value = row
  drawerVisible.value = true
  taskStatus.value = null
  taskSourceType.value = null
  loadTasks(1)
}

async function changeTaskPageSize(pageSize: number) {
  taskPageSize.value = pageSize
  taskPagination.pageSize = pageSize
  await loadTasks(1)
}

async function pause(row: OpenInvoiceTaskOverviewItem) {
  await pauseOpenInvoiceTaskQueueApi(row.digitalAccountId, '手动暂停')
  appMessage.success('队列已暂停')
  await load()
}

async function resume(row: OpenInvoiceTaskOverviewItem) {
  await resumeOpenInvoiceTaskQueueApi(row.digitalAccountId)
  appMessage.success('队列已恢复')
  await load()
  if (selected.value?.digitalAccountId === row.digitalAccountId) {
    await loadTasks(taskPage.value)
  }
}

onMounted(load)
</script>

<style scoped>
.queue-summary {
  display: grid;
  grid-template-columns: repeat(4, minmax(120px, 1fr));
  gap: 12px;
  padding: 0 16px 12px;
}

.metric {
  border: 1px solid var(--border-color);
  border-radius: 8px;
  padding: 12px;
  background: var(--card-color);
}

.metric span {
  display: block;
  color: var(--text-color-2);
  font-size: 12px;
}

.metric strong {
  display: block;
  margin-top: 4px;
  font-size: 22px;
  font-weight: 700;
}

.drawer-toolbar {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-bottom: 12px;
}

.task-filter {
  width: 140px;
}

.action-buttons {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: 144px;
}

@media (max-width: 720px) {
  .queue-summary {
    grid-template-columns: repeat(2, minmax(120px, 1fr));
  }
}
</style>
