<template>
  <div class="space-y-4">
    <!-- Filtros -->
    <div class="bg-colorPrimary border-l-4 border-colorSecondary p-4 rounded-box space-y-3 shadow-lg shadow-tertiary/20">
      <div class="flex flex-col md:flex-row gap-3 items-end">
        <div class="flex-1 w-full">
          <label class="label py-0 text-xs font-medium">Buscar</label>
          <input
            v-model="search"
            type="text"
            placeholder="Nombre, correo, teléfono, documento…"
            class="input input-bordered input-sm w-full"
            @input="onSearch"
          />
        </div>
        <div class="w-full md:w-52">
          <label class="label py-0 text-xs font-medium">Status</label>
          <details class="dropdown w-full">
            <summary class="btn btn-sm btn-outline w-full justify-between">
              <span class="truncate">{{ statusLabel }}</span>
              <span class="opacity-60">▾</span>
            </summary>
            <ul class="menu dropdown-content bg-base-100 rounded-box shadow ring-1 ring-base-300 z-20 w-56 max-h-64 overflow-y-auto">
              <li v-for="s in statuses" :key="s">
                <label class="flex items-center gap-2 py-1.5">
                  <input
                    type="checkbox"
                    :value="s"
                    v-model="selectedStatuses"
                    class="checkbox checkbox-xs"
                    @change="applyFilters"
                  />
                  <span>{{ s }}</span>
                </label>
              </li>
            </ul>
          </details>
        </div>
        <div class="flex gap-2">
          <button class="btn btn-ghost btn-sm text-tertiary" @click="clearFilters">Limpiar</button>
          <button class="btn btn-primary btn-sm" @click="showFilters = !showFilters">
            {{ showFilters ? "Ocultar filtros" : "Filtros" }}
            <span v-if="activeFilterCount" class="badge badge-sm bg-tertiary text-colorPrimary border-0">{{ activeFilterCount }}</span>
          </button>
        </div>
      </div>

      <!-- Chips de filtros activos -->
      <div v-if="activeChips.length" class="flex flex-wrap gap-1.5">
        <span
          v-for="chip in activeChips"
          :key="chip.key"
          class="badge badge-sm bg-white gap-1 border border-colorSecondary/60 text-tertiary"
        >
          {{ chip.label }}
          <button type="button" class="opacity-60 hover:opacity-100" @click="chip.remove()">✕</button>
        </span>
      </div>

      <!-- Panel de filtros -->
      <div v-if="showFilters" class="border-t border-colorSecondary/40 pt-3 space-y-4">
        <div>
          <p class="text-xs font-bold text-tertiary mb-2 uppercase tracking-wide flex items-center gap-2">
            <span class="inline-block w-1 h-3.5 bg-colorSecondary"></span>Fecha y edad
          </p>
          <div class="grid grid-cols-2 md:grid-cols-4 gap-3">
            <div>
              <label class="label py-0 text-xs font-medium">Desde</label>
              <input v-model="desde" type="date" class="input input-bordered input-sm w-full" @change="applyFilters" />
            </div>
            <div>
              <label class="label py-0 text-xs font-medium">Hasta</label>
              <input v-model="hasta" type="date" class="input input-bordered input-sm w-full" @change="applyFilters" />
            </div>
            <div>
              <label class="label py-0 text-xs font-medium">Edad mín</label>
              <input v-model="edadMin" type="number" min="0" max="120" class="input input-bordered input-sm w-full" @change="applyFilters" />
            </div>
            <div>
              <label class="label py-0 text-xs font-medium">Edad máx</label>
              <input v-model="edadMax" type="number" min="0" max="120" class="input input-bordered input-sm w-full" @change="applyFilters" />
            </div>
          </div>
        </div>

        <div>
          <p class="text-xs font-bold text-tertiary mb-2 uppercase tracking-wide flex items-center gap-2">
            <span class="inline-block w-1 h-3.5 bg-colorSecondary"></span>Ubicación
          </p>
          <div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-3">
            <div>
              <label class="label py-0 text-xs font-medium">País</label>
              <SearchableCombobox
                v-model="selectedPaises"
                field="pais"
                multiple
                placeholder="Buscar país…"
                @update:modelValue="applyFilters"
              />
            </div>
            <div>
              <label class="label py-0 text-xs font-medium">Nacionalidad</label>
              <SearchableCombobox
                v-model="nacionalidad"
                field="nacionalidad"
                placeholder="Buscar…"
                @update:modelValue="onSearch"
              />
            </div>
            <div>
              <label class="label py-0 text-xs font-medium">Sexo</label>
              <select v-model="sexo" class="select select-bordered select-sm w-full" @change="applyFilters">
                <option value="">Todos</option>
                <option value="M">M</option>
                <option value="F">F</option>
              </select>
            </div>
            <div>
              <label class="label py-0 text-xs font-medium">Ciudad</label>
              <SearchableCombobox
                v-model="coreText.ciudad"
                field="ciudad"
                placeholder="Buscar…"
                @update:modelValue="onSearch"
              />
            </div>
            <div>
              <label class="label py-0 text-xs font-medium">Estado</label>
              <SearchableCombobox
                v-model="coreText.estado"
                field="estado"
                placeholder="Buscar…"
                @update:modelValue="onSearch"
              />
            </div>
          </div>
        </div>

        <div>
          <p class="text-xs font-bold text-tertiary mb-2 uppercase tracking-wide flex items-center gap-2">
            <span class="inline-block w-1 h-3.5 bg-colorSecondary"></span>Perfil
          </p>
          <div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-3">
            <div>
              <label class="label py-0 text-xs font-medium">Profesión</label>
              <SearchableCombobox
                v-model="coreText.profesion"
                field="profesion"
                placeholder="Buscar…"
                @update:modelValue="onSearch"
              />
            </div>
            <div>
              <label class="label py-0 text-xs font-medium">Nivel académico</label>
              <SearchableCombobox
                v-model="coreText.nivel_academico"
                field="nivel_academico"
                placeholder="Buscar…"
                @update:modelValue="onSearch"
              />
            </div>
            <div>
              <label class="label py-0 text-xs font-medium">Documento</label>
              <input v-model="coreText.documento_nro" type="text" class="input input-bordered input-sm w-full" @input="onSearch" />
            </div>
            <div>
              <label class="label py-0 text-xs font-medium">Versión de formulario</label>
              <select v-model="formVersion" class="select select-bordered select-sm w-full" @change="applyFilters">
                <option value="">Todas</option>
                <option v-for="f in formVersions" :key="f" :value="f">{{ f }}</option>
              </select>
            </div>
          </div>
        </div>

        <div>
          <p class="text-xs font-bold text-tertiary mb-2 uppercase tracking-wide flex items-center gap-2">
            <span class="inline-block w-1 h-3.5 bg-colorSecondary"></span>Preferencias y condiciones
          </p>
          <div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-3">
            <div v-for="f in responseFields" :key="f">
              <label class="label py-0 text-xs font-medium">{{ respLabels[f] }}</label>
              <select v-model="respFilters[f]" class="select select-bordered select-sm w-full" @change="applyFilters">
                <option value="">Todos</option>
                <option v-for="o in respFilterOptions[f]" :key="o" :value="o">{{ o }}</option>
              </select>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- Tabla -->
    <div class="overflow-x-auto bg-base-100 rounded-box shadow ring-1 ring-base-300">
      <table class="table table-sm">
        <thead>
          <tr class="text-xs uppercase">
            <th class="cursor-pointer select-none" @click="toggleSort('numero_voluntario')">#</th>
            <th class="cursor-pointer select-none" @click="toggleSort('nombre')">Nombre completo</th>
            <th>Correo</th>
            <th>Teléfono</th>
            <th class="cursor-pointer select-none" @click="toggleSort('pais')">País</th>
            <th>Ciudad</th>
            <th>Idiomas</th>
            <th>Áreas</th>
            <th>Status</th>
            <th class="cursor-pointer select-none" @click="toggleSort('submitted_at')">Fecha</th>
            <th class="w-20 text-right">Acción</th>
          </tr>
        </thead>
        <tbody>
          <tr v-if="loading">
            <td colspan="11" class="text-center py-10">
              <span class="loading loading-spinner loading-md text-primary"></span>
            </td>
          </tr>
          <tr v-else-if="error">
            <td colspan="11" class="text-center py-10 text-error">{{ error }}</td>
          </tr>
          <tr v-else-if="rows.length === 0">
            <td colspan="11" class="text-center py-10 text-base-content/40">Sin resultados</td>
          </tr>
          <tr v-for="row in rows" :key="row.id" class="hover:bg-base-200/50 cursor-pointer" @click="openDetail(row)">
            <td class="font-mono">{{ row.numero_voluntario }}</td>
            <td class="font-medium whitespace-nowrap">{{ row.nombre_completo }}</td>
            <td class="max-w-[220px] truncate">{{ row.correo }}</td>
            <td class="whitespace-nowrap">{{ row.telefono || "—" }}</td>
            <td class="whitespace-nowrap">{{ row.pais || "—" }}</td>
            <td class="whitespace-nowrap">{{ row.ciudad || "—" }}</td>
            <td class="max-w-[200px] truncate" :title="row.idioma">{{ row.idioma || "—" }}</td>
            <td class="max-w-[200px] truncate" :title="row.areas_colaborar">{{ row.areas_colaborar || "—" }}</td>
            <td>
              <span class="badge badge-sm" :class="badgeClass(row.status)">{{ row.status || "pendiente" }}</span>
            </td>
            <td class="whitespace-nowrap">{{ formatDate(row.submitted_at) }}</td>
            <td class="text-right">
              <button class="btn btn-ghost btn-xs" title="Ver detalle" @click.stop="openDetail(row)">Ver</button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>

    <!-- Paginación -->
    <div class="flex items-center justify-between flex-wrap gap-3">
      <p class="text-sm text-amber-200">
        {{ total }} registros · página {{ page }} de {{ totalPages || 1 }}
      </p>
      <div class="join">
        <button class="join-item btn btn-sm" :disabled="page <= 1" @click="goPage(page - 1)">«</button>
        <button
          v-for="p in pageNumbers"
          :key="p"
          class="join-item btn btn-sm"
          :class="p === page ? 'btn-primary' : ''"
          @click="goPage(p)"
        >
          {{ p }}
        </button>
        <button class="join-item btn btn-sm" :disabled="page >= totalPages" @click="goPage(page + 1)">»</button>
      </div>
    </div>

    <!-- Modal de detalle -->
    <Teleport v-if="detailNumero !== null" to="body">
      <div class="fixed inset-0 z-[60] overflow-y-auto">
        <div class="fixed inset-0 bg-black/60" @click="closeDetail"></div>
        <div class="relative min-h-full flex items-center justify-center p-4 sm:p-6">
          <div class="w-full max-w-3xl max-h-[85vh] overflow-y-auto rounded-box bg-base-100 shadow-2xl ring-1 ring-base-300">
            <div class="sticky top-0 z-10 flex items-center justify-between px-4 py-3 bg-base-100 border-b border-base-200">
              <span class="text-sm font-semibold">Detalle del voluntario</span>
              <button class="btn btn-ghost btn-sm" @click="closeDetail">✕</button>
            </div>
            <div class="p-4">
              <VoluntarioDetail :numero="detailNumero" />
            </div>
          </div>
        </div>
      </div>
    </Teleport>
  </div>
