<template>
  <div class="exam-page">
    <!-- HEADER PROFESIONAL -->
    <a-card class="top-card" :bordered="false">
      <div class="topbar">
        <div class="top-left">
          <div class="title">
            <div class="sub">
              <span class="area">{{ examenInfo.area || "Área no disponible" }}</span>
              <span class="sep">•</span>
              <span class="prog">Pregunta {{ indiceActual + 1 }} / {{ totalPreguntas }}</span>
            </div>
          </div>

          <div class="meta">
            <span><b>Duración:</b> {{ examenInfo.duracion }} min</span>
            <span class="sep">•</span>
            <span><b>Intentos:</b> {{ examenInfo.intentos }} / {{ examenInfo.intentos_maximos }}</span>
          </div>

          <a-progress class="progress" :percent="porcentajeCompletado" :show-info="false" />
          <div class="progressText">
            Progreso: <b>{{ preguntasRespondidas }}</b> guardadas de <b>{{ totalPreguntas }}</b>
          </div>
        </div>

        <div class="top-right">
          <div class="statusPill">
            <span class="dot" :class="{ ok: porcentajeCompletado === 100 }"></span>
            <span>{{ porcentajeCompletado === 100 ? "Listo para finalizar" : "En progreso" }}</span>
          </div>

          <div class="timerBox">
            <div class="timerLabel">Tiempo restante</div>
            <a-statistic-countdown
              class="timer"
              :value="timerValue"
              @finish="finalizarExamenAutomaticamente"
              format="HH:mm:ss"
            />
          </div>
        </div>
      </div>
    </a-card>

    <!-- LOADING -->
    <a-card v-if="cargandoInicio" class="card" :bordered="false">
      <a-skeleton active />
    </a-card>

    <!-- CONTENIDO -->
    <a-card v-else-if="preguntaActual" class="card question-card" :bordered="false">
      <!-- Cabecera pregunta -->
      <div class="q-header">
        <div class="q-left">
          <div class="q-number">Pregunta {{ indiceActual + 1 }}</div>

          <div class="q-tags">
            <span v-if="preguntaActual.curso" class="chip">
              {{ preguntaActual.curso }}
            </span>
            <span class="chip muted">
              {{ estadoTexto(preguntaActual) }}
            </span>
          </div>
        </div>
      </div>

      <div class="custom-divider"></div>

      <!-- ENUNCIADO (SIN MARCOS: SOLO TEXTO + LÍNEAS) -->
      <div class="qBody">
        <div class="qStatement">
          <MarkdownLatex :content="preguntaActual.enunciado" />
        </div>

        <div v-if="imagenesPregunta.length" class="imgWrap">
          <a-image-preview-group>
            <div class="imgGrid">
              <a-image
                v-for="(src, i) in imagenesPregunta"
                :key="i"
                :src="src"
                :alt="`Imagen ${i + 1}`"
                class="img"
              />
            </div>
          </a-image-preview-group>
        </div>

        <div v-if="preguntaActual.extra && preguntaActual.extra !== preguntaActual.enunciado" class="qExtra">
          <MarkdownLatex :content="preguntaActual.extra" />
        </div>

        <!-- solo línea -->
        <div class="lineDivider"></div>
      </div>

      <!-- RESPUESTAS (SIN MARCOS: SOLO LÍNEAS) -->
      <div class="answer">
        <div v-if="tieneOpciones(preguntaActual)">
          <a-radio-group
            v-model:value="preguntaActual.respuestaSeleccionada"
            :disabled="preguntaActual.estado === 'respondida' || guardando || finalizando"
            class="radio-group"
          >
            <div class="optList">
              <a-radio
                v-for="op in preguntaActual.opcionesOrdenadas"
                :key="op.key"
                :value="op.key.toString()"
                class="optRow"
              >
                <span class="optKey">{{ getLetraOpcion(op.key) }})</span>
                <span class="optTextInline">
                  <MarkdownLatex :content="op.texto" />
                </span>
              </a-radio>
            </div>
          </a-radio-group>
        </div>

        <!-- Abierta -->
        <div v-else>
          <a-textarea
            v-model:value="preguntaActual.respuestaTexto"
            :rows="6"
            placeholder="Escribe tu respuesta..."
            :disabled="preguntaActual.estado === 'respondida' || guardando || finalizando"
          />
        </div>
      </div>

      <!-- NAV -->
      <div class="nav">
        <a-button :disabled="indiceActual === 0 || guardando || finalizando" @click="irAnterior" class="btn">
          Atrás
        </a-button>

        <a-button
          type="primary"
          :loading="guardando || finalizando"
          @click="siguienteAccion"
          class="btn primary"
        >
          {{ esUltima ? "Guardar y finalizar" : "Siguiente" }}
        </a-button>
      </div>

      <!-- Nota -->
      <div class="note">
        Al presionar <b>Siguiente</b>, tu respuesta se guarda. Evita recargar o cerrar durante el examen.
      </div>
    </a-card>

    <!-- SIN PREGUNTAS -->
    <a-card v-else class="card" :bordered="false">
      <a-alert
        type="warning"
        show-icon
        message="No hay preguntas para mostrar"
        description="Verifica que el examen tenga preguntas generadas."
      />
      <div class="nav" style="margin-top: 12px">
        <a-button @click="router.push({ name: 'DashboardPostulante' })" class="btn">
          Volver
        </a-button>
      </div>
    </a-card>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount, watch, h } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useExamenStore } from "../../store/examen.store";
