<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ElMessage, ElLoading } from 'element-plus'
import type { UploadProps, UploadInstance } from 'element-plus'
import {
  downloadLicense,
  uploadLicense,
  getLicenseTaskStatus,
  getProject,
  saveProject,
  downloadDeployView,
  uploadDeployView,
  downloadSelfCheck,
  uploadSelfCheck,
  downloadBlob,
} from '@/api/service-manage'
import type { SaveProjectRequest } from '@/types/service-manage'

// ============================================================
// 表单数据
// ============================================================

const projectForm = ref<SaveProjectRequest>({
  salesPeople: '',
  deployer: '',
  orderTime: '',
  serverPassword: '',
  projectOverview: '',
})

const projectLoaded = ref(false)  // 是否已从后端加载过项目信息

// ============================================================
// 上传引用
// ============================================================

const authUploadRef = ref<UploadInstance>()
const deployUploadRef = ref<UploadInstance>()
const checkUploadRef = ref<UploadInstance>()

// ============================================================
// 辅助：睡眠
// ============================================================

function sleep(ms: number) {
  return new Promise(resolve => setTimeout(resolve, ms))
}

// ============================================================
// 下载工具
// ============================================================

async function handleDownload(apiFn: () => Promise<Blob>, filename: string, label: string) {
  const loading = ElLoading.service({ text: `正在生成${label}...` })
  try {
    const blob = await apiFn()
    downloadBlob(blob, filename)
    ElMessage.success(`${label}下载成功`)
  } catch (e: any) {
    ElMessage.error(`下载失败：${e?.message || '未知错误'}`)
  } finally {
    loading.close()
  }
}

// ============================================================
// Step 1: 申请服务授权
// ============================================================

// 下载激活文件
async function handleDownloadActivation() {
  await handleDownload(
    downloadLicense,
    'licences.zip',
    '激活文件',
  )
}

// 上传授权文件
const handleAuthUpload: UploadProps['onChange'] = async (uploadFile) => {
  if (!uploadFile.raw) {
    ElMessage.warning('请选择文件')
    return false
  }

  const loading = ElLoading.service({ text: '正在上传授权文件...' })
  try {
    const res = await uploadLicense(uploadFile.raw)
    if (res.success) {
      ElMessage.success('授权文件上传成功，正在处理...')
      // 轮询授权任务状态
      await pollLicenseTask(res.taskId)
    } else {
      ElMessage.error(res.message || '上传失败')
    }
  } catch (e: any) {
    ElMessage.error(`上传失败：${e?.message || '未知错误'}`)
  } finally {
    loading.close()
  }
  return false
}

// 轮询授权任务状态（5 分钟超时，2s 间隔）
async function pollLicenseTask(taskId: string) {
  const deadline = Date.now() + 5 * 60 * 1000
  while (Date.now() < deadline) {
    await sleep(2000)
    try {
      const res = await getLicenseTaskStatus(taskId)
      if (res.status === 'completed') {
        ElMessage.success('🎉 授权处理完成！')
        return
      }
      if (res.status === 'failed') {
        ElMessage.error(`授权失败：${res.message || '未知错误'}`)
        return
      }
      // 仍在处理中，继续轮询
    } catch {
      // 轮询失败继续尝试
    }
  }
  ElMessage.warning('授权处理超时，请稍后刷新查看状态')
}

// ============================================================
// Step 2: 项目信息
// ============================================================

// 加载已有项目信息
onMounted(async () => {
  try {
    const res = await getProject()
    if (res.success && res.project) {
      const p = res.project
      projectForm.value = {
        salesPeople: p.salesPeople || '',
        deployer: p.deployer || '',
        orderTime: p.orderTime || '',
        serverPassword: '',
        projectOverview: p.projectOverview || '',
      }
      projectLoaded.value = true
    }
  } catch {
    // 首次使用无项目信息
  }
})

