
<template>
  <a-spin :spinning="loading">

        <div class="topbar">
          <div class="topbarLeft">
            <div class="hello">Bienvenido, {{ authStore.userName}}</div>
            <div class="sub">DNI: {{ authStore.userDni || 'No registrado' }}</div>
          </div>

          <div class="topbarRight">
            <div class="statusLine">
              <span class="label">Estado:</span>
              <a-badge :status="eligibilityUi.badge" :text="eligibilityUi.text" />
            </div>

            <a-button class="btnTop" @click="fetchDashboard" :loading="loading" block>
              Actualizar
            </a-button>
          </div>
        </div>

        <a-divider />

        <div class="testBox">
          <div class="testHead">
            <div class="testHeadLeft">
              <div class="testTitle">Tu test de admisión</div>
              <div class="testSub">
                Responde con calma. Busca un lugar tranquilo. (10 preguntas • 10 min aprox.)
              </div>
            </div>

            <div class="testHeadRight">
              <a-button
                type="primary"
                size="large"
                class="btnTest"
                :disabled="!canStartTest"
                block
                @click="onStartTest"
              >
                {{ testCtaText }}
              </a-button>
              <div class="microHelp" v-if="!canStartTest">No disponible por el momento.</div>
            </div>
          </div>

          <div class="testInfoGrid">
            <div class="infoItem">
              <div class="infoK">Estado</div>
              <div class="infoV">
                <a-badge :status="testStatusUi.badge" :text="testStatusUi.text" />
              </div>
            </div>

            <div class="infoItem">
              <div class="infoK">Tiempo restante</div>
              <div class="infoV">
                <span class="strong" :class="{ warn: expiresSoon && timeRemainingText !== 'Vencido' }">
                  {{ timeRemainingText }}
                </span>
                <span v-if="expiresSoon && timeRemainingText !== 'Vencido'" class="hintInline">
                  (vence pronto)
                </span>
              </div>
            </div>

            <div class="infoItem">
              <div class="infoK">Disponible desde</div>
              <div class="infoV">
                {{ state.eligibility.testAvailableAt ? fmtDate(state.eligibility.testAvailableAt) : "—" }}
              </div>
            </div>

            <div class="infoItem">
              <div class="infoK">Fecha límite</div>
              <div class="infoV">
                {{ state.eligibility.testExpiresAt ? fmtDate(state.eligibility.testExpiresAt) : "—" }}
              </div>
            </div>
          </div>

          <div class="mt12">
            <a-alert
              v-if="state.eligibility.testStatus === 'COMPLETADO'"
              type="success"
              show-icon
              message="¡Listo! Ya completaste el test."
              description="Ahora puedes revisar los procesos disponibles."
            />
            <a-alert
              v-else-if="!state.eligibility.hasTestAssigned"
              type="info"
              show-icon
              message="Aún no tienes un test asignado."
              description="Vuelve a revisar en unos minutos."
            />
            <a-alert
              v-else
              type="info"
              show-icon
              message="Importante"
              description="Al iniciar o continuar, el tiempo puede comenzar a correr según la configuración del proceso."
            />
          </div>

          <a-alert
            v-if="!state.eligibility.isEligibleToApply && state.eligibility.reasons?.length"
            type="warning"
            show-icon
            message="Requisitos pendientes"
            class="mt12"
          >
            <template #description>
              <ul class="reasons">
                <li v-for="(r, idx) in state.eligibility.reasons" :key="idx">{{ r }}</li>
              </ul>
            </template>
          </a-alert>
        </div>

        <a-divider />



        <a-divider />

        <!-- Procesos -->
        <div class="section">
          <div class="sectionHead">
            <div>
              <div class="sectionTitle">Procesos disponibles</div>
              <div class="sectionSub">Revisa fechas y postula cuando esté habilitado.</div>
            </div>
          </div>

          <div class="tableWrap mt12">
            <a-table
              :columns="processColumns"
              :data-source="state.availableProcesses"
              row-key="id"
              :pagination="{ pageSize: 6 }"
              :scroll="{ x: 720 }"
            >
              <template #bodyCell="{ column, record }">
                <template v-if="column.key === 'startDate'">
                  {{ fmtDate(record.startDate) }}
                </template>

                <template v-else-if="column.key === 'endDate'">
                  {{ fmtDate(record.endDate) }}
                </template>

                <template v-else-if="column.key === 'status'">
                  <a-tag class="chip">{{ record.status }}</a-tag>
                </template>

                <template v-else-if="column.key === 'actions'">
                  <div class="actions">
                    <a-button size="small" block @click="onViewProcess(record)">Ver</a-button>
                    <a-button size="small" type="primary" block :disabled="!record.canApply" @click="onApply(record)">
                      Postular
                    </a-button>
                  </div>

                  <div v-if="!record.canApply" class="microHelp">Este proceso aún no permite postular.</div>
                </template>
              </template>
            </a-table>
          </div>
        </div>

        <a-divider />
  </a-spin>