import { message, Modal, Spin } from "ant-design-vue";
import MarkdownLatex from "../../views/administrador/cursos/MarkdownLatex.vue";

const route = useRoute();
const router = useRouter();
const examenStore = useExamenStore();

const guardando = ref(false);
const finalizando = ref(false);
const timerValue = ref(null);
let timerIntervalId = null;

const preguntasLocal = ref([]);
const indiceActual = ref(0);
const cargandoInicio = ref(false);
const initOnce = ref(false);

/* INFO EXAMEN */
const examenInfo = computed(() => {
  if (!examenStore.examenActual) {
    return { proceso: null, area: null, duracion: 60, intentos: 0, intentos_maximos: 3 };
  }
  return {
    proceso: examenStore.examenActual?.proceso || "Proceso no disponible",
    area: examenStore.examenActual?.area || "Área no disponible",
    duracion: examenStore.examenActual?.duracion || 60,
    intentos: examenStore.examenActual?.intentos || 0,
    intentos_maximos: examenStore.examenActual?.intentos_maximos || 3,
  };
});

/* TRANSFORMAR */
const transformarPreguntas = (arr) => {
  if (!Array.isArray(arr)) return [];
  return arr.map((p) => ({
    ...p,
    opcionesOrdenadas: p.opciones ? [...p.opciones].sort((a, b) => a.key - b.key) : [],
    respuestaSeleccionada: p.respuestaSeleccionada ?? null,
    respuestaTexto: p.respuestaTexto ?? "",
  }));
};

watch(
  () => examenStore.preguntas,
  (nuevas) => {
    if (!Array.isArray(nuevas) || nuevas.length === 0) return;
    if (preguntasLocal.value.length === 0) {
      preguntasLocal.value = transformarPreguntas(nuevas);
      indiceActual.value = 0;
    }
  },
  { immediate: true }
);

/* COMPUTEDS */
const totalPreguntas = computed(() => preguntasLocal.value.length);
const preguntaActual = computed(() => preguntasLocal.value[indiceActual.value] || null);
const esUltima = computed(() => indiceActual.value >= totalPreguntas.value - 1);

const preguntasRespondidas = computed(() => preguntasLocal.value.filter((p) => p.estado === "respondida").length);

const porcentajeCompletado = computed(() => {
  if (!totalPreguntas.value) return 0;
  return Math.round((preguntasRespondidas.value / totalPreguntas.value) * 100);
});

/* HELPERS */
const tieneOpciones = (p) => !!(p?.opciones && p.opciones.length);

const getLetraOpcion = (key) => {
  const letras = ["A", "B", "C", "D", "E", "F", "G", "H"];
  return letras[key] || `Opción ${key}`;
};

const tieneRespuestaLocal = (p) => {
  if (!p) return false;
  if (tieneOpciones(p)) return !!p.respuestaSeleccionada;
  return !!(p.respuestaTexto && p.respuestaTexto.trim());
};

const estadoTexto = (p) => {
  if (p.estado === "respondida") return "Guardada";
  if (tieneRespuestaLocal(p)) return "Sin guardar";
  return "Pendiente";
};

/* NAV */
const irAnterior = () => {
  if (indiceActual.value > 0) indiceActual.value--;
};

