<template>
  <div class="layout-px-spacing">
    <div class="row layout-top-spacing">
      <div class="col-lg-9 mx-auto layout-spacing">
        <div class="panel p-4">
          <h3 class="mb-1">Respaldo de base de datos</h3>
          <p class="text-muted mb-4">
            Descarga un volcado SQL de MySQL del rancho. Compatible con phpMyAdmin: puedes importar el archivo
            <code>.sql</code> o <code>.sql.gz</code> desde <strong>Importar</strong>.
          </p>

          <div v-if="error" class="alert alert-danger">{{ error }}</div>
          <div v-if="success" class="alert alert-success">{{ success }}</div>

          <div class="d-flex flex-wrap gap-2 mb-4">
            <button type="button" class="btn btn-primary" :disabled="downloading" @click="downloadFresh">
              {{ downloading ? 'Generando respaldo…' : 'Descargar respaldo ahora' }}
            </button>
            <button type="button" class="btn btn-outline-secondary" :disabled="loading" @click="load">
              {{ loading ? 'Actualizando…' : 'Actualizar lista' }}
            </button>
          </div>

          <div class="card mb-4">
            <div class="card-body">
              <h6 class="mb-2">Servidor</h6>
              <ul class="small text-muted mb-0">
                <li>El respaldo usa <strong>mysqldump</strong> en el servidor (no phpMyAdmin en el navegador).</li>
                <li>Si falla, configura la ruta en <code>RANCH_MYSQLDUMP_PATH</code> del <code>.env</code>.</li>
                <li>Retención local: {{ info.retention_days ?? 14 }} días ·
                  {{ info.gzip ? 'comprimido .sql.gz' : 'sin comprimir .sql' }}.</li>
                <li>También puedes programar: <code>php artisan ranch:backup-database</code>.</li>
              </ul>
            </div>
          </div>

          <h5 class="mb-3">Respaldos recientes en el servidor</h5>
          <p v-if="loading && !backups.length" class="text-muted">Cargando…</p>
          <div v-else-if="!backups.length" class="text-muted">Aún no hay respaldos guardados en el servidor.</div>
          <div v-else class="table-responsive">
            <table class="table table-sm align-middle">
              <thead>
                <tr>
                  <th>Archivo</th>
                  <th>Tamaño</th>
                  <th>Fecha</th>
                  <th />
                </tr>
              </thead>
              <tbody>
                <tr v-for="row in backups" :key="row.filename">
                  <td><code class="small">{{ row.filename }}</code></td>
                  <td>{{ formatSize(row.size_bytes) }}</td>
                  <td>{{ formatDate(row.created_at) }}</td>
                  <td class="text-end">
                    <button
                      type="button"
                      class="btn btn-outline-primary btn-sm"
                      :disabled="downloadingFile === row.filename"
                      @click="downloadExisting(row.filename)"
                    >
                      {{ downloadingFile === row.filename ? '…' : 'Descargar' }}
                    </button>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { onMounted, reactive, ref } from 'vue';
import RanchRepository from '@/repositories/RanchRepository';

const loading = ref(false);
const downloading = ref(false);
const downloadingFile = ref('');
const error = ref('');
const success = ref('');
const backups = ref([]);
const info = reactive({ retention_days: 14, gzip: true });

function formatSize(bytes) {
  const n = Number(bytes || 0);
  if (n >= 1024 * 1024) return `${(n / (1024 * 1024)).toFixed(1)} MB`;
  if (n >= 1024) return `${(n / 1024).toFixed(1)} KB`;
  return `${n} B`;
}

function formatDate(value) {
  if (!value) return '—';
  return new Intl.DateTimeFormat('es-MX', {
    dateStyle: 'medium',
    timeStyle: 'short',
  }).format(new Date(value));
}

function downloadBlob(blob, filename) {
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  a.click();
  URL.revokeObjectURL(url);
}

function filenameFromBlob(blob, fallback) {
  if (blob?.type?.includes('json')) return null;
  return fallback;
}

async function parseDownloadError(err) {
  const data = err?.response?.data;
  if (data instanceof Blob) {
    try {
      const text = await data.text();
      const json = JSON.parse(text);
      return json.message || 'No se pudo generar el respaldo.';
    } catch {
      return 'No se pudo generar el respaldo.';
    }
  }
  return err?.response?.data?.message || err?.message || 'No se pudo generar el respaldo.';
}

async function load() {
  loading.value = true;
  error.value = '';
  try {
    const data = await RanchRepository.listDatabaseBackups();
    backups.value = data.backups || [];
    info.retention_days = data.retention_days;
    info.gzip = data.gzip;
  } catch (e) {
    error.value = e?.response?.data?.message || 'No se pudo cargar la lista de respaldos.';
  } finally {
    loading.value = false;
  }
}

async function downloadFresh() {
  downloading.value = true;
  error.value = '';
  success.value = '';
  try {
    const blob = await RanchRepository.downloadDatabaseBackup({ fresh: true });
    if (blob.type?.includes('json')) {
      const text = await blob.text();
      const json = JSON.parse(text);
      throw new Error(json.message || 'Error al generar respaldo');
    }
    const name = info.gzip
      ? `ganaderia-respaldo-${new Date().toISOString().slice(0, 10)}.sql.gz`
      : `ganaderia-respaldo-${new Date().toISOString().slice(0, 10)}.sql`;
    downloadBlob(blob, filenameFromBlob(blob, name) || name);
    success.value = 'Respaldo descargado. Guarda el archivo en un lugar seguro.';
    await load();
  } catch (e) {
    error.value = await parseDownloadError(e);
  } finally {
    downloading.value = false;
  }
}

async function downloadExisting(filename) {
  downloadingFile.value = filename;
  error.value = '';
  try {
    const blob = await RanchRepository.downloadDatabaseBackup({ fresh: false, file: filename });
    if (blob.type?.includes('json')) {
      const text = await blob.text();
      const json = JSON.parse(text);
      throw new Error(json.message || 'Error al descargar');
    }
    downloadBlob(blob, filename);
    success.value = `Descargado: ${filename}`;
  } catch (e) {
    error.value = await parseDownloadError(e);
  } finally {
    downloadingFile.value = '';
  }
}

onMounted(load);
</script>
