<template>
  <ArtTableFullScreen>
    <div class="export-task-detail-page" id="table-full-screen">
      <ElCard shadow="never" class="art-table-card">
        <div class="detail-header">
          <ElButton @click="goBack">
            <template #icon>
              <ElIcon><ArrowLeft /></ElIcon>
            </template>
            返回
          </ElButton>
          <h2 class="detail-title">导出任务详情</h2>
          <div class="detail-actions" v-if="taskDetail && canViewDetail">
            <ElButton v-if="canDownloadTask" type="primary" @click="downloadTask">
              下载文件
            </ElButton>
            <ElButton v-if="canCancelTask" type="danger" @click="cancelTask"> 取消任务 </ElButton>
          </div>
        </div>

        <div v-if="polling.loading && !taskDetail" class="detail-loading">
          <ElIcon class="is-loading" :size="36">
            <Loading />
          </ElIcon>
          <div>加载中...</div>
        </div>
        <DetailPage
          v-if="taskDetail && canViewDetail"
          :sections="detailSections"
          :data="taskDetail"
        />
        <ElEmpty
          v-else
          :description="polling.forbidden ? '暂无权限查看该导出任务详情' : '暂无详情'"
        />
      </ElCard>
    </div>
  </ArtTableFullScreen>
</template>