</template>

<script setup>
import { computed, onMounted, reactive, ref, onBeforeUnmount } from "vue";
import { message, Modal } from "ant-design-vue";
import { useAuthStore } from '../../store/postulanteStore'
const authStore = useAuthStore()

const loading = ref(false);
const nowTick = ref(Date.now());
let timer = null;

const state = reactive({
  applicant: { id: null, nombres: "Postulante", documento: "—" },
  applications: [],
  eligibility: {
    isEligibleToApply: false,
    reasons: [],
    hasTestAssigned: true,
    testStatus: "PENDIENTE", 
    testAvailableAt: null,
    testExpiresAt: null,
    testUrl: null,
  },
  availableProcesses: [],
});


function parseDate(val) {
  if (!val) return null;
  const iso = String(val).includes("T") ? String(val) : String(val).replace(" ", "T");
  const d = new Date(iso);
  return isNaN(d.getTime()) ? null : d;
}
function msToHuman(ms) {
  if (ms <= 0) return "0m";
  const totalMin = Math.floor(ms / 60000);
  const d = Math.floor(totalMin / (60 * 24));
  const h = Math.floor((totalMin % (60 * 24)) / 60);
  const m = totalMin % 60;
  if (d > 0) return `${d}d ${h}h`;
  if (h > 0) return `${h}h ${m}m`;
  return `${m}m`;
}
function fmtDate(val) {
  const d = parseDate(val);
  if (!d) return val || "—";
  const dd = String(d.getDate()).padStart(2, "0");
  const mm = String(d.getMonth() + 1).padStart(2, "0");
  const yyyy = d.getFullYear();
  const hh = String(d.getHours()).padStart(2, "0");
  const mi = String(d.getMinutes()).padStart(2, "0");
  return `${dd}/${mm}/${yyyy} ${hh}:${mi}`;
}


const eligibilityUi = computed(() => {
  return state.eligibility.isEligibleToApply
    ? { badge: "success", text: "Apto para postular" }
    : { badge: "error", text: "No apto para postular" };
});

const testStatusUi = computed(() => {
  const s = state.eligibility.testStatus;
  if (s === "EN_PROGRESO") return { badge: "processing", text: "En progreso" };
  if (s === "COMPLETADO") return { badge: "success", text: "Completado" };
  if (s === "NO_DISPONIBLE") return { badge: "default", text: "No disponible" };
  return { badge: "warning", text: "Pendiente" };
});

const testCtaText = computed(() => {
  const s = state.eligibility.testStatus;
  if (s === "EN_PROGRESO") return "Continuar test";
  if (s === "COMPLETADO") return "Ver estado";
  if (s === "NO_DISPONIBLE") return "No disponible";
  return "Iniciar test";
});

const canStartTest = computed(() => {
  const e = state.eligibility;
  if (!e.hasTestAssigned) return false;
  if (e.testStatus === "COMPLETADO") return false;
  if (e.testStatus === "NO_DISPONIBLE") return false;
  return true;
});

const testExpireMs = computed(() => {
  const d = parseDate(state.eligibility.testExpiresAt);
  if (!d) return null;
  return d.getTime() - nowTick.value;
});

const expiresSoon = computed(() => {
  const ms = testExpireMs.value;
  return ms !== null && ms > 0 && ms <= 24 * 60 * 60 * 1000;
});

const timeRemainingText = computed(() => {
  const ms = testExpireMs.value;
  if (ms === null) return "—";
  if (ms <= 0) return "Vencido";
  return msToHuman(ms);
});


