<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Delete, Refresh } from '@element-plus/icons-vue'
import type { TagProps, UploadRequestOptions, UploadFile, UploadRawFile } from 'element-plus'
import PageCard from '@/components/PageCard.vue'
import {
  getDataConvertTasks,
  createDataConvertTask,
  uploadSourceFiles,
  deleteDataConvertTask,
  type DataConvertTask,
} from '@/api/modules/data-convert'

const loading = ref(false)
const tasks = ref<DataConvertTask[]>([])
const showCreate = ref(false)
const form = ref({ name: '', outputName: 'converted-data' })
const fileList = ref<UploadFile[]>([])
const creating = ref(false)

async function load() {
  loading.value = true
  try {
    const res = await getDataConvertTasks()
    tasks.value = res.items || []
  } finally {
    loading.value = false
  }
}

// 文件上传前的校验（仅校验文件格式）
function beforeUpload(file: UploadRawFile) {
  // 检查文件类型
  const isJson = file.name.endsWith('.json') || file.type === 'application/json'
  if (!isJson) {
    ElMessage.error('只能上传 .json 格式的文件')
    return false
  }
  return true
}

// 手动点击"创建并上传"
async function submitCreate() {
  // 校验任务名称
  if (!form.value.name || !form.value.name.trim()) {
    ElMessage.warning('请填写任务名称')
    return
  }
  // 检查名称是否重复
  const exists = tasks.value.some((t) => t.name === form.value.name.trim())
  if (exists) {
    ElMessage.error(`数据集管理中已存在名为「${form.value.name}」的任务，请换一个名称`)
    return
  }
  // 检查是否选择了文件
  if (!fileList.value || fileList.value.length === 0) {
    ElMessage.warning('请选择要上传的 JSON 文件')
    return
  }

  creating.value = true
  try {
    // 1. 创建转换任务
    const task = await createDataConvertTask({
      name: form.value.name.trim(),
      output_filename: form.value.outputName.trim() + '.jsonl',
    })

    // 2. 获取任务 ID
    const taskId = (task as any)?.id || task?.id || (task as any)?.data?.id
    if (!taskId) {
      throw new Error('创建任务失败，服务端未返回任务 ID')
    }

    // 3. 上传文件到刚创建的任务
    const file = fileList.value[0].raw
    if (!file) {
      throw new Error('文件信息丢失，请重新选择文件')
    }

    const res = await uploadSourceFiles(taskId, [file])
    const data = (res as any)?.data || res

    if (data?.auto_converted) {
      ElMessage.success(
        `创建成功！文件已上传并自动转换完成（输入 ${data.input_count} 条 / 输出 ${data.output_count} 条），结果已导入数据集`,
      )
    } else if (data?.error) {
      ElMessage.error(`文件上传成功但转换失败：${data.error}`)
    } else {
      ElMessage.warning('文件已上传，等待后台转换处理...')
    }

    // 关闭弹窗并刷新列表
    showCreate.value = false
    resetForm()
    load()
  } catch (e: any) {
    // 根据错误类型给出更清晰的提示
    const msg = e?.message || e?.toString() || '未知错误'
    if (msg.includes('409') || msg.includes('conflict') || msg.includes('已存在') || msg.includes('duplicate')) {
      ElMessage.error(`数据集管理中已存在名为「${form.value.name}」的任务，请换一个名称`)
    } else if (msg.includes('400')) {
      ElMessage.error(`参数错误：${msg}`)
    } else if (msg.includes('403') || msg.includes('权限')) {
      ElMessage.error(`没有权限执行此操作：${msg}`)
    } else {
      ElMessage.error(`操作失败：${msg}`)
    }
  } finally {
    creating.value = false
  }
}

// 自定义上传（表格中的上传按钮仍使用此方法）
async function customUpload(options: UploadRequestOptions) {
  const taskId = options.data?.taskId as string
  if (!taskId) {
    ElMessage.error('任务 ID 缺失')
    return
  }
  try {
    const res = await uploadSourceFiles(taskId, [options.file])
    const data = (res as any)?.data || res
    if (data?.auto_converted) {
      ElMessage.success(
        `上传并自动转换完成，输入 ${data.input_count} / 输出 ${data.output_count}，已自动导入数据集`,
      )
    } else {
      ElMessage.warning('上传完成，但转换失败：' + (data?.error || '未知错误'))
    }
    load()
  } catch (e: any) {
    ElMessage.error('上传失败：' + (e?.message || '未知错误'))
  }
}