const guardarRespuestaDePregunta = async (p) => {
  if (!p) return { success: false, message: "No hay pregunta" };

  if (p.estado === "respondida") return { success: true };

  let respuesta = null;

  if (tieneOpciones(p)) {
    if (p.respuestaSeleccionada) {
      const sel = p.respuestaSeleccionada.toString();
      const op = p.opcionesOrdenadas.find((x) => x.key.toString() === sel);
      respuesta = op ? op.texto : sel;
    }
  } else {
    if (p.respuestaTexto && p.respuestaTexto.trim()) {
      respuesta = p.respuestaTexto.trim();
    }
  }

  return await examenStore.responderPregunta(p.id, respuesta);
};

/* IMÁGENES */
const normalizarImagenes = (imagenes) => {
  if (!imagenes) return [];
  if (Array.isArray(imagenes)) return imagenes.filter(Boolean).map(String);

  if (typeof imagenes === "string") {
    const s = imagenes.trim();
    if (!s) return [];

    if ((s.startsWith("[") && s.endsWith("]")) || (s.startsWith("{") && s.endsWith("}"))) {
      try {
        const parsed = JSON.parse(s);
        if (Array.isArray(parsed)) return parsed.filter(Boolean).map(String);
        if (parsed?.imagenes && Array.isArray(parsed.imagenes)) return parsed.imagenes.filter(Boolean).map(String);
      } catch (_) {}
    }
    return [s];
  }
  return [];
};

const imagenesPregunta = computed(() => normalizarImagenes(preguntaActual.value?.imagenes));

/* ACCIÓN SIGUIENTE */
const siguienteAccion = async () => {
  const p = preguntaActual.value;
  if (!p) return;

  try {
    guardando.value = true;

    const r = await guardarRespuestaDePregunta(p);
    if (!r?.success) {
      message.warning(r?.message || "Completa tu respuesta antes de continuar");
      return;
    }

    p.estado = "respondida";

    if (!esUltima.value) {
      indiceActual.value++;
      return;
    }

    await finalizarExamen();
  } catch (e) {
    console.error(e);
    message.error("Error al guardar");
  } finally {
    guardando.value = false;
  }
};

const finalizarExamen = async () => {
  const examenId = Number(route.params.examenId);

  const modal = Modal.info({
    title: "Procesando calificación",
    content: h("div", { style: "display:flex;align-items:center;gap:12px;" }, [
      h(Spin, { size: "large" }),
      h("div", [
        h("div", { style: "font-weight:600;" }, "Finalizando evaluación"),
        h("div", { style: "margin-top:4px;color:rgba(0,0,0,.65);" }, "Estamos calificando sus respuestas. Por favor, espere..."),
      ]),
    ]),
    maskClosable: false,
    closable: false,
    okButtonProps: { style: { display: "none" } },
  });

  try {
    finalizando.value = true;

    const r = await examenStore.finalizarExamen(examenId);

    const msg = (r?.message || "").toLowerCase();
    if (!r?.success && (msg.includes("ya está finalizado") || msg.includes("ya esta finalizado"))) {
      modal.update({
        title: "Evaluación finalizada",
        content: "El examen ya se encuentra finalizado. Redirigiendo a la página de resultados...",
        okButtonProps: { style: { display: "none" } },
      });

      setTimeout(() => {
        modal.destroy();
        router.push({ name: "PanelResultados", params: { examenId } });
      }, 1200);

      return;
    }

    if (!r?.success) {
      modal.update({
        title: "No se pudo finalizar",
        content: r?.message || "No fue posible finalizar el examen. Inténtelo nuevamente.",
        okButtonProps: { style: { display: "none" } },
      });
      setTimeout(() => modal.destroy(), 1800);
      return;
    }

    setTimeout(() => {
      modal.update({
        title: "Calificación completada",
        content: "Redirigiendo a la página de resultados...",
        okButtonProps: { style: { display: "none" } },
      });

      setTimeout(() => {
        modal.destroy();
        router.push({ name: "PanelResultados", params: { examenId } });
      }, 900);
    }, 5000);
  } catch (e) {
    modal.update({
      title: "Error",
      content: "Ocurrió un problema al finalizar el examen. Por favor, inténtelo nuevamente.",
      okButtonProps: { style: { display: "none" } },
    });
    setTimeout(() => modal.destroy(), 2000);
  } finally {
    setTimeout(() => {
      finalizando.value = false;
    }, 5000);
  }
};

