"use client";
import { formatDuration } from "@/lib/aula/duration";
import SystemAlert from "@/components/ui/SystemAlert";
import Link from "next/link";
import { useCallback, useEffect, useRef, useState, useTransition } from "react";
import { Button, ProgressBar, Radio, RadioGroup } from "@heroui/react";
import { ArrowLeft, ArrowRight, Check, Clock3, RotateCcw } from "lucide-react";
import { iniciarEvaluacion, responderEvaluacion } from "@/app/actions/aprendizaje";
import type { AssessmentView } from "@/lib/alumno/learning";

type Props = {
  aulaId: number;
  evaluacionId: string;
  titulo: string;
  retornoId: string;
  total: number;
  minutos: number | null;
  minima: number;
};
export default function AulaEvaluacion({
  aulaId,
  evaluacionId,
  titulo,
  retornoId,
  total,
  minutos,
  minima,
}: Props) {
  const [view, setView] = useState<AssessmentView | null>(null);
  const [answer, setAnswer] = useState<string | null>(null);
  const [error, setError] = useState("");
  const [pending, transition] = useTransition();
  const [remaining, setRemaining] = useState<number | null>(null);
  const expirySent = useRef(false);
  const back = `/aula/${aulaId}?actividad=${encodeURIComponent(retornoId)}`;
  function start(retry = false) {
    transition(async () => {
      try {
        const result = await iniciarEvaluacion(aulaId, evaluacionId, retry);
        if (result.ok) {
          setView(result.vista);
          setAnswer(null);
          setError("");
          expirySent.current = false;
        } else setError(result.error);
      } catch {
        setError("No se pudo iniciar la evaluación. Revisa tu conexión.");
      }
    });
  }
  const submit = useCallback(
    (expired = false) => {
      if (!view || view.tipo !== "pregunta" || pending || (!expired && answer === null)) return;
      transition(async () => {
        try {
          const result = await responderEvaluacion(
            aulaId,
            evaluacionId,
            view.intentoId,
            view.indice,
            expired ? null : Number(answer),
          );
          if (result.ok) {
            setView(result.vista);
            setAnswer(null);
            setError("");
          } else {
            setError(result.error);
            expirySent.current = false;
          }
        } catch {
          setError("No se guardó tu respuesta. Reintenta para continuar.");
          expirySent.current = false;
        }
      });
    },
    [aulaId, evaluacionId, view, answer, pending],
  );
  useEffect(() => {
    if (view?.tipo !== "pregunta" || !view.vence) return;
    const tick = () => {
      const seconds = Math.max(0, Math.ceil((view.vence! - Date.now()) / 1000));
      setRemaining(seconds);
      if (seconds === 0 && !expirySent.current && !pending) {
        expirySent.current = true;
        submit(true);
      }
    };
    tick();
    const timer = window.setInterval(tick, 1000);
    return () => window.clearInterval(timer);
  }, [view, submit, pending]);
  return (
    <main className="flex min-h-dvh w-full flex-col bg-[#fafafa] text-zinc-900">
      <header className="flex items-center justify-between gap-4 border-b border-zinc-200/70 bg-white px-4 py-4 sm:px-8">
        <Link
          href={back}
          className="action-link inline-flex shrink-0 items-center gap-2 text-sm text-zinc-600"
        >
          <ArrowLeft className="size-4" />
          Volver al aula
        </Link>
        <p className="truncate text-sm font-medium">{titulo}</p>
        {view?.tipo === "pregunta" && remaining !== null ? (
          <span className="inline-flex shrink-0 items-center gap-1.5 text-sm tabular-nums text-zinc-500">
            <Clock3 className="size-4" />
            {formatDuration(remaining)}
          </span>
        ) : (
          <span className="hidden text-xs text-zinc-400 sm:block">Evaluación</span>
        )}
      </header>
      <div className="mx-auto flex w-full max-w-2xl flex-1 flex-col justify-center px-5 py-10 sm:py-14">
        {!view ? (
          <div className="space-y-6">
            <p className="text-xs font-medium uppercase tracking-widest text-zinc-400">
              Antes de comenzar
            </p>
            <h1 className="text-2xl font-semibold leading-snug sm:text-3xl">{titulo}</h1>
            <p className="text-sm leading-relaxed text-zinc-500">
              Responde una pregunta a la vez. Cada respuesta se guarda al continuar. Puedes salir y
              retomar el intento; el tiempo seguirá corriendo.
            </p>
            <div className="flex flex-wrap gap-x-6 gap-y-2 border-y border-zinc-200 py-4 text-sm text-zinc-600">
              <span>{total} preguntas</span>
              <span>
                {minutos ? formatDuration(Math.round(minutos * 60)) : "Sin límite de tiempo"}
              </span>
              <span>Mínimo: {minima}%</span>
            </div>
            <Button
              variant="secondary"
              isPending={pending}
              onPress={() => start()}
              className="bg-[#9d2449] px-6 text-white hover:bg-[#801c3a] rounded-full"
            >
              Comenzar o retomar
              <ArrowRight className="size-4" />
            </Button>
          </div>
        ) : view.tipo === "pregunta" ? (
          <div key={`${view.intentoId}-${view.indice}`} className="space-y-7">
            <div className="space-y-3">
              <p className="text-xs font-medium text-zinc-500">
                Pregunta {view.indice + 1} de {view.total}
              </p>
              <ProgressBar
                aria-label="Preguntas respondidas"
                value={view.indice}
                maxValue={view.total}
              >
                <ProgressBar.Track className="h-1">
                  <ProgressBar.Fill className="bg-zinc-800" />
                </ProgressBar.Track>
              </ProgressBar>
            </div>
            <h1
              id="pregunta-actual"
              className="whitespace-pre-wrap break-words text-xl font-semibold leading-relaxed sm:text-2xl"
            >
              {view.pregunta.texto}
            </h1>
            <RadioGroup
              aria-labelledby="pregunta-actual"
              value={answer}
              onChange={setAnswer}
              isDisabled={pending || remaining === 0}
              className="gap-3"
            >
              {view.pregunta.opciones.map((option, index) => (
                <Radio
                  key={index}
                  value={String(index)}
                  className={`w-full rounded-xl border p-4 transition-colors ${answer === String(index) ? "border-zinc-800 bg-zinc-100" : "border-zinc-200 bg-white hover:border-zinc-400"}`}
                >
                  <Radio.Content>
                    <Radio.Control>
                      <Radio.Indicator />
                    </Radio.Control>
                    <span className="min-w-0 whitespace-pre-wrap break-words text-sm leading-relaxed">
                      {option}
                    </span>
                  </Radio.Content>
                </Radio>
              ))}
            </RadioGroup>
            <div className="flex items-center justify-between gap-3 border-t border-zinc-200 pt-5">
              <p className="text-xs text-zinc-400">Tu respuesta se guarda al continuar.</p>
              <Button
                variant="secondary"
                isPending={pending}
                isDisabled={answer === null || remaining === 0}
                onPress={() => submit()}
                className="shrink-0 bg-zinc-900 px-5 text-white hover:bg-zinc-700 rounded-full"
              >
                {view.indice + 1 === view.total ? "Finalizar" : "Continuar"}
                <ArrowRight className="size-4" />
              </Button>
            </div>
          </div>
        ) : (
          <div className="space-y-6">
            <span className="inline-flex size-12 items-center justify-center rounded-full bg-zinc-100">
              {view.aprobado ? (
                <Check className="size-6 text-emerald-700" />
              ) : (
                <RotateCcw className="size-5 text-zinc-600" />
              )}
            </span>
            <h1 className="text-3xl font-semibold">
              {view.aprobado
                ? "Evaluación aprobada"
                : view.expirado
                  ? "El tiempo ha terminado"
                  : "Puedes volver a intentarlo"}
            </h1>
            <p className="text-sm leading-relaxed text-zinc-500">
              {view.aprobado
                ? "Tu resultado se guardó. Ya puedes continuar con el curso."
                : `Necesitas al menos ${view.minima}% para continuar. Repasa la clase y vuelve a realizar la evaluación.`}
            </p>
            <div className="flex items-end gap-3 border-y border-zinc-200 py-5">
              <p className="text-5xl font-semibold tracking-tight">
                {view.calificacion}
                <span className="text-xl text-zinc-400">%</span>
              </p>
              <p className="pb-1 text-sm text-zinc-500">
                {view.correctas} de {view.total} respuestas correctas
              </p>
            </div>
            {!view.aprobado && (
              <p className="text-sm text-zinc-500">
                {view.intentosRestantes
                  ? `Intentos restantes: ${view.intentosRestantes}. Espera antes de reintentar.`
                  : "Has alcanzado el límite de intentos. Comunícate con tu instructor."}
              </p>
            )}
            <div className="flex flex-wrap gap-3">
              <Link
                href={back}
                className="inline-flex min-h-10 items-center gap-2 rounded-xl bg-zinc-900 px-5 py-2 text-sm font-medium text-white hover:bg-zinc-700"
              >
                {view.aprobado ? "Continuar en el aula" : "Repasar la clase"}
                <ArrowRight className="size-4" />
              </Link>
              {!view.aprobado && view.intentosRestantes > 0 && (
                <Button
                  className="rounded-full"
                  variant="secondary"
                  isPending={pending}
                  onPress={() => start(true)}
                >
                  Intentar de nuevo
                </Button>
              )}
            </div>
          </div>
        )}
        {error && (
          <SystemAlert status="danger" title="No se pudo continuar la evaluación" className="mt-5">
            {error}
          </SystemAlert>
        )}
      </div>
    </main>
  );
}