</template>

<script setup>
import { ref, reactive, computed, watch, onMounted, onUnmounted } from "vue";
import SearchableCombobox from "./SearchableCombobox.vue";
import VoluntarioDetail from "./VoluntarioDetail.vue";
import { cachedFetch } from "../../lib/adminCache";

const rows = ref([]);
const total = ref(0);
const page = ref(1);
const totalPages = ref(1);
const limit = 25;
const loading = ref(false);
const error = ref("");

const detailNumero = ref(null);
let returnPath = "";

function slugUrl(numero) {
  const m = window.location.pathname.match(/^\/([a-z]{2})\/admin/);
  const locale = m ? m[1] : "es";
  return `/${locale}/admin/voluntario/${numero}`;
}

function openDetail(row) {
  returnPath = window.location.pathname;
  detailNumero.value = row.numero_voluntario;
  history.pushState({ voluntario: true }, "", slugUrl(row.numero_voluntario));
}

function closeDetail() {
  detailNumero.value = null;
  history.replaceState(null, "", returnPath || window.location.pathname);
}

function onPopstate() {
  if (detailNumero.value !== null) detailNumero.value = null;
}

function onKeydown(e) {
  if (e.key === "Escape" && detailNumero.value !== null) closeDetail();
}

watch(detailNumero, (v) => {
  document.body.style.overflow = v === null ? "" : "hidden";
});