const finalizarExamenAutomaticamente = () => {
  message.error("Tiempo agotado. El examen se finalizará.");
  finalizarExamen();
};

const calcularTiempoRestante = () => {
  if (examenStore.examenActual?.hora_inicio && examenInfo.value.duracion) {
    const inicio = new Date(examenStore.examenActual.hora_inicio);
    const fin = inicio.getTime() + examenInfo.value.duracion * 60 * 1000;
    timerValue.value = fin;
    if (Date.now() > fin) finalizarExamenAutomaticamente();
  } else {
    timerValue.value = Date.now() + examenInfo.value.duracion * 60 * 1000;
  }
};

const iniciarSesionExamen = async () => {
  if (initOnce.value) return;
  initOnce.value = true;

  const examenId = route.params.examenId;
  if (!examenId) {
    message.error("No se encontró el examen");
    router.push({ name: "DashboardPostulante" });
    return;
  }

  try {
    cargandoInicio.value = true;

    const r = await examenStore.iniciarExamen(examenId);
    if (!r?.success) {
      message.error(r?.message || "No se pudo iniciar el examen");
      router.push({ name: "DashboardPostulante" });
      return;
    }

    if (Array.isArray(examenStore.preguntas) && examenStore.preguntas.length) {
      preguntasLocal.value = transformarPreguntas(examenStore.preguntas);
      indiceActual.value = 0;
    } else {
      message.error("No hay preguntas");
      router.push({ name: "DashboardPostulante" });
      return;
    }

    calcularTiempoRestante();
    if (timerIntervalId) clearInterval(timerIntervalId);
    timerIntervalId = setInterval(calcularTiempoRestante, 30000);
  } finally {
    cargandoInicio.value = false;
  }
};

onMounted(iniciarSesionExamen);

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

<style scoped>
.exam-page {
  max-width: 980px;
  margin: 0 auto;
  padding: 18px;
  background: #f5f7fb;
  min-height: 100vh;
}

/* HEADER */
.top-card {
  border-radius: 16px;
  background: #ffffff;
  border: 1px solid rgba(17, 24, 39, 0.08);
  box-shadow: 0 10px 24px rgba(17, 24, 39, 0.06);
  overflow: hidden;
}
.top-card::before {
  content: "";
  display: block;
  height: 6px;
  background: linear-gradient(90deg, #111827, #374151);
}

.topbar {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  align-items: flex-start;
  padding: 14px 16px 16px;
}

.top-left {
  flex: 1;
  min-width: 280px;
}

.sub {
  margin-top: 6px;
  color: #475569;
  font-size: 12px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}

.area {
  font-weight: 800;
  color: #0f172a;
}

.sep {
  opacity: 0.55;
}

.meta {
  margin-top: 10px;
  font-size: 12px;
  color: #64748b;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.progress {
  margin-top: 12px;
}

.progressText {
  margin-top: 6px;
  font-size: 12px;
  color: #64748b;
}

/* top-right */
.top-right {
  min-width: 220px;
  text-align: right;
  display: grid;
  gap: 10px;
  justify-items: end;
}

.statusPill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 999px;
  border: 1px solid rgba(17, 24, 39, 0.10);
  background: #f8fafc;
  color: #334155;
  font-size: 12px;
  font-weight: 800;
}

.statusPill .dot {
  width: 10px;
  height: 10px;
  border-radius: 99px;
  background: #f59e0b;
}
.statusPill .dot.ok {
  background: #22c55e;
}

.timerBox {
  width: 100%;
  padding: 10px 12px;
  border-radius: 14px;
  border: 1px solid rgba(17, 24, 39, 0.10);
  background: #ffffff;
}

.timerLabel {
  font-size: 12px;
  color: #64748b;
  font-weight: 800;
  margin-bottom: 4px;
}

.timer :deep(.ant-statistic-content) {
  font-size: 28px;
  font-weight: 1000;
  color: #0f172a;
  letter-spacing: 0.6px;
}

/* CARDS */
.card {
  margin-top: 14px;
  border-radius: 18px;
  background: #fff;
  border: 1px solid rgba(17, 24, 39, 0.08);
  box-shadow: 0 8px 20px rgba(17, 24, 39, 0.05);
}