// 保存项目信息
async function handleSaveProject() {
  // 表单校验
  if (!projectForm.value.salesPeople.trim()) {
    ElMessage.warning('请输入项目销售')
    return
  }
  if (!projectForm.value.deployer.trim()) {
    ElMessage.warning('请输入部署人员')
    return
  }
  if (!projectForm.value.orderTime) {
    ElMessage.warning('请选择下单时间')
    return
  }
  if (!projectForm.value.serverPassword) {
    ElMessage.warning('请输入服务器密码')
    return
  }
  if (!projectForm.value.projectOverview.trim()) {
    ElMessage.warning('请输入项目概述')
    return
  }

  const loading = ElLoading.service({ text: '正在保存项目信息...' })
  try {
    const res = await saveProject(projectForm.value)
    if (res.success) {
      ElMessage.success('✅ 项目信息保存成功')
    }
  } catch (e: any) {
    ElMessage.error(`保存失败：${e?.message || '未知错误'}`)
  } finally {
    loading.close()
  }
}

// ============================================================
// Step 3: 部署视图
// ============================================================

async function handleDownloadDeployView() {
  await handleDownload(
    downloadDeployView,
    `deploymentView_${new Date().toISOString().slice(0, 10)}.xlsx`,
    '部署视图',
  )
}

const handleDeployUpload: UploadProps['onChange'] = async (uploadFile) => {
  if (!uploadFile.raw) {
    ElMessage.warning('请选择文件')
    return false
  }
  const loading = ElLoading.service({ text: '正在上传部署视图...' })
  try {
    const res = await uploadDeployView(uploadFile.raw)
    if (res.success) {
      ElMessage.success('✅ 部署视图上传成功')
    } else {
      ElMessage.error(res.message || '上传失败')
    }
  } catch (e: any) {
    ElMessage.error(`上传失败：${e?.message || '未知错误'}`)
  } finally {
    loading.close()
  }
  return false
}

// ============================================================
// Step 4: 自检文档
// ============================================================

async function handleDownloadSelfCheck() {
  await handleDownload(
    downloadSelfCheck,
    `checkList_${new Date().toISOString().slice(0, 10)}.xlsx`,
    '自检文档',
  )
}

const handleCheckUpload: UploadProps['onChange'] = async (uploadFile) => {
  if (!uploadFile.raw) {
    ElMessage.warning('请选择文件')
    return false
  }
  const loading = ElLoading.service({ text: '正在上传自检文档...' })
  try {
    const res = await uploadSelfCheck(uploadFile.raw)
    if (res.success) {
      ElMessage.success('✅ 自检文档上传成功')
    } else {
      ElMessage.error(res.message || '上传失败')
    }
  } catch (e: any) {
    ElMessage.error(`上传失败：${e?.message || '未知错误'}`)
  } finally {
    loading.close()
  }
  return false
}
</script>

