<template>
  <div class="recycle-bin-manage">
    <div class="toolbar">
      <el-input v-model="keyword" placeholder="按虚拟机名称搜索" style="width: 200px" size="small" clearable
        @clear="loadList" @keyup.enter="loadList" />
      <el-select v-model="filterStatus" placeholder="按状态过滤" style="width: 140px" size="small" clearable
        @change="() => { currentPage = 1; loadList() }">
        <el-option v-for="s in statusOptions" :key="s.value" :label="s.label" :value="s.value" />
      </el-select>
      <el-button size="small" :icon="Search" @click="loadList">搜索</el-button>
      <el-button size="small" :icon="Refresh" @click="loadList" :loading="loading">刷新</el-button>
      <el-dropdown trigger="click" @command="handleClean" style="margin-left: auto">
        <el-button size="small" type="danger">
          清空回收站<el-icon class="el-icon--right"><ArrowDown /></el-icon>
        </el-button>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item command="expired">清理已到期</el-dropdown-item>
            <el-dropdown-item command="all">清空全部</el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
    </div>

    <el-table :data="list" v-loading="loading" stripe size="small" style="width: 100%">
      <el-table-column prop="id" label="ID" width="60" />
      <el-table-column prop="vm_name" label="虚拟机名称" min-width="140" show-overflow-tooltip />
      <el-table-column prop="vm_id" label="原虚拟机ID" width="100" />
      <el-table-column label="状态" width="100">
        <template #default="{ row }">
          <el-tag :type="statusTagType(row.status)" size="small">{{ statusLabel(row.status) }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="任务ID" width="160">
        <template #default="{ row }">
          <span class="mono-text">{{ row.task_id || '-' }}</span>
        </template>
      </el-table-column>
      <el-table-column label="到期时间" width="170">
        <template #default="{ row }">
          <span :style="isExpired(row.expire_at) ? 'color: #f56c6c' : ''">{{ formatTs(row.expire_at) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="创建时间" width="170">
        <template #default="{ row }">{{ formatTs(row.created_at) }}</template>
      </el-table-column>
      <el-table-column label="更新时间" width="170">
        <template #default="{ row }">{{ formatTs(row.updated_at) }}</template>
      </el-table-column>
      <el-table-column label="操作" width="200" fixed="right">
        <template #default="{ row }">
          <el-button link type="primary" size="small" @click="handleDetail(row)">详情</el-button>
          <el-button link type="success" size="small" @click="handleRestore(row)"
            :disabled="row.status !== 'archived'">恢复</el-button>
          <el-button link type="danger" size="small" @click="handleDelete(row)"
            :disabled="row.status === 'restoring' || row.status === 'purging'">永久删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-empty v-if="!list.length && !loading" description="回收站为空" :image-size="60" />
    <div class="pagination-wrapper" v-if="total > 0">
      <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize"
        :page-sizes="[10, 20, 50]" :total="total" layout="total, sizes, prev, pager, next"
        @size-change="s => { pageSize = s; currentPage = 1; loadList() }"
        @current-change="p => { currentPage = p; loadList() }" />
    </div>

    <!-- 详情弹窗 -->
    <el-dialog v-model="detailVisible" title="回收站记录详情" width="720px" destroy-on-close>
      <div v-loading="detailLoading">
        <el-descriptions :column="2" border size="small" v-if="detailData?.recycle" style="margin-bottom: 16px">
          <el-descriptions-item label="记录ID">{{ detailData.recycle.id }}</el-descriptions-item>
          <el-descriptions-item label="原虚拟机ID">{{ detailData.recycle.vm_id }}</el-descriptions-item>
          <el-descriptions-item label="虚拟机名称">{{ detailData.recycle.vm_name }}</el-descriptions-item>
          <el-descriptions-item label="状态">
            <el-tag :type="statusTagType(detailData.recycle.status)" size="small">{{ statusLabel(detailData.recycle.status) }}</el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="宿主机ID">{{ detailData.recycle.host_id }}</el-descriptions-item>
          <el-descriptions-item label="归档目录">
            <span class="mono-text">{{ detailData.recycle.recycle_dir || '-' }}</span>
          </el-descriptions-item>
          <el-descriptions-item label="到期时间">{{ formatTs(detailData.recycle.expire_at) }}</el-descriptions-item>
          <el-descriptions-item label="创建时间">{{ formatTs(detailData.recycle.created_at) }}</el-descriptions-item>
        </el-descriptions>

        <template v-if="detailData">
          <div v-for="snap in snapshotSections" :key="snap.key">
            <div class="snapshot-title">{{ snap.label }}</div>
            <el-input type="textarea" :model-value="formatSnapshot(detailData[snap.key])" :rows="6" readonly
              style="margin-bottom: 12px; font-family: Consolas, Monaco, monospace; font-size: 12px" />
          </div>
        </template>
        <el-empty v-if="!detailData" description="暂无详情数据" />
      </div>
      <template #footer>
        <el-button @click="detailVisible = false">关闭</el-button>
      </template>
    </el-dialog>

    <!-- 恢复弹窗（可选指定网络） -->
    <el-dialog v-model="restoreVisible" title="恢复虚拟机" width="480px" destroy-on-close>
      <el-form label-width="120px">
        <el-form-item label="虚拟机名称">
          <span>{{ restoreRow?.vm_name }} (ID: {{ restoreRow?.vm_id }})</span>
        </el-form-item>
        <el-form-item label="内网网络ID">
          <el-input v-model="restoreForm.network_ids" placeholder="可选，多个用逗号分隔" />
        </el-form-item>
        <el-form-item label="外网网络ID">
          <el-input v-model="restoreForm.internet_network_id" placeholder="可选" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="restoreVisible = false">取消</el-button>
        <el-button type="primary" :loading="restoreLoading" @click="submitRestore">确认恢复</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, inject, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, Refresh, ArrowDown } from '@element-plus/icons-vue'
import {
  getRecycleBinList, getRecycleBinDetail,
  restoreRecycleBin, deleteRecycleBin, cleanRecycleBin
} from '@/api/admin/kvmService'
import { extractApiError } from '@/utils/kvmErrorUtil'

const serviceId = inject('serviceId')
const hostId = inject('hostId')

const loading = ref(false)
const list = ref([])
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(10)
const keyword = ref('')
const filterStatus = ref('')

const statusOptions = [
  { value: 'pending', label: '等待归档' },
  { value: 'archiving', label: '归档中' },
  { value: 'archived', label: '已归档' },
  { value: 'restoring', label: '恢复中' },
  { value: 'purging', label: '清理中' }
]

const statusLabelMap = {
  pending: '等待归档', archiving: '归档中', archived: '已归档',
  restoring: '恢复中', purging: '清理中', failed: '失败', error: '错误'
}
const statusLabel = (s) => statusLabelMap[s] || s || '-'
const statusTagType = (s) => ({
  archived: 'success', pending: 'info', archiving: 'warning',
  restoring: 'primary', purging: 'danger', failed: 'danger', error: 'danger'
}[s] || 'info')

const formatTs = (ts) => {
  if (!ts) return '-'
  if (typeof ts === 'object' && ts.seconds) return new Date(Number(ts.seconds) * 1000).toLocaleString('zh-CN')
  if (typeof ts === 'string' || typeof ts === 'number') {
    const d = new Date(ts)
    return isNaN(d.getTime()) ? String(ts) : d.toLocaleString('zh-CN')
  }
  return '-'
}

const isExpired = (ts) => {
  if (!ts) return false
  let t
  if (typeof ts === 'object' && ts.seconds) t = Number(ts.seconds) * 1000
  else t = new Date(ts).getTime()
  return !isNaN(t) && t < Date.now()
}

const loadList = async () => {
  loading.value = true
  try {
    const params = {
      service_id: serviceId.value,
      host_id: hostId.value,
      page: currentPage.value,
      count: pageSize.value
    }
    if (keyword.value) params.keyword = keyword.value
    if (filterStatus.value) params.status = filterStatus.value

    const res = await getRecycleBinList(params)
    if (res?.data?.code === 200 && res?.data?.data) {
      const d = res.data.data
      list.value = d.data || d.list || (Array.isArray(d) ? d : [])
      total.value = d.meta?.count ?? d.total ?? list.value.length
    } else { list.value = []; total.value = 0 }
  } catch { list.value = []; total.value = 0 } finally { loading.value = false }
}

/* ---- 详情 ---- */
const detailVisible = ref(false)
const detailLoading = ref(false)
const detailData = ref(null)

const snapshotSections = [
  { key: 'vm_snapshot', label: '虚拟机快照' },
  { key: 'volumes_snapshot', label: '磁盘快照' },
  { key: 'networks_snapshot', label: '网络快照' },
  { key: 'traffic_policy_snapshot', label: '流量策略快照' }
]

const formatSnapshot = (raw) => {
  if (!raw) return '(无)'
  try { return JSON.stringify(JSON.parse(raw), null, 2) } catch { return raw }
}

const handleDetail = async (row) => {
  detailData.value = null
  detailVisible.value = true
  detailLoading.value = true
  try {
    const res = await getRecycleBinDetail({
      service_id: serviceId.value,
      host_id: hostId.value,
      recycle_id: row.id
    })
    if (res?.data?.code === 200 && res?.data?.data) {
      detailData.value = res.data.data.data ?? res.data.data
    } else { ElMessage.warning('获取详情失败') }
  } catch (e) {
    ElMessage.error(extractApiError(e?.response?.data, '获取详情失败'))
  } finally { detailLoading.value = false }
}

/* ---- 恢复 ---- */
const restoreVisible = ref(false)
const restoreLoading = ref(false)
const restoreRow = ref(null)
const restoreForm = reactive({ network_ids: '', internet_network_id: '' })

const handleRestore = (row) => {
  restoreRow.value = row
  Object.assign(restoreForm, { network_ids: '', internet_network_id: '' })
  restoreVisible.value = true
}

const submitRestore = async () => {
  restoreLoading.value = true
  try {
    const fd = new FormData()
    fd.append('service_id', serviceId.value)
    fd.append('host_id', hostId.value)
    fd.append('recycle_id', restoreRow.value.id)
    if (restoreForm.network_ids) {
      restoreForm.network_ids.split(',').map(s => s.trim()).filter(Boolean).forEach(id => {
        fd.append('network_ids', id)
      })
    }
    if (restoreForm.internet_network_id) {
      fd.append('internet_network_id', restoreForm.internet_network_id)
    }
    const res = await restoreRecycleBin(fd)
    if (res?.data?.code === 200) {
      ElMessage.success('恢复任务已提交')
      restoreVisible.value = false
      loadList()
    } else { ElMessage.error(extractApiError(res?.data, '恢复失败')) }
  } catch (e) {
    ElMessage.error(extractApiError(e?.response?.data, '恢复失败'))
  } finally { restoreLoading.value = false }
}

/* ---- 永久删除 ---- */
const handleDelete = (row) => {
  ElMessageBox.confirm(
    `确定要永久删除「${row.vm_name}」的回收站记录吗？此操作不可恢复！`,
    '永久删除确认',
    { confirmButtonText: '确定删除', cancelButtonText: '取消', type: 'warning' }
  ).then(async () => {
    try {
      const res = await deleteRecycleBin({
        service_id: serviceId.value,
        host_id: hostId.value,
        recycle_id: row.id
      })
      if (res?.data?.code === 200) { ElMessage.success('删除任务已提交'); loadList() }
      else ElMessage.error(extractApiError(res?.data, '删除失败'))
    } catch (e) { ElMessage.error(extractApiError(e?.response?.data, '删除失败')) }
  }).catch(() => {})
}

/* ---- 清空回收站 ---- */
const handleClean = (command) => {
  const isAll = command === 'all'
  const msg = isAll ? '确定要清空全部回收站记录吗？此操作不可恢复！' : '确定要清理所有已到期的回收站记录吗？'
  ElMessageBox.confirm(msg, '清空回收站', {
    confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning'
  }).then(async () => {
    try {
      const res = await cleanRecycleBin({
        service_id: serviceId.value,
        host_id: hostId.value,
        all: isAll
      })
      if (res?.data?.code === 200) {
        const purged = res.data.data?.purged ?? 0
        ElMessage.success(`已提交清理任务，清理 ${purged} 条记录`)
        loadList()
      } else { ElMessage.error(extractApiError(res?.data, '清空失败')) }
    } catch (e) { ElMessage.error(extractApiError(e?.response?.data, '清空失败')) }
  }).catch(() => {})
}

onMounted(() => { loadList() })

defineExpose({ loadList })
</script>

<style scoped>
.recycle-bin-manage { padding: 0; }
.toolbar { display: flex; gap: 8px; align-items: center; margin-top: 12px; margin-bottom: 12px; }
.mono-text { font-family: Consolas, Monaco, monospace; font-size: 12px; }
.snapshot-title { font-size: 13px; font-weight: 600; color: #606266; margin: 12px 0 6px; }
.pagination-wrapper { margin-top: 12px; display: flex; justify-content: flex-end; }
</style>