.question-card {
  padding-bottom: 10px;
}

/* PREGUNTA */
.q-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 16px 6px;
}

.q-number {
  font-weight: 1000;
  color: #0f172a;
  font-size: 15px;
}

.q-tags {
  margin-top: 8px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.chip {
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 10px;
  border-radius: 999px;
  background: #eef2ff;
  color: #1f2937;
  font-size: 12px;
  font-weight: 900;
  border: 1px solid rgba(17, 24, 39, 0.08);
}

.chip.muted {
  background: #f1f5f9;
  color: #334155;
}

/* divisor bajo el header de pregunta */
.custom-divider {
  margin: 0 16px 8px;
  height: 1px;
  background: rgba(15, 23, 42, 0.10);
}

/* ===== ENUNCIADO SIN MARCO (solo texto + aire) ===== */
.qBody {
  margin: 0 16px 10px;
}

.qStatement,
.qExtra {
  padding: 8px 0;
  line-height: 1.75;
  color: #0f172a;
  overflow-wrap: anywhere;
}

/* Separador tipo examen (solo línea) */
.lineDivider {
  margin: 12px 0 6px;
  height: 1px;
  background: rgba(15, 23, 42, 0.10);
}

/* KaTeX: aire arriba/abajo sin “flechas” */
.qBody :deep(.katex-display) {
  margin: 14px 0;
  padding: 8px 0;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
}
.qBody :deep(.katex-display::-webkit-scrollbar) {
  height: 0px;
}

/* IMÁGENES */
.imgWrap { margin-top: 10px; }
.imgGrid {
  display: grid;
  grid-template-columns: repeat(1, minmax(0, 520px));
  gap: 10px;
  justify-content: center;
}
.img :deep(img) {
  width: 100%;
  height: 260px;
  object-fit: contain;
  border-radius: 12px;
  border: 1px solid rgba(17, 24, 39, 0.10);
  background: #fff;
}

/* ===== OPCIONES SIN MARCOS: solo líneas ===== */
.answer {
  margin: 0 16px;
  padding-bottom: 6px;
}

.radio-group { width: 100%; }

.optList {
  display: flex;
  flex-direction: column;
}

/* cada opción = una fila con solo línea abajo */
.optRow {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 2px;
  margin: 0;
  border-bottom: 1px solid rgba(15, 23, 42, 0.10);
}

/* radio alineado */
.optRow :deep(.ant-radio) {
  align-self: flex-start;
  margin-top: 2px;
}

/* A) y texto en una sola fila */
.optKey {
  flex: 0 0 auto;
  min-width: 28px;
  font-weight: 1000;
  color: #0f172a;
  line-height: 1.4;
}

.optTextInline {
  flex: 1 1 auto;
  min-width: 0;
  color: #0f172a;
  line-height: 1.6;
  overflow-wrap: anywhere;
}

/* seleccionado (sin caja) */
.optRow:has(:deep(.ant-radio-checked)) {
  background: rgba(37, 99, 235, 0.06);
}

/* hover suave */
.optRow:hover {
  background: rgba(15, 23, 42, 0.03);
}

/* Textarea */
:deep(.ant-input) {
  border-radius: 12px;
}
:deep(.ant-input:focus),
:deep(.ant-input-focused) {
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}

/* NAV */
.nav {
  margin: 16px 16px 0;
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding-bottom: 6px;
}

.btn {
  height: 42px;
  border-radius: 12px;
  font-weight: 900;
  min-width: 150px;
}

.primary {
  min-width: 230px;
}

/* Nota */
.note {
  margin: 12px 16px 16px;
  font-size: 12px;
  color: #64748b;
  line-height: 1.6;
  padding: 10px 12px;
  border-radius: 12px;
  background: #f8fafc;
  border: 1px dashed rgba(17, 24, 39, 0.14);
}

/* Responsive */
@media (max-width: 640px) {
  .exam-page {
    padding: 10px;
  }

  .top-right {
    text-align: left;
    justify-items: start;
    min-width: 100%;
  }

  .qBody,
  .answer {
    margin: 0 12px;
  }

  .nav {
    flex-direction: column;
    margin: 14px 12px 0;
  }

  .btn,
  .primary {
    width: 100%;
    min-width: 0;
  }

  .img :deep(img) {
    height: 220px;
  }

  .optRow {
    padding: 12px 0;
  }
}
</style>