const search = ref("");
const selectedStatuses = ref([]);
const selectedPaises = ref([]);
const sort = ref("submitted_at");
const order = ref("desc");
const showFilters = ref(false);

const desde = ref("");
const hasta = ref("");
const edadMin = ref("");
const edadMax = ref("");

const coreText = reactive({
  ciudad: "",
  estado: "",
  profesion: "",
  nivel_academico: "",
  documento_nro: "",
});
const sexo = ref("");
const nacionalidad = ref("");
const formVersion = ref("");

const responseFields = [
  "idioma",
  "areas_colaborar",
  "dias_disponibles",
  "horario_preferido",
  "fuera_ciudad",
  "misiones_internacionales",
  "condicion_medica",
  "voluntariado_anterior",
];
const respFilters = reactive(Object.fromEntries(responseFields.map((f) => [f, ""])));

const respLabels = {
  idioma: "Idioma",
  areas_colaborar: "Áreas de colaboración",
  dias_disponibles: "Días disponibles",
  horario_preferido: "Horario preferido",
  fuera_ciudad: "Disponible fuera de ciudad",
  misiones_internacionales: "Misiones internacionales",
  condicion_medica: "Condición médica",
  voluntariado_anterior: "Voluntariado anterior",
};

const respFilterOptions = {
  idioma: ["Espanol", "Ingles", "Hebreo", "Portugues", "Frances", "Otro"],
  areas_colaborar: [
    "Ayuda Humanitaria", "Educacion", "Desarrollo Comunitario", "Liderazgo",
    "Logistica", "Organizacion de Eventos", "Comunicacion Institucional",
    "Fotografia y Medios", "Recaudacion de Fondos", "Gestion de Proyectos",
    "Traduccion e Interpretacion", "Asesoria Juridica", "Servicios Medicos",
    "Diplomacia Publica", "Administracion", "Tecnologia e Innovacion", "Otra",
  ],
  dias_disponibles: ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo"],
  horario_preferido: ["Manana", "Tarde", "Noche", "Segun necesidades"],
  fuera_ciudad: ["si", "no"],
  misiones_internacionales: ["si", "no"],
  condicion_medica: ["si", "no"],
  voluntariado_anterior: ["si", "no"],
};