const processColumns = computed(() => [
  { title: "Proceso", dataIndex: "name", key: "name", ellipsis: true },
  { title: "Inicio", dataIndex: "startDate", key: "startDate", responsive: ["md"] },
  { title: "Fin", dataIndex: "endDate", key: "endDate", responsive: ["md"] },
  { title: "Estado", dataIndex: "status", key: "status", responsive: ["sm"] },
  { title: "Vacantes", dataIndex: "vacancies", key: "vacancies", responsive: ["sm"] },
  { title: "Acciones", key: "actions" },
]);


const api = {
  async getDashboard() {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve({
         
          applications: [
            { id: 1, processName: "Admisión 2025-II", status: "NO_APTO", createdAt: "2025-09-05" },
            { id: 2, processName: "Admisión 2026-I", status: "EN_REVISION", createdAt: "2026-02-03" },
            { id: 3, processName: "Admisión 2026-I", status: "APROBADO", createdAt: "2026-02-06" },
          ],
          eligibility: {
            isEligibleToApply: true,
            reasons: [],
            hasTestAssigned: true,
            testStatus: "PENDIENTE",
            testAvailableAt: "2026-02-10 09:00",
            testExpiresAt: "2026-02-20 23:59",
            testUrl: "portal-postulante/test",
          },
          availableProcesses: [
            { id: 10, name: "Admisión 2026-I", startDate: "2026-02-01", endDate: "2026-02-20", status: "ABIERTO", vacancies: 120, canApply: true },
            { id: 11, name: "Admisión Extraordinaria 2026", startDate: "2026-03-01", endDate: "2026-03-10", status: "PRONTO", vacancies: 40, canApply: false },
          ],
        });
      }, 350);
    });
  },
  async startTest() {
    return new Promise((resolve) => setTimeout(resolve, 300));
  },
  async applyToProcess() {
    return new Promise((resolve) => setTimeout(resolve, 300));
  },
};

/** ---------------------------
 * Actions
 * --------------------------- */
async function fetchDashboard() {
  loading.value = true;
  try {
    const data = await api.getDashboard();
    state.applicant = data.applicant;
    state.applications = data.applications;
    state.eligibility = data.eligibility;
    state.availableProcesses = data.availableProcesses;
  } catch {
    message.error("No se pudo cargar el dashboard.");
  } finally {
    loading.value = false;
  }
}

async function onStartTest() {
  if (!canStartTest.value) return;

  Modal.confirm({
    title: "Test de Admisión",
    content: "Al iniciar o continuar, el tiempo puede comenzar a correr según la configuración. ¿Deseas continuar?",
    okText: "Continuar",
    cancelText: "Cancelar",
    async onOk() {
      try {
        await api.startTest();
        if (state.eligibility.testUrl) window.location.href = state.eligibility.testUrl;
      } catch {
        message.error("No se pudo iniciar el test.");
      }
    },
  });
}

async function onApply(process) {
  if (!process.canApply) return;

  Modal.confirm({
    title: "Confirmar postulación",
    content: `¿Deseas postular al proceso "${process.name}"?`,
    okText: "Postular",
    cancelText: "Cancelar",
    async onOk() {
      try {
        await api.applyToProcess(process.id);
        message.success("Postulación registrada.");
        await fetchDashboard();
      } catch {
        message.error("No se pudo completar la postulación.");
      }
    },
  });
}

function onViewProcess(process) {
  message.info(`Abrir detalle del proceso: ${process.name}`);
}

onMounted(async () => {
  await fetchDashboard();
  timer = setInterval(() => (nowTick.value = Date.now()), 1000);
});

onBeforeUnmount(() => {
  if (timer) clearInterval(timer);
});
</script>


<style scoped>


.page {
  width: 100%;
  padding: 12px;
}

.pageCard {
  max-width: 1120px;
  margin: 0 auto;
  border-radius: 14px;
}

/* Header */
.topbar {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  align-items: flex-start;
}

