<template>
  <div class="ota-upgrade">
    <!-- 页面标题 -->
    <div class="page-header">
      <h2 class="page-title">OTA升级</h2>
    </div>

    <!-- 当前状态卡片 -->
    <a-card :bordered="false" class="status-card">
      <div class="status-header">
        <h3>当前状态</h3>
        <a-button @click="refreshStatus" :loading="loading">
          <template #icon><reload-outlined /></template>
          刷新
        </a-button>
      </div>

      <a-descriptions :column="3" bordered size="small">
        <a-descriptions-item label="升级状态">
          <a-tag :color="statusColor">{{ statusText }}</a-tag>
        </a-descriptions-item>
        <a-descriptions-item label="当前固件版本">
          {{ currentFirmware || '-' }}
        </a-descriptions-item>
        <a-descriptions-item label="目标固件版本">
          {{ otaStatus.target_version || '-' }}
        </a-descriptions-item>
        <a-descriptions-item label="升级进度">
          <a-progress
            :percent="otaStatus.progress"
            :status="progressStatus"
            :stroke-color="progressColor"
            style="width: 150px"
          />
        </a-descriptions-item>
        <a-descriptions-item label="最后更新">
          {{ otaStatus.last_update || '-' }}
        </a-descriptions-item>
        <a-descriptions-item label="错误信息">
          <span v-if="otaStatus.error_message" class="error-text">
            {{ otaStatus.error_message }}
          </span>
          <span v-else class="text-muted">-</span>
        </a-descriptions-item>
      </a-descriptions>
    </a-card>

    <!-- 升级配置卡片 -->
    <a-card :bordered="false" class="config-card">
      <h3>发起OTA升级</h3>

      <a-form
        :model="form"
        :rules="rules"
        layout="vertical"
        @finish="handleUpgrade"
      >
        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item label="固件URL" name="firmware_url">
              <a-input
                v-model:value="form.firmware_url"
                placeholder="http://example.com/firmware.tar.gz"
                :disabled="upgrading"
              >
                <template #suffix>
                  <a-button size="small" type="link" @click="detectFirmware" :loading="detecting">检测</a-button>
                </template>
              </a-input>
            </a-form-item>
          </a-col>
          <a-col :span="6">
            <a-form-item label="目标版本" name="firmware_version">
              <a-input
                v-model:value="form.firmware_version"
                placeholder="v1.2.0"
                :disabled="upgrading"
              />
            </a-form-item>
          </a-col>
          <a-col :span="6">
            <a-form-item label="文件大小(字节)" name="file_size">
              <a-input-number
                v-model:value="form.file_size"
                :min="0"
                style="width: 100%"
                placeholder="1048576"
                :disabled="upgrading"
              />
            </a-form-item>
          </a-col>
        </a-row>

        <a-row :gutter="16">
          <a-col :span="8">
            <a-form-item label="校验和" name="checksum">
              <a-input
                v-model:value="form.checksum"
                placeholder="MD5/SHA256值"
                :disabled="upgrading"
              />
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item label="校验和类型" name="checksum_type">
              <a-select v-model:value="form.checksum_type" :disabled="upgrading">
                <a-select-option value="MD5">MD5</a-select-option>
                <a-select-option value="SHA256">SHA256</a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item label="强制升级" name="force_upgrade">
              <a-switch v-model:checked="form.force_upgrade" :disabled="upgrading" />
              <span class="switch-hint">忽略版本一致性</span>
            </a-form-item>
          </a-col>
        </a-row>

        <a-form-item>
          <a-button
            type="primary"
            html-type="submit"
            :loading="upgrading"
            :disabled="!canUpgrade"
          >
            <template #icon><cloud-upload-outlined /></template>
            开始升级
          </a-button>
          <a-button
            v-if="otaStatus.status !== 'IDLE' && otaStatus.status !== 'SUCCESS' && otaStatus.status !== 'FAILED'"
            @click="cancelUpgrade"
            danger
            style="margin-left: 12px"
          >
            取消升级
          </a-button>
        </a-form-item>
      </a-form>
    </a-card>

    <!-- 升级说明 -->
    <a-card :bordered="false" class="help-card">
      <h3>升级说明</h3>
      <ul>
        <li><strong>固件URL:</strong> 固件文件的完整下载链接</li>
        <li><strong>目标版本:</strong> 升级后的固件版本号（如v1.2.0）</li>
        <li><strong>文件大小:</strong> 固件文件的字节数</li>
        <li><strong>校验和:</strong> 固件文件的MD5或SHA256值（用于验证完整性）</li>
        <li><strong>强制升级:</strong> 即使当前版本与目标版本相同也执行升级</li>
      </ul>

      <a-divider />

      <h4>OTA状态说明</h4>
      <a-descriptions :column="3" bordered size="small">
        <a-descriptions-item label="IDLE">空闲，未进行升级</a-descriptions-item>
        <a-descriptions-item label="DOWNLOADING">正在下载固件</a-descriptions-item>
        <a-descriptions-item label="VERIFYING">正在验证校验和</a-descriptions-item>
        <a-descriptions-item label="FLASHING">正在写入固件</a-descriptions-item>
        <a-descriptions-item label="SUCCESS">升级成功</a-descriptions-item>
        <a-descriptions-item label="FAILED">升级失败</a-descriptions-item>
      </a-descriptions>

      <a-divider />

      <h4>常见错误码</h4>
      <a-descriptions :column="2" bordered size="small">
        <a-descriptions-item label="1021">已是目标版本</a-descriptions-item>
        <a-descriptions-item label="1022">校验和验证失败</a-descriptions-item>
        <a-descriptions-item label="1023">下载失败</a-descriptions-item>
        <a-descriptions-item label="1024">写入失败</a-descriptions-item>
        <a-descriptions-item label="1025">存储空间不足</a-descriptions-item>
      </a-descriptions>
    </a-card>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { message } from 'ant-design-vue'