const statuses = ref([]);
const formVersions = ref([]);

let searchTimer = null;

const statusLabel = computed(() =>
  selectedStatuses.value.length ? selectedStatuses.value.join(", ") : "Todos"
);

const activeFilterCount = computed(() => activeChips.value.length);

const activeChips = computed(() => {
  const chips = [];
  const add = (key, label, remove) => chips.push({ key, label, remove });

  if (search.value.trim()) add("q", `Búsqueda: ${search.value.trim()}`, () => {
    search.value = "";
    onSearch();
  });
  for (const s of selectedStatuses.value) add(`status-${s}`, `Status: ${s}`, () => {
    selectedStatuses.value = selectedStatuses.value.filter((x) => x !== s);
    applyFilters();
  });
  for (const p of selectedPaises.value) add(`pais-${p}`, `País: ${p}`, () => {
    selectedPaises.value = selectedPaises.value.filter((x) => x !== p);
    applyFilters();
  });
  if (desde.value) add("desde", `Desde: ${desde.value}`, () => {
    desde.value = "";
    applyFilters();
  });
  if (hasta.value) add("hasta", `Hasta: ${hasta.value}`, () => {
    hasta.value = "";
    applyFilters();
  });
  if (edadMin.value) add("edad_min", `Edad mín: ${edadMin.value}`, () => {
    edadMin.value = "";
    applyFilters();
  });
  if (edadMax.value) add("edad_max", `Edad máx: ${edadMax.value}`, () => {
    edadMax.value = "";
    applyFilters();
  });
  for (const [k, v] of Object.entries(coreText)) {
    if (v) {
      const label = { ciudad: "Ciudad", estado: "Estado", profesion: "Profesión", nivel_academico: "Nivel académico", documento_nro: "Documento" }[k];
      add(`core-${k}`, `${label}: ${v}`, () => {
        coreText[k] = "";
        applyFilters();
      });
    }
  }
  if (sexo.value) add("sexo", `Sexo: ${sexo.value}`, () => {
    sexo.value = "";
    applyFilters();
  });
  if (nacionalidad.value) add("nacionalidad", `Nacionalidad: ${nacionalidad.value}`, () => {
    nacionalidad.value = "";
    applyFilters();
  });
  if (formVersion.value) add("form_version", `Versión: ${formVersion.value}`, () => {
    formVersion.value = "";
    applyFilters();
  });
  for (const f of responseFields) {
    if (respFilters[f]) add(`resp-${f}`, `${respLabels[f]}: ${respFilters[f]}`, () => {
      respFilters[f] = "";
      applyFilters();
    });
  }
  return chips;
});