<template>
  <div class="page-authorization">
    <div class="section-head">
      <h1 class="section-title">🔑 服务授权</h1>
    </div>

    <div class="steps-container">
      <!-- Step 1: 申请服务授权 -->
      <el-card class="step-card">
        <div class="step-number">1</div>
        <div class="step-title">申请服务授权</div>
        <div class="step-actions">
          <el-button type="primary" @click="handleDownloadActivation">📥 下载激活文件</el-button>
        </div>
        <el-upload
          ref="authUploadRef"
          class="upload-area"
          drag
          :auto-upload="false"
          :show-file-list="false"
          accept=".zip,.lic,.key,.dat"
          :on-change="handleAuthUpload"
        >
          <div class="upload-icon">📁</div>
          <div class="upload-text">点击或拖拽上传授权文件</div>
          <div class="upload-hint">支持 .zip / .lic / .key / .dat 格式，文件大小不超过 2048M</div>
        </el-upload>
        <div class="step-desc">
          下载激活文件后发送给厂商获取授权，收到授权文件后上传即可完成授权申请。
        </div>
      </el-card>

      <!-- Step 2: 填写项目信息 -->
      <el-card class="step-card">
        <div class="step-number">2</div>
        <div class="step-title">填写项目信息</div>
        <el-form :model="projectForm" label-position="top">
          <el-form-item label="项目销售" required>
            <el-input v-model="projectForm.salesPeople" placeholder="请输入项目的销售" />
          </el-form-item>
          <el-form-item label="部署人员" required>
            <el-input v-model="projectForm.deployer" placeholder="请输入项目部署或更新人员" />
          </el-form-item>
          <el-form-item label="下单时间" required>
            <el-date-picker
              v-model="projectForm.orderTime"
              type="datetime"
              placeholder="选择日期时间"
              value-format="YYYY-MM-DD HH:mm:ss"
              style="width: 100%;"
            />
          </el-form-item>
          <el-form-item label="服务器密码" required>
            <el-input
              v-model="projectForm.serverPassword"
              type="password"
              placeholder="请输入服务器密码"
              show-password
            />
          </el-form-item>
          <el-form-item label="项目概述" required>
            <el-input
              v-model="projectForm.projectOverview"
              type="textarea"
              :rows="3"
              placeholder="请输入项目概述"
            />
          </el-form-item>
          <el-button type="primary" @click="handleSaveProject">💾 保存</el-button>
        </el-form>
      </el-card>

      <!-- Step 3: 部署视图 -->
      <el-card class="step-card">
        <div class="step-number">3</div>
        <div class="step-title">填写并提交部署视图</div>
        <div class="step-actions">
          <el-button type="primary" @click="handleDownloadDeployView">📥 下载部署视图</el-button>
        </div>
        <el-upload
          ref="deployUploadRef"
          class="upload-area"
          drag
          :auto-upload="false"
          :show-file-list="false"
          accept=".xlsx,.xls,.pdf"
          :on-change="handleDeployUpload"
        >
          <div class="upload-icon">📄</div>
          <div class="upload-text">点击上传已填写的部署视图</div>
          <div class="upload-hint">支持 .xlsx / .xls / .pdf 格式</div>
        </el-upload>
        <div class="step-desc">
          下载部署视图模板，填写后上传提交。
        </div>
      </el-card>

      <!-- Step 4: 自检文档 -->
      <el-card class="step-card">
        <div class="step-number">4</div>
        <div class="step-title">填写并提交自检文档</div>
        <div class="step-actions">
          <el-button type="primary" @click="handleDownloadSelfCheck">📥 下载自检文档</el-button>
        </div>
        <el-upload
          ref="checkUploadRef"
          class="upload-area"
          drag
          :auto-upload="false"
          :show-file-list="false"
          accept=".docx,.doc,.pdf"
          :on-change="handleCheckUpload"
        >
          <div class="upload-icon">📋</div>
          <div class="upload-text">点击上传已填写的自检文档</div>
          <div class="upload-hint">支持 .docx / .doc / .pdf 格式</div>
        </el-upload>
        <div class="step-desc">
          下载自检文档模板，填写后上传提交。
        </div>
      </el-card>
    </div>
  </div>
</template>

<style scoped lang="scss">
.page-authorization {
  padding: 0 0 40px;
}

.section-head {
  margin-bottom: 20px;
}

.section-title {
  font-size: 20px;
  font-weight: 700;
  color: $gray-900;
}

.steps-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
}

.step-card {
  position: relative;
  border-radius: 12px;

  :deep(.el-card__body) {
    padding: 24px;
  }
}

.step-number {
  position: absolute;
  top: -12px;
  left: 20px;
  background: $primary;
  color: #fff;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 14px;
}

.step-title {
  font-size: 16px;
  font-weight: 700;
  color: $gray-900;
  margin-bottom: 16px;
  padding-top: 8px;
}

.step-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 12px;
}

.step-desc {
  font-size: 13px;
  color: $gray-500;
  line-height: 1.6;
  margin-top: 12px;
}

.upload-area {
  border: 2px dashed $gray-300;
  border-radius: 8px;
  padding: 20px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.2s, background 0.2s;
  width: 100%;

  &:hover {
    border-color: $primary;
    background: #eff6ff;
  }

  :deep(.el-upload) {
    width: 100%;
  }

  :deep(.el-upload-dragger) {
    border: none;
    background: transparent;
    padding: 0;
  }
}

.upload-icon {
  font-size: 24px;
  margin-bottom: 8px;
}

.upload-text {
  font-size: 14px;
  color: $gray-600;
}

.upload-hint {
  font-size: 12px;
  color: $gray-400;
  margin-top: 4px;
}

@media screen and (max-width: 768px) {
  .steps-container {
    grid-template-columns: 1fr;
  }

  .step-card {
    :deep(.el-card__body) {
      padding: 20px 16px;
    }
  }
}
</style>