<script setup lang="ts">
  import { computed, h, onMounted } from 'vue'
  import { useRoute, useRouter } from 'vue-router'
  import { ElButton, ElCard, ElEmpty, ElIcon, ElMessage, ElMessageBox, ElTag } from 'element-plus'
  import { ArrowLeft, Loading } from '@element-plus/icons-vue'
  import DetailPage from '@/components/common/DetailPage.vue'
  import type { DetailSection } from '@/components/common/DetailPage.vue'
  import { ExportTaskService } from '@/api/modules'
  import { useAuth } from '@/composables/useAuth'
  import { getExportTaskSceneConfig, getExportTaskSceneName } from '@/config/constants'
  import { formatDateTime } from '@/utils/business/format'
  import type { ExportTaskDetail } from '@/types/api'
  import { ExportTaskStatus } from '@/types/api'
  import { useAsyncTaskPolling } from '@/composables/useAsyncTaskPolling'

  defineOptions({ name: 'ExportTaskDetail' })

  const route = useRoute()
  const router = useRouter()
  const { hasAuth } = useAuth()
  const polling = useAsyncTaskPolling<ExportTaskDetail>({
    storageKey: `export-task-detail:${String(route.query.id || '')}`,
    autoRestore: false,
    fetchTask: async (taskId) => {
      const res = await ExportTaskService.getExportTaskDetail(taskId)
      if (res.code === 403) {
        const error = new Error('您没有查看该导出任务详情的权限') as Error & { status?: number }
        error.status = 403
        throw error
      }
      if (res.code !== 0 || !res.data) throw new Error(res.msg || '获取导出任务详情失败')
      return res.data
    },
    isForbidden: (error: any) => error?.status === 403 || error?.response?.status === 403
  })
  const taskDetail = polling.task

  const taskPermissions = computed(
    () => getExportTaskSceneConfig(taskDetail.value?.scene)?.permissions
  )
  const canViewDetail = computed(
    () => !!taskPermissions.value && hasAuth(taskPermissions.value.detail)
  )
  const canDownloadTask = computed(
    () =>
      canViewDetail.value &&
      taskDetail.value?.status === ExportTaskStatus.COMPLETED &&
      !!taskPermissions.value &&
      hasAuth(taskPermissions.value.download)
  )

  const getStatusTagType = (status?: ExportTaskStatus) => {
    const statusTypeMap: Record<
      ExportTaskStatus,
      'primary' | 'success' | 'warning' | 'danger' | 'info'
    > = {
      [ExportTaskStatus.PENDING]: 'info',
      [ExportTaskStatus.PROCESSING]: 'warning',
      [ExportTaskStatus.COMPLETED]: 'success',
      [ExportTaskStatus.FAILED]: 'danger',
      [ExportTaskStatus.CANCELED]: 'info'
    }

    return status ? statusTypeMap[status] : 'info'
  }

  const canCancelTask = computed(
    () =>
      canViewDetail.value &&
      [ExportTaskStatus.PENDING, ExportTaskStatus.PROCESSING].includes(
        taskDetail.value?.status as ExportTaskStatus
      ) &&
      !!taskPermissions.value &&
      hasAuth(taskPermissions.value.cancel)
  )

  const detailSections = computed((): DetailSection[] => [
    {
      title: '任务基本信息',
      fields: [
        { label: '任务编号', prop: 'task_no', formatter: (value: string) => value || '-' },
        { label: '任务ID', prop: 'task_id', formatter: (value: number) => String(value ?? '-') },
        {
          label: '导出场景',
          render: (data: ExportTaskDetail) => h(ElTag, {}, () => getExportTaskSceneName(data.scene))
        },
        {
          label: '任务状态',
          render: (data: ExportTaskDetail) =>
            h(ElTag, { type: getStatusTagType(data.status) }, () => data.status_name || '-')
        },
        { label: '导出格式', prop: 'format', formatter: (value: string) => value || '-' },
        {
          label: '取消请求',
          formatter: (_value: unknown, data: ExportTaskDetail) =>
            data.cancel_requested ? '是' : '否'
        },
        {
          label: '创建时间',
          prop: 'created_at',
          formatter: (value: string) => formatDateTime(value) || '-'
        },
        {
          label: '开始时间',
          prop: 'started_at',
          formatter: (value: string) => formatDateTime(value) || '-'
        },
        {
          label: '完成时间',
          prop: 'completed_at',
          formatter: (value: string) => formatDateTime(value) || '-'
        },
        {
          label: '更新时间',
          prop: 'updated_at',
          formatter: (value: string) => formatDateTime(value) || '-'
        },
        {
          label: '错误信息',
          prop: 'error_summary',
          fullWidth: true,
          formatter: (value: string, data: ExportTaskDetail) =>
            data.error_summary || data.error_message || value || '-'
        }
      ]
    },
    {
      title: '处理进度',
      fields: [
        { label: '进度', prop: 'progress', formatter: (value: number) => `${value ?? 0}%` },
        {
          label: '总数',
          prop: 'total_count',
          formatter: (value: number, data: ExportTaskDetail) =>
            String(value ?? data.total_rows ?? 0)
        },
        {
          label: '成功数',
          prop: 'success_count',
          formatter: (value: number) => String(value ?? 0)
        },
        {
          label: '失败数',
          prop: 'failed_count',
          formatter: (value: number) => String(value ?? 0)
        },
        { label: '总行数', prop: 'total_rows', formatter: (value: number) => String(value ?? 0) },
        {
          label: '已处理行数',
          prop: 'processed_rows',
          formatter: (value: number) => String(value ?? 0)
        },
        {
          label: '分片进度',
          formatter: (_value: unknown, data: ExportTaskDetail) =>
            `${data.success_shards ?? 0}/${data.total_shards ?? 0}`
        },
        {
          label: '失败分片',
          prop: 'failed_shards',
          formatter: (value: number) => String(value ?? 0)
        }
      ]
    },
    {
      title: '文件信息',
      fields: [
        {
          label: '文件Key',
          prop: 'file_key',
          fullWidth: true,
          formatter: (value: string) => value || '-'
        },
        {
          label: '下载地址',
          fullWidth: true,
          render: (data: ExportTaskDetail) => {
            if (!data.download_url) return h('span', '-')
            if (!canDownloadTask.value) return h('span', '-')
            return h(
              ElButton,
              {
                type: 'primary',
                link: true,
                onClick: () => downloadTask()
              },
              () => '打开下载地址'
            )
          }
        },
        {
          label: '下载过期时间',
          prop: 'download_expires_at',
          formatter: (value: string) => formatDateTime(value) || '-'
        }
      ]
    }
  ])

  const goBack = () => {
    router.back()
  }

  const getTaskId = () => Number(route.query.id)

  const loadTaskDetail = async () => {
    const taskId = getTaskId()
    if (!taskId) {
      ElMessage.error('缺少任务ID参数')
      goBack()
      return
    }
    await polling.start(taskId)
    if (polling.error.value) ElMessage.error(polling.error.value)
    if (polling.forbidden.value) ElMessage.warning('您没有查看该导出任务详情的权限')
  }

  const downloadTask = () => {
    if (!canDownloadTask.value) {
      ElMessage.warning('您没有下载该导出任务的权限')
      return
    }

    if (!taskDetail.value?.download_url) {
      ElMessage.warning('当前任务暂无可用下载地址')
      return
    }

    window.open(taskDetail.value.download_url, '_blank')
  }

  const cancelTask = () => {
    if (!taskDetail.value) return
    if (!canCancelTask.value) {
      ElMessage.warning('您没有取消该导出任务的权限')
      return
    }

    ElMessageBox.confirm(`确定取消导出任务 ${taskDetail.value.task_no} 吗？`, '取消确认', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }).then(async () => {
      try {
        const res = await ExportTaskService.cancelExportTask(
          taskDetail.value!.task_id ?? taskDetail.value!.id
        )
        if (res.code === 0) {
          ElMessage.success(res.data?.message || '任务取消成功')
          polling.retry()
        } else {
          ElMessage.error(res.msg || '取消导出任务失败')
        }
      } catch (error) {
        console.error('取消导出任务失败:', error)
        ElMessage.error('取消导出任务失败')
      }
    })
  }

  onMounted(() => {
    loadTaskDetail()
  })
</script>

<style scoped lang="scss">
  .export-task-detail-page {
    .detail-header {
      display: flex;
      gap: 16px;
      align-items: center;
      padding-bottom: 16px;

      .detail-title {
        margin: 0;
        font-size: 20px;
        font-weight: 600;
        color: var(--el-text-color-primary);
      }

      .detail-actions {
        display: flex;
        gap: 10px;
        margin-left: auto;
      }
    }

    .detail-loading {
      display: flex;
      flex-direction: column;
      gap: 12px;
      align-items: center;
      justify-content: center;
      min-height: 220px;
      color: var(--el-text-color-secondary);
    }
  }
</style>