import { ReloadOutlined, CloudUploadOutlined } from '@ant-design/icons-vue'
import apiService from '../api/apiService'

// 状态
const loading = ref(false)
const upgrading = ref(false)
const detecting = ref(false)
const pollTimer = ref(null)
const currentFirmware = ref('')

// OTA状态
const otaStatus = ref({
  status: 'IDLE',
  progress: 0,
  target_version: null,
  error_code: null,
  error_message: null,
  last_update: null
})

// 表单数据
const form = ref({
  firmware_url: '',
  firmware_version: '',
  file_size: null,
  checksum: '',
  checksum_type: 'MD5',
  force_upgrade: false
})

// 表单校验规则
const rules = {
  firmware_url: [
    { required: true, message: '请输入固件URL' },
    { type: 'url', message: '请输入有效的URL' }
  ],
  firmware_version: [
    { required: true, message: '请输入目标版本' }
  ],
  file_size: [
    { required: true, message: '请输入文件大小' },
    { type: 'number', min: 1, message: '文件大小必须大于0' }
  ],
  checksum: [
    { required: true, message: '请输入校验和' }
  ],
  checksum_type: [
    { required: true, message: '请选择校验和类型' }
  ]
}

// 计算属性
const canUpgrade = computed(() => {
  return form.value.firmware_url &&
    form.value.firmware_version &&
    form.value.file_size &&
    form.value.checksum &&
    !upgrading.value &&
    (otaStatus.value.status === 'IDLE' || otaStatus.value.status === 'SUCCESS' || otaStatus.value.status === 'FAILED')
})

const statusText = computed(() => {
  const statusMap = {
    'IDLE': '空闲',
    'DOWNLOADING': '下载中',
    'VERIFYING': '验证中',
    'FLASHING': '烧录中',
    'SUCCESS': '成功',
    'FAILED': '失败'
  }
  return statusMap[otaStatus.value.status] || otaStatus.value.status
})

const statusColor = computed(() => {
  const colorMap = {
    'IDLE': 'default',
    'DOWNLOADING': 'processing',
    'VERIFYING': 'processing',
    'FLASHING': 'processing',
    'SUCCESS': 'success',
    'FAILED': 'error'
  }
  return colorMap[otaStatus.value.status] || 'default'
})

const progressStatus = computed(() => {
  if (otaStatus.value.status === 'FAILED') return 'exception'
  if (otaStatus.value.status === 'SUCCESS') return 'success'
  if (otaStatus.value.progress >= 100) return 'success'
  return 'normal'
})

const progressColor = computed(() => {
  if (otaStatus.value.status === 'FAILED') return '#ff4d4f'
  if (otaStatus.value.status === 'SUCCESS') return '#52c41a'
  return '#1890ff'
})