async function fetchData() {
  loading.value = true;
  error.value = "";
  const params = new URLSearchParams();
  params.set("page", String(page.value));
  params.set("limit", String(limit));
  params.set("sort", sort.value);
  params.set("order", order.value);
  if (search.value.trim()) params.set("q", search.value.trim());
  if (selectedStatuses.value.length) params.set("status", selectedStatuses.value.join(","));
  if (selectedPaises.value.length) params.set("pais", selectedPaises.value.join(","));
  if (desde.value) params.set("desde", desde.value);
  if (hasta.value) params.set("hasta", hasta.value);
  if (edadMin.value) params.set("edad_min", edadMin.value);
  if (edadMax.value) params.set("edad_max", edadMax.value);
  for (const [f, v] of Object.entries(coreText)) if (v) params.set(f, v);
  if (sexo.value) params.set("sexo", sexo.value);
  if (nacionalidad.value) params.set("nacionalidad", nacionalidad.value);
  if (formVersion.value) params.set("form_version", formVersion.value);
  for (const f of responseFields) if (respFilters[f]) params.set(f, respFilters[f]);

  try {
    const res = await cachedFetch(`/api/admin/voluntarios?${params.toString()}`, { ttl: 30 });
    const json = await res.json();
    if (!json.success) throw new Error(json.message || "Error al cargar");
    rows.value = json.data;
    total.value = json.total;
    totalPages.value = json.totalPages;
    page.value = json.page;
  } catch (e) {
    error.value = e.message;
  } finally {
    loading.value = false;
  }
}

async function fetchOptions() {
  try {
    const res = await cachedFetch("/api/admin/voluntarios/options", { ttl: 300 });
    const json = await res.json();
    if (json.success) {
      statuses.value = json.statuses;
      formVersions.value = json.form_versions;
    }
  } catch {
    // opciones no críticas
  }
}

function onSearch() {
  clearTimeout(searchTimer);
  searchTimer = setTimeout(() => {
    page.value = 1;
    fetchData();
  }, 400);
}

function applyFilters() {
  page.value = 1;
  fetchData();
}

function clearFilters() {
  search.value = "";
  selectedStatuses.value = [];
  selectedPaises.value = [];
  desde.value = "";
  hasta.value = "";
  edadMin.value = "";
  edadMax.value = "";
  Object.keys(coreText).forEach((k) => (coreText[k] = ""));
  sexo.value = "";
  nacionalidad.value = "";
  formVersion.value = "";
  Object.keys(respFilters).forEach((k) => (respFilters[k] = ""));
  page.value = 1;
  fetchData();
}

function toggleSort(field) {
  if (sort.value === field) {
    order.value = order.value === "asc" ? "desc" : "asc";
  } else {
    sort.value = field;
    order.value = "asc";
  }
  page.value = 1;
  fetchData();
}

function goPage(p) {
  if (p < 1 || p > totalPages.value || p === page.value) return;
  page.value = p;
  fetchData();
}

const pageNumbers = computed(() => {
  const total = totalPages.value;
  const current = page.value;
  const start = Math.max(1, current - 2);
  const end = Math.min(total, current + 2);
  const pages = [];
  for (let i = start; i <= end; i++) pages.push(i);
  return pages;
});

function formatDate(iso) {
  if (!iso) return "—";
  return new Date(iso).toLocaleDateString("es", {
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
  });
}

function badgeClass(s) {
  switch (s) {
    case "aprobado":
      return "badge-success";
    case "rechazado":
      return "badge-error";
    case "legacy":
      return "badge-warning";
    default:
      return "badge-neutral";
  }
}

onMounted(() => {
  fetchOptions();
  fetchData();
  window.addEventListener("popstate", onPopstate);
  window.addEventListener("keydown", onKeydown);
});

onUnmounted(() => {
  window.removeEventListener("popstate", onPopstate);
  window.removeEventListener("keydown", onKeydown);
});
</script>