// 重置表单
function resetForm() {
  form.value = { name: '', outputName: 'converted-data' }
  fileList.value = []
}

// 移除已选文件
function handleRemoveFile(file: UploadFile) {
  fileList.value = fileList.value.filter((f) => f.uid !== file.uid)
}

async function handleDelete(task: DataConvertTask) {
  try {
    await ElMessageBox.confirm(
      `确定要删除任务「${task.name}」吗？`,
      '删除确认',
      { confirmButtonText: '确定删除', cancelButtonText: '取消', type: 'warning' },
    )
  } catch {
    return
  }
  await deleteDataConvertTask(task.id)
  ElMessage.success('任务已删除')
  load()
}

function statusTag(status: string) {
  const map: Record<string, { type: TagProps['type']; label: string }> = {
    pending: { type: 'info', label: '待上传' },
    uploaded: { type: 'warning', label: '已上传' },
    running: { type: 'warning', label: '转换中' },
    completed: { type: 'success', label: '已完成' },
    failed: { type: 'danger', label: '失败' },
  }
  return map[status] || { type: 'info', label: status }
}

onMounted(load)
</script>

<template>
  <PageCard
    class="data-convert-page"
    title="数据类型转换"
    subtitle="将 JSON 文件转换为 JSONL 格式，转换结果自动导入到数据集管理"
  >
    <div class="toolbar">
      <el-button type="primary" :icon="Plus" @click="showCreate = true">新建转换任务</el-button>
      <el-button :icon="Refresh" @click="load">刷新</el-button>
    </div>

    <el-table :data="tasks" v-loading="loading" border stripe>
      <el-table-column prop="name" label="任务名称" min-width="140" />
      <el-table-column label="状态" min-width="100">
        <template #default="{ row }">
          <el-tag :type="statusTag(row.status).type">{{ statusTag(row.status).label }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="数据量" min-width="120">
        <template #default="{ row }">
          {{ row.output_count }} 条
        </template>
      </el-table-column>
      <el-table-column prop="output_filename" label="输出文件名" min-width="160" />
      <el-table-column prop="create_time" label="创建时间" min-width="180" />
      <el-table-column label="操作" width="240" fixed="right">
        <template #default="{ row }">
          <el-upload
            v-if="row.status === 'pending'"
            :auto-upload="true"
            :show-file-list="false"
            accept=".json"
            :http-request="customUpload"
            :data="{ taskId: row.id }"
            style="display: inline-block; margin-right: 8px"
          >
            <el-button link type="primary">上传文件</el-button>
          </el-upload>
          <el-button link type="danger" :icon="Delete" @click="handleDelete(row as DataConvertTask)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 新建任务弹窗（一步到位：填写信息 + 上传文件） -->
    <el-dialog v-model="showCreate" title="新建转换任务" width="520px" :close-on-click-modal="false">
      <el-form label-width="100px">
        <el-form-item label="任务名称" required>
          <el-input v-model="form.name" placeholder="请输入任务名称" clearable />
        </el-form-item>
        <el-form-item label="输出文件名">
          <el-input v-model="form.outputName" placeholder="converted-data" clearable>
            <template #append>.jsonl</template>
          </el-input>
        </el-form-item>
        <el-form-item label="上传文件" required>
          <el-upload
            ref="uploadRef"
            v-model:file-list="fileList"
            :auto-upload="false"
            :limit="1"
            accept=".json"
            :before-upload="beforeUpload"
            :on-remove="handleRemoveFile"
            :disabled="creating"
            drag
          >
            <el-icon class="el-icon--upload"><Plus /></el-icon>
            <div class="el-upload__text">将 JSON 文件拖到此处，或<em>点击上传</em></div>
            <template #tip>
              <div class="el-upload__tip">仅支持 .json 格式文件，点击"创建并上传"按钮后自动创建任务并上传文件</div>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showCreate = false" :disabled="creating">取消</el-button>
        <el-button type="primary" :loading="creating" :disabled="!form.name || fileList.length === 0" @click="submitCreate">
          {{ creating ? '处理中...' : '创建并上传' }}
        </el-button>
      </template>
    </el-dialog>
  </PageCard>
</template>

<style scoped lang="scss">
.toolbar {
  display: flex;
  gap: 10px;
  margin-bottom: 16px;
}
:deep(.el-upload-dragger) {
  width: 100%;
  .el-upload__text {
    padding: 20px 0;
  }
}
</style>