// 检测固件信息
async function detectFirmware() {
  if (!form.value.firmware_url) {
    message.warning('请先输入固件URL')
    return
  }
  detecting.value = true
  try {
    const res = await apiService.dtu.detectFirmware(form.value.firmware_url)
    if (res.data.success) {
      const d = res.data.data
      form.value.firmware_version = d.firmware_version
      form.value.file_size = d.file_size
      form.value.checksum = d.checksum
      form.value.checksum_type = d.checksum_type
      message.success('已自动获取固件信息')
    } else {
      message.error(res.data.message || '检测失败')
    }
  } catch (e) {
    message.error('检测失败: ' + (e.response?.data?.message || e.message))
  } finally {
    detecting.value = false
  }
}

// 获取OTA状态
async function fetchOtaStatus() {
  try {
    const res = await apiService.dtu.getOtaStatus()
    if (res.data.success) {
      const d = res.data.data
      otaStatus.value = {
        status: d.ota_status,
        progress: d.ota_progress || 0,
        target_version: d.target_version,
        error_code: d.error_code,
        error_message: d.error_message,
        last_update: d.last_update
      }
      if (d.current_firmware) currentFirmware.value = d.current_firmware
    }
  } catch (e) {
    console.error('fetch ota status error:', e)
  }
}

// 获取DTU状态（包含固件版本）
async function fetchDtuStatus() {
  try {
    const res = await apiService.dtu.getStatus()
    if (res.data.success && res.data.status) {
      currentFirmware.value = res.data.status.firmware_version || ''
    }
  } catch (e) {
    console.error('fetch dtu status error:', e)
  }
}

// 刷新状态
async function refreshStatus() {
  loading.value = true
  try {
    await Promise.all([fetchOtaStatus(), fetchDtuStatus()])
  } finally {
    loading.value = false
  }
}

// 发起OTA升级
async function handleUpgrade() {
  upgrading.value = true
  try {
    const res = await apiService.dtu.triggerOtaUpgrade({
      firmware_url: form.value.firmware_url,
      firmware_version: form.value.firmware_version,
      file_size: form.value.file_size,
      checksum: form.value.checksum,
      checksum_type: form.value.checksum_type,
      force_upgrade: form.value.force_upgrade
    })

    if (res.data.success) {
      message.success('OTA升级已发起')
      // 立即刷新状态
      await fetchOtaStatus()
    } else {
      message.error(res.data.message || '升级发起失败')
    }
  } catch (e) {
    console.error('ota upgrade error:', e)
    message.error('升级发起失败')
  } finally {
    upgrading.value = false
  }
}

// 取消升级（通过发送取消命令）
async function cancelUpgrade() {
  try {
    await apiService.dtu.sendControl({ command: 'OTA_CANCEL' })
    message.info('取消命令已发送')
  } catch (e) {
    console.error('cancel upgrade error:', e)
    message.error('取消失败')
  }
}

// 生命周期
onMounted(async () => {
  await refreshStatus()
  // 每3秒轮询OTA状态
  pollTimer.value = setInterval(fetchOtaStatus, 3000)
})

onUnmounted(() => {
  if (pollTimer.value) clearInterval(pollTimer.value)
})
</script>

<style scoped>
.ota-upgrade {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.page-header {
  margin-bottom: 8px;
}

.page-title {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  color: #333;
}

.status-card {
  flex-shrink: 0;
}

.status-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.status-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
}

.error-text {
  color: #ff4d4f;
}

.text-muted {
  color: #999;
}

.config-card h3 {
  margin: 0 0 16px 0;
  font-size: 16px;
  font-weight: 500;
}

.switch-hint {
  margin-left: 8px;
  color: #666;
  font-size: 12px;
}

.help-card h3 {
  margin: 0 0 16px 0;
  font-size: 16px;
  font-weight: 500;
}

.help-card h4 {
  margin: 12px 0 8px 0;
  font-size: 14px;
  font-weight: 500;
}

.help-card ul {
  margin: 0;
  padding-left: 20px;
}

.help-card li {
  margin-bottom: 8px;
  color: #666;
}

@media (max-width: 768px) {
  .config-card :deep(.ant-row > .ant-col) {
    margin-bottom: 0;
  }
}
</style>