.hello {
  font-size: 24px;
  font-weight: 800;
  color: var(--ant-colorTextHeading, #111827);
}
.sub {
  margin-top: 4px;
  font-size: 12px;
  color: var(--ant-colorTextSecondary, #6b7280);
}

.topbarRight {
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: flex-end;
  min-width: 260px;
}
.statusLine {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.label {
  font-size: 12px;
  color: var(--ant-colorTextSecondary, #6b7280);
}
.btnTop {
  min-width: 180px;
}

/* TEST destacado (sin degradado) */
.testBox {
  border: 2px solid var(--ant-colorPrimary, #1677ff);
  background: var(--ant-colorBgContainer, #fff);
  border-radius: 12px;
  padding: 16px;
}

.testHead {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap; /* ✅ clave para móvil */
  align-items: flex-start;
}

.testTitle {
  font-size: 20px;
  font-weight: 900;
  color: var(--ant-colorTextHeading, #111827);
}
.testSub {
  margin-top: 4px;
  font-size: 12px;
  color: var(--ant-colorTextSecondary, #6b7280);
  line-height: 1.4;
}

.testHeadRight {
  min-width: 260px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-end;
}

.btnTest {
  height: 44px;
  border-radius: 10px;
  font-weight: 800;
}

.testInfoGrid {
  margin-top: 12px;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
}

.infoItem {
  border: 1px solid var(--ant-colorBorderSecondary, rgba(0,0,0,.06));
  background: var(--ant-colorFillAlter, #fafafa);
  border-radius: 10px;
  padding: 10px 12px;
  min-width: 0;
}
.infoK {
  font-size: 12px;
  color: var(--ant-colorTextSecondary, #6b7280);
}
.infoV {
  margin-top: 4px;
  font-weight: 800;
  color: var(--ant-colorText, #111827);
  word-break: break-word;
}

.strong { font-weight: 900; }
.warn { color: var(--ant-colorTextHeading, #111827); }
.hintInline {
  margin-left: 6px;
  font-size: 12px;
  color: var(--ant-colorTextSecondary, #6b7280);
}

.reasons {
  margin: 8px 0 0 18px;
  line-height: 1.7;
}

.summaryBox {
  border: 1px solid var(--ant-colorBorderSecondary, rgba(0,0,0,.06));
  background: var(--ant-colorFillAlter, #fafafa);
  border-radius: 12px;
  padding: 14px;
}
.summaryTitle {
  font-weight: 800;
  color: var(--ant-colorTextHeading, #111827);
  margin-bottom: 10px;
}
.summaryGrid {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 12px;
}
.summaryK {
  font-size: 12px;
  color: var(--ant-colorTextSecondary, #6b7280);
}
.summaryV {
  font-weight: 900;
  color: var(--ant-colorTextHeading, #111827);
}
.chips {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.chip {
  border-radius: 999px;
}

/* Secciones */
.sectionHead {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  align-items: flex-start;
}
.sectionTitle {
  font-size: 20px;
  font-weight: 800;
  color: var(--ant-colorTextHeading, #111827);
}
.sectionSub {
  margin-top: 4px;
  font-size: 12px;
  color: var(--ant-colorTextSecondary, #6b7280);
}

/* Tabla: evita romper en móvil */
.tableWrap {
  width: 100%;
  overflow-x: auto;
}
:deep(.ant-table-container) {
  overflow-x: auto;
}

/* Acciones: en móvil se apilan */
.actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.microHelp {
  margin-top: 6px;
  font-size: 12px;
  color: var(--ant-colorTextSecondary, #6b7280);
}

.listItem {
  padding-left: 0;
  padding-right: 0;
}
.listTitle {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
}
.listName {
  font-weight: 700;
}
.muted {
  color: var(--ant-colorTextSecondary, #6b7280);
}

.mt12 { margin-top: 12px; }

/* ✅ Breakpoints reales */
@media (max-width: 768px) {
  .page { padding: 8px; }

  .topbarRight {
    width: 100%;
    min-width: 0;
    align-items: stretch;
  }
  .btnTop {
    width: 100%;
    min-width: 0;
  }

  .testHeadRight {
    width: 100%;
    min-width: 0;
    align-items: stretch;
  }

  .testInfoGrid {
    grid-template-columns: 1fr; /* ✅ cards info en columna */
  }

  .summaryGrid {
    grid-template-columns: 1fr; /* ✅ resumen en columna */
  }

  .actions {
    grid-template-columns: 1fr; /* ✅ botones uno debajo del otro */
  }
}

@media (max-width: 480px) {
  .testBox { padding: 12px; }
  .testTitle { font-size: 16px; }
}
</style>
