<template>
  <section>
    <header class="page-head">
      <div>
        <h2>备份管理</h2>
        <p>查看本地数据库备份，必要时手动备份或回滚到指定时间点。</p>
      </div>
      <div class="head-actions">
        <el-button @click="loadBackups">刷新</el-button>
        <el-button type="primary" :loading="creating" @click="createBackup">立即备份</el-button>
      </div>
    </header>

    <el-alert
      class="risk-alert"
      type="warning"
      show-icon
      :closable="false"
      title="回滚会覆盖当前数据库。系统会先自动备份当前库，再执行恢复；建议在无人操作后台时使用。"
    />

    <el-card class="panel" shadow="never">
      <div class="panel-head">
        <div>
          <h3>本地备份点</h3>
          <p>备份文件保存在服务器的系统数据目录中，只能由系统管理员操作。</p>
        </div>
        <el-tag type="info">{{ backups.length }} 个备份</el-tag>
      </div>

      <el-table v-loading="loading" :data="backups" border empty-text="还没有数据库备份">
        <el-table-column label="备份时间" min-width="180">
          <template #default="{ row }">{{ formatTime(row.created_at) }}</template>
        </el-table-column>
        <el-table-column prop="filename" label="文件名" min-width="300" show-overflow-tooltip />
        <el-table-column label="数据库" width="110">
          <template #default="{ row }">
            <el-tag>{{ row.database_type }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="size_label" label="大小" width="110" />
        <el-table-column label="来源" min-width="170">
          <template #default="{ row }">{{ reasonLabel(row.reason) }}</template>
        </el-table-column>
        <el-table-column label="操作" width="130" fixed="right">
          <template #default="{ row }">
            <el-button type="danger" plain size="small" :loading="restoring === row.filename" @click="confirmRestore(row)">
              回滚
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
  </section>
</template>

<script setup lang="ts">
import { ElMessage, ElMessageBox } from "element-plus";
import { onMounted, ref } from "vue";

import { http, type DatabaseBackup, type RestoreDatabaseBackupResult } from "../api";

const backups = ref<DatabaseBackup[]>([]);
const loading = ref(false);
const creating = ref(false);
const restoring = ref("");

function formatTime(value: string) {
  if (!value) return "-";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return date.toLocaleString("zh-CN", { hour12: false });
}

function reasonLabel(reason: string | null) {
  if (!reason || reason === "manual") return "手动备份";
  if (reason.startsWith("pre_restore_")) return "回滚前自动备份";
  return reason;
}

async function loadBackups() {
  loading.value = true;
  try {
    const { data } = await http.get<DatabaseBackup[]>("/admin/backups");
    backups.value = data;
  } finally {
    loading.value = false;
  }
}

async function createBackup() {
  creating.value = true;
  try {
    await http.post<DatabaseBackup>("/admin/backups", { reason: "manual" });
    ElMessage.success("数据库备份已创建");
    await loadBackups();
  } finally {
    creating.value = false;
  }
}

async function confirmRestore(row: DatabaseBackup) {
  const confirmation = `RESTORE ${row.filename}`;
  try {
    const { value } = await ElMessageBox.prompt(
      `将数据库回滚到 ${formatTime(row.created_at)}。请输入确认语：${confirmation}`,
      "确认回滚数据库",
      {
        confirmButtonText: "确认回滚",
        cancelButtonText: "取消",
        inputPlaceholder: confirmation,
        inputValidator: (input) => input.trim() === confirmation || "确认语不正确",
        type: "warning",
      },
    );
    restoring.value = row.filename;
    const { data } = await http.post<RestoreDatabaseBackupResult>(`/admin/backups/${encodeURIComponent(row.filename)}/restore`, {
      confirmation: String(value),
    });
    ElMessage.success(`已回滚，回滚前备份：${data.pre_restore_backup.filename}`);
    await loadBackups();
  } finally {
    restoring.value = "";
  }
}

onMounted(loadBackups);
</script>

<style scoped>
.page-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin-bottom: 16px;
}

.page-head p,
.panel-head p {
  margin: 6px 0 0;
  color: #64748b;
}

.head-actions {
  display: flex;
  gap: 8px;
}

.risk-alert {
  margin-bottom: 16px;
}

.panel {
  border-radius: 8px;
}

.panel-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 14px;
}

.panel-head h3 {
  margin: 0;
  font-size: 18px;
}

@media (max-width: 900px) {
  .page-head,
  .panel-head {
    align-items: stretch;
    flex-direction: column;
  }

  .head-actions {
    justify-content: flex-start;
  }
}
</style>
