"use client";
import { formatDuration } from "@/lib/aula/duration";
import { useConfirmDialog } from "@/components/ui/useConfirmDialog";
import ModuleManager from "./aula/ModuleManager";
import CourseVideo from "@/components/ui/CourseVideo";
import SystemAlert from "@/components/ui/SystemAlert";
import { createEditorId } from "@/lib/aula/client-id";
import ResourceLink from "@/components/ui/ResourceLink";
import { useRef, useState } from "react";
import {
  ClipboardList,
  FileCheck2,
  FolderOpen,
  MessageSquare,
  Plus,
  Send,
  Settings2,
  Trash2,
  Video,
  Eye,
  Pencil,
} from "lucide-react";
import { moveTimelineGroup, normalizeTimeline, timelineGroups } from "@/lib/aula/timeline";
import {
  courseHours,
  courseSchema,
  type CourseDocument,
  type CourseSession,
  type DidacticMaterial,
} from "@/lib/aula/schema";
import { useCourseEditor } from "./aula/useCourseEditor";
import { IconActionButton, ActionButton, Field, Panel, TextField, fileHref } from "./aula/EditorUI";
import SessionEditor from "./aula/SessionEditor";
import MaterialEditor from "./aula/MaterialEditor";
import AulaForum from "./aula/AulaForum";
import AulaComponentsSettings from "./aula/AulaComponentsSettings";
import AulaTimeline from "./aula/AulaTimeline";

const tabs = [
  { id: "informacion", label: "Información", icon: Settings2 },
  { id: "videos", label: "Videoclases", icon: Video },
  { id: "material", label: "Materiales", icon: FolderOpen },
  { id: "tareas", label: "Tareas", icon: ClipboardList },
  { id: "evaluaciones", label: "Evaluaciones", icon: FileCheck2 },
  { id: "foro", label: "Foro", icon: MessageSquare },
  { id: "publicacion", label: "Publicación", icon: Send },
] as const;
type Tab = (typeof tabs)[number]["id"];
type Props = {
  aulaId: number;
  instructorId: number;
  titulo: string;
  horas: number;
  initial: CourseDocument;
  version: string;
  initialTab?: string;
};
export default function DashboardAulaForm({
  aulaId,
  instructorId,
  titulo,
  horas,
  initial,
  version,
  initialTab,
}: Props) {
  const { ask, confirmationDialog } = useConfirmDialog();
  const confirmDiscard = () =>
    ask({
      title: "¿Descartar los cambios del formulario?",
      description: "Los cambios que no hayas aplicado al contenido se descartarán.",
      confirmLabel: "Descartar cambios",
      status: "warning",
    });
  const editor = useCourseEditor(aulaId, instructorId, initial, version);
  const { course: allCourse, update: updateAll } = editor;
  const [moduleId, setModuleId] = useState<string | null>(null);
  const activeModule = allCourse.modulos.find((m) => m.id === moduleId);
  const course: CourseDocument = activeModule
    ? {
        ...allCourse,
        descripcion: activeModule.descripcion,
        componentes: activeModule.componentes,
        sesiones: allCourse.sesiones.filter((s) => s.moduloId === activeModule.id),
        materiales: allCourse.materiales.filter((m) => m.moduloId === activeModule.id),
      }
    : allCourse;
  function update(next: CourseDocument) {
    if (!activeModule) return updateAll(next);
    const sessions = [
      ...allCourse.sesiones.filter((s) => s.moduloId !== activeModule.id),
      ...next.sesiones.map((s) => ({ ...s, moduloId: activeModule.id })),
    ];
    updateAll({
      ...allCourse,
      descripcion: allCourse.descripcion,
      estatus: next.estatus,
      porcentajes: next.porcentajes,
      modulos: allCourse.modulos.map((m) =>
        m.id === activeModule.id
          ? { ...m, descripcion: next.descripcion, componentes: next.componentes }
          : m,
      ),
      sesiones: allCourse.modulos
        .flatMap((m) => sessions.filter((s) => s.moduloId === m.id))
        .map((s, i) => ({ ...s, orden: i + 1 })),
      materiales: [
        ...allCourse.materiales.filter((m) => m.moduloId !== activeModule.id),
        ...next.materiales.map((m) => ({ ...m, moduloId: activeModule.id })),
      ],
    });
  }
  const [tab, setTab] = useState<Tab>(() => tabs.find((t) => t.id === initialTab)?.id ?? "videos");
  const [session, setSession] = useState<CourseSession | null>(null);
  const [material, setMaterial] = useState<DidacticMaterial | null>(null);
  const [preview, setPreview] = useState<CourseSession | null>(null);
  const [search, setSearch] = useState("");
  const componentsDialog = useRef<HTMLDialogElement>(null);
  const videos = course.sesiones.filter((s) => s.tipo === "video");
  const tasks = course.sesiones.filter((s) => s.tipo === "tarea");
  const examinations = course.sesiones.filter(
    (s) => s.tipo === "examen" || s.tipo === "evaluacion",
  );
  const hours = courseHours(course.sesiones);
  const validation = courseSchema.safeParse(allCourse);
  async function changeTab(next: Tab) {
    if ((session || material) && !(await confirmDiscard())) return;
    setSession(null);
    setMaterial(null);
    setPreview(null);
    setTab(next);
  }
  async function addSession(tipo: CourseSession["tipo"]) {
    if (session && !(await confirmDiscard())) return;
    setSession({
      id: createEditorId(),
      moduloId: activeModule?.id,
      tipo,
      titulo: "",
      orden: course.sesiones.length + 1,
      ...(tipo === "video"
        ? { duracionMinutos: 0, objetivos: [] }
        : tipo === "tarea"
          ? {
              puntosMaximos: 100,
              ponderacion: 20,
              formatoEntrega: "Archivo digital (PDF, ZIP, DOCX)",
            }
          : {
              tiempoLimiteMinutos: 30,
              calificacionMinima: 80,
              momentoEvaluacion: "modular",
              tipoExamen: "parcial",
              questions: [],
              preguntas: [],
            }),
    });
    setPreview(null);
  }
  function saveSession(next: CourseSession) {
    const exists = course.sesiones.some((s) => s.id === next.id);
    update({
      ...course,
      sesiones: normalizeTimeline(
        exists
          ? course.sesiones.map((s) => (s.id === next.id ? next : s))
          : [...course.sesiones, next],
      ),
    });
    setSession(null);
  }
  async function deleteSession(item: CourseSession) {
    const linked =
      course.sesiones.some((s) => s.claseVinculadaId === item.id) ||
      course.materiales.some((m) => m.claseVinculadaId === item.id);
    if (
      !(await ask({
        title: `¿Eliminar «${item.titulo}»?`,
        description: `Se quitará esta actividad del módulo.${linked ? " Los contenidos vinculados quedarán sin videoclase." : ""}`,
        confirmLabel: "Eliminar actividad",
      }))
    )
      return;
    update({
      ...course,
      sesiones: course.sesiones
        .filter((s) => s.id !== item.id)
        .map((s, i) => ({
          ...s,
          orden: i + 1,
          ...(s.claseVinculadaId === item.id
            ? { claseVinculadaId: "", claseVinculadaTitulo: "" }
            : {}),
        })),
      materiales: course.materiales.map((m) =>
        m.claseVinculadaId === item.id ? { ...m, claseVinculadaId: "" } : m,
      ),
    });
    if (session?.id === item.id) setSession(null);
  }
  function move(id: string, target: number) {
    const sesiones = moveTimelineGroup(course.sesiones, id, target);
    if (sesiones !== course.sesiones) update({ ...course, sesiones });
  }
  function newMaterial() {
    setMaterial({
      id: createEditorId(),
      moduloId: activeModule?.id,
      titulo: "",
      descripcion: "",
      categoria: "Manual Técnico",
      archivoUrl: "",
      archivoNombre: "",
      tamano: "",
      fechaSubida: new Date().toISOString(),
    });
  }
  function rows(items: CourseSession[]) {
    if (!items.length)
      return <p className="py-4 text-sm text-zinc-500">Aún no hay contenido en esta sección.</p>;
    return (
      <ul className="divide-y divide-zinc-100">
        {items.map((item) => {
          const position = timelineGroups(course.sesiones).findIndex(
            (group) =>
              group.item.id === item.id ||
              group.evaluations.some((evaluation) => evaluation.id === item.id),
          );
          const Icon =
            item.tipo === "video" ? Video : item.tipo === "tarea" ? ClipboardList : FileCheck2;
          return (
            <li
              key={item.id}
              className="flex min-w-0 flex-col justify-between gap-3 py-4 sm:flex-row sm:items-center"
            >
              <div className="flex min-w-0 items-start gap-3">
                <div className="rounded-lg bg-[#9d2449]/7 p-2 text-[#9d2449]">
                  <Icon className="size-4" aria-hidden="true" />
                </div>
                <div className="min-w-0">
                  <h3 className="break-words text-sm font-medium">
                    {position + 1}. {item.titulo}
                  </h3>
                  <p className="mt-1 text-xs text-zinc-500">
                    {item.tipo === "video"
                      ? formatDuration(Math.round((item.duracionMinutos ?? 0) * 60))
                      : item.tipo === "tarea"
                        ? `Entrega: ${item.fechaEntrega?.replace("T", " ") || "Sin fecha"}`
                        : `${(item.questions ?? item.preguntas ?? []).length} preguntas · ${item.tiempoLimiteMinutos ?? 0} min`}
                  </p>
                </div>
              </div>
              <div className="flex shrink-0 flex-wrap gap-2">
                <IconActionButton
                  aria-label={`Vista previa de ${item.titulo}`}
                  onClick={() => setPreview(item)}
                >
                  <Eye className="size-4" />
                </IconActionButton>
                <IconActionButton
                  aria-label={`Editar ${item.titulo}`}
                  onClick={async () => {
                    if (session && !(await confirmDiscard())) return;
                    setSession(item);
                    setPreview(null);
                    setTab(
                      item.tipo === "video"
                        ? "videos"
                        : item.tipo === "tarea"
                          ? "tareas"
                          : "evaluaciones",
                    );
                  }}
                >
                  <Pencil className="size-4" />
                </IconActionButton>
                <IconActionButton
                  aria-label={`Eliminar ${item.titulo}`}
                  onClick={() => deleteSession(item)}
                >
                  <Trash2 className="size-4" />
                </IconActionButton>
              </div>
            </li>
          );
        })}
      </ul>
    );
  }
  const sectionDisabled =
    tab === "videos"
      ? !course.componentes.modulos
      : tab === "material"
        ? !course.componentes.material
        : tab === "tareas"
          ? !course.componentes.tareas
          : tab === "evaluaciones"
            ? !course.componentes.evaluacion && !course.componentes.examen
            : tab === "foro"
              ? !course.componentes.foro
              : false;
  return (
    <div className="space-y-5">
      {confirmationDialog}
      {activeModule && (
        <div className="flex flex-wrap items-center gap-3">
          <ActionButton
            onClick={async () => {
              if ((session || material) && !(await confirmDiscard())) return;
              setSession(null);
              setMaterial(null);
              setPreview(null);
              setModuleId(null);
            }}
          >
            Volver a módulos
          </ActionButton>
          <h2 className="text-lg font-semibold">{activeModule.titulo} · Gestión de componentes</h2>
        </div>
      )}
      <div className="flex flex-wrap items-center justify-between gap-3 rounded-2xl border border-zinc-200 bg-white p-4">
        <div className="flex flex-wrap items-center gap-3">
          <span
            className={`rounded-full px-3 py-1 text-xs font-medium ${editor.savedStatus === "PUBLICADO" ? "bg-green-50 text-green-700" : "bg-zinc-100 text-zinc-600"}`}
          >
            {editor.savedStatus === "PUBLICADO" ? "Publicado" : "Borrador"}
          </span>
          <span role="status" className="text-xs text-zinc-500">
            {editor.status}
          </span>
        </div>
        <div className="flex flex-wrap gap-2">
          {activeModule && (
            <ActionButton onClick={() => componentsDialog.current?.showModal()}>
              <Settings2 className="size-4" />
              Configurar componentes
            </ActionButton>
          )}
          <ActionButton
            disabled={editor.pending || !!session || !!material}
            onClick={() => editor.save()}
          >
            Guardar cambios
          </ActionButton>
        </div>
      </div>
      {!validation.success && !editor.error && (
        <SystemAlert status="warning" title="Revisa el contenido antes de guardar">
          {validation.error.issues[0]?.message}
        </SystemAlert>
      )}
      {editor.error && (
        <SystemAlert status="danger" title="No se pudieron guardar los cambios">
          {editor.error}
        </SystemAlert>
      )}
      {editor.recovery && (
        <SystemAlert
          status="warning"
          title="Hay cambios sin guardar"
          action={
            <>
              <ActionButton onClick={editor.restore}>Recuperar copia</ActionButton>
              <ActionButton
                onClick={async () => {
                  if (
                    await ask({
                      title: "¿Descartar la copia local?",
                      description:
                        "Se eliminará la copia de recuperación de este curso. El contenido guardado en el servidor se conserva.",
                      confirmLabel: "Descartar copia",
                      status: "warning",
                    })
                  )
                    editor.dismissRecovery();
                }}
              >
                Descartar copia
              </ActionButton>
            </>
          }
        >
          Hay una copia local. Recuperarla reemplazará el contenido abierto.
        </SystemAlert>
      )}
      {!activeModule ? (
        <ModuleManager
          course={allCourse}
          onChange={updateAll}
          onSelect={(id) => {
            setModuleId(id);
            setTab("videos");
            setSearch("");
          }}
        />
      ) : (
        <>
          <AulaComponentsSettings dialogRef={componentsDialog} course={course} onChange={update} />
          <div className="grid min-w-0 items-start gap-5 xl:grid-cols-[minmax(0,1.8fr)_minmax(24rem,1fr)]">
            <div className="min-w-0 space-y-5">
              <div
                role="tablist"
                aria-label="Secciones de gestión del aula"
                className="flex flex-wrap gap-2"
              >
                {tabs.map((t, index) => (
                  <button
                    type="button"
                    role="tab"
                    id={`tab-${t.id}`}
                    aria-controls={`panel-${t.id}`}
                    aria-selected={tab === t.id}
                    tabIndex={tab === t.id ? 0 : -1}
                    key={t.id}
                    onClick={() => changeTab(t.id)}
                    onKeyDown={(e) => {
                      if (e.key === "ArrowRight" || e.key === "ArrowLeft") {
                        e.preventDefault();
                        const next =
                          tabs[
                            (index + (e.key === "ArrowRight" ? 1 : tabs.length - 1)) % tabs.length
                          ];
                        changeTab(next.id);
                        document.getElementById(`tab-${next.id}`)?.focus();
                      }
                    }}
                    className={`inline-flex items-center gap-2 rounded-xl px-3 py-2.5 text-sm transition-colors motion-reduce:transition-none ${tab === t.id ? "bg-[#9d2449] text-white" : "bg-white text-zinc-500 hover:bg-zinc-100 hover:text-zinc-900"}`}
                  >
                    <t.icon className="size-4" aria-hidden="true" />
                    {t.label}
                  </button>
                ))}
              </div>
              <div
                role="tabpanel"
                id={`panel-${tab}`}
                aria-labelledby={`tab-${tab}`}
                className="space-y-5"
              >
                {sectionDisabled ? (
                  <Panel title="Componente desactivado">
                    <p className="text-sm text-zinc-500">
                      Puedes activarlo en la configuración de componentes. Su contenido se conserva.
                    </p>
                    <ActionButton
                      className="mt-4"
                      onClick={() => componentsDialog.current?.showModal()}
                    >
                      Configurar componentes
                    </ActionButton>
                  </Panel>
                ) : (
                  <>
                    {tab === "informacion" && (
                      <>
                        <Panel title="Información del módulo">
                          <div className="mb-5 grid gap-3 sm:grid-cols-2">
                            <div className="rounded-xl bg-zinc-50 p-4">
                              <p className="text-xs text-zinc-500">Nombre oficial</p>
                              <p className="mt-1 text-sm font-medium">{titulo}</p>
                            </div>
                            <div className="rounded-xl bg-zinc-50 p-4">
                              <p className="text-xs text-zinc-500">Duración oficial</p>
                              <p className="mt-1 text-sm font-medium">{horas} horas</p>
                            </div>
                          </div>
                          <TextField
                            label="Descripción del módulo"
                            value={course.descripcion}
                            maxLength={20000}
                            onChange={(e) => update({ ...course, descripcion: e.target.value })}
                          />
                          <p className="mt-2 text-xs text-zinc-400">
                            El nombre y la duración corresponden al registro institucional.
                          </p>
                        </Panel>
                      </>
                    )}
                    {tab === "videos" && (
                      <>
                        <Panel
                          title="Videoclases"
                          action={
                            <ActionButton primary onClick={() => addSession("video")}>
                              <Plus className="size-4" />
                              Nueva videoclase
                            </ActionButton>
                          }
                        >
                          {rows(videos)}
                        </Panel>
                        {session?.tipo === "video" && (
                          <SessionEditor
                            key={session.id}
                            draftKey={`neo:form:${instructorId}:${aulaId}:${moduleId}:${session.tipo}:${course.sesiones.some((s) => s.id === session.id) ? session.id : "new"}`}
                            aulaId={aulaId}
                            initial={session}
                            videos={videos}
                            onSave={saveSession}
                            onCancel={() => setSession(null)}
                          />
                        )}
                      </>
                    )}
                    {tab === "tareas" && (
                      <>
                        <Panel
                          title="Tareas y prácticas"
                          action={
                            <ActionButton primary onClick={() => addSession("tarea")}>
                              <Plus className="size-4" />
                              Nueva tarea
                            </ActionButton>
                          }
                        >
                          {rows(tasks)}
                        </Panel>
                        {session?.tipo === "tarea" && (
                          <SessionEditor
                            key={session.id}
                            draftKey={`neo:form:${instructorId}:${aulaId}:${moduleId}:${session.tipo}:${course.sesiones.some((s) => s.id === session.id) ? session.id : "new"}`}
                            aulaId={aulaId}
                            initial={session}
                            videos={videos}
                            onSave={saveSession}
                            onCancel={() => setSession(null)}
                          />
                        )}
                      </>
                    )}
                    {tab === "evaluaciones" && (
                      <>
                        <Panel
                          title="Evaluaciones y exámenes"
                          action={
                            <ActionButton
                              primary
                              onClick={() =>
                                addSession(course.componentes.evaluacion ? "evaluacion" : "examen")
                              }
                            >
                              <Plus className="size-4" />
                              Nueva evaluación
                            </ActionButton>
                          }
                        >
                          {rows(examinations)}
                        </Panel>
                        {session &&
                          (session.tipo === "examen" || session.tipo === "evaluacion") && (
                            <SessionEditor
                              key={session.id}
                              draftKey={`neo:form:${instructorId}:${aulaId}:${moduleId}:${session.tipo}:${course.sesiones.some((s) => s.id === session.id) ? session.id : "new"}`}
                              aulaId={aulaId}
                              initial={session}
                              videos={videos}
                              onSave={saveSession}
                              onCancel={() => setSession(null)}
                            />
                          )}
                      </>
                    )}
                    {tab === "material" && (
                      <>
                        <Panel
                          title="Biblioteca de materiales"
                          action={
                            <ActionButton primary onClick={newMaterial}>
                              <Plus className="size-4" />
                              Nuevo material
                            </ActionButton>
                          }
                        >
                          <Field
                            label="Buscar material"
                            type="search"
                            value={search}
                            onChange={(e) => setSearch(e.target.value)}
                          />
                          <ul className="mt-4 divide-y divide-zinc-100">
                            {course.materiales
                              .filter((m) =>
                                `${m.titulo} ${m.categoria}`
                                  .toLocaleLowerCase("es-MX")
                                  .includes(search.toLocaleLowerCase("es-MX")),
                              )
                              .map((m) => (
                                <li
                                  key={m.id}
                                  className="flex flex-col justify-between gap-3 py-4 sm:flex-row sm:items-center"
                                >
                                  <div className="min-w-0">
                                    <ResourceLink
                                      url={fileHref(aulaId, m.archivoUrl)}
                                      title={m.titulo}
                                      filename={m.archivoNombre}
                                      className="break-words text-sm font-medium text-[#9d2449] underline underline-offset-4"
                                    />
                                    <p className="mt-1 text-xs text-zinc-500">
                                      {m.categoria} · {m.tamano}
                                    </p>
                                  </div>
                                  <div className="flex gap-2">
                                    <IconActionButton
                                      aria-label={`Editar ${m.titulo}`}
                                      onClick={() => setMaterial(m)}
                                    >
                                      <Pencil className="size-4" />
                                    </IconActionButton>
                                    <IconActionButton
                                      aria-label={`Eliminar ${m.titulo}`}
                                      onClick={async () => {
                                        if (
                                          await ask({
                                            title: `¿Eliminar «${m.titulo}»?`,
                                            description:
                                              "El material dejará de estar disponible en este módulo.",
                                            confirmLabel: "Eliminar material",
                                          })
                                        )
                                          update({
                                            ...course,
                                            materiales: course.materiales.filter(
                                              (old) => old.id !== m.id,
                                            ),
                                          });
                                      }}
                                    >
                                      <Trash2 className="size-4" />
                                    </IconActionButton>
                                  </div>
                                </li>
                              ))}
                          </ul>
                          {!course.materiales.length && (
                            <p className="py-4 text-sm text-zinc-500">
                              Aún no hay materiales registrados.
                            </p>
                          )}
                        </Panel>
                        {material && (
                          <MaterialEditor
                            key={material.id}
                            draftKey={`neo:form:${instructorId}:${aulaId}:${moduleId}:material:${course.materiales.some((m) => m.id === material.id) ? material.id : "new"}`}
                            aulaId={aulaId}
                            initial={material}
                            videos={videos}
                            onCancel={() => setMaterial(null)}
                            onSave={(next) => {
                              update({
                                ...course,
                                materiales: course.materiales.some((m) => m.id === next.id)
                                  ? course.materiales.map((m) => (m.id === next.id ? next : m))
                                  : [...course.materiales, next],
                              });
                              setMaterial(null);
                            }}
                          />
                        )}
                      </>
                    )}
                    {tab === "foro" && (
                      <AulaForum
                        key={moduleId}
                        aulaId={aulaId}
                        moduleId={activeModule.id}
                        tasks={tasks}
                        materials={course.materiales}
                      />
                    )}
                    {tab === "publicacion" && (
                      <>
                        <Panel title="Resumen del aula">
                          <h3 className="text-xl font-semibold">{titulo}</h3>
                          <div className="mt-5 grid gap-3 sm:grid-cols-3">
                            <Summary label="Videoclases" value={videos.length} />
                            <Summary label="Tareas" value={tasks.length} />
                            <Summary label="Evaluaciones y exámenes" value={examinations.length} />
                          </div>
                          <div className="mt-5 space-y-2">
                            <p className="text-sm text-zinc-600">
                              Tiempo programado:{" "}
                              <strong>
                                {hours} / {horas} horas
                              </strong>
                            </p>
                            <div
                              role="progressbar"
                              aria-label="Horas programadas"
                              aria-valuemin={0}
                              aria-valuemax={horas || 1}
                              aria-valuenow={Math.min(hours, horas || 1)}
                              className="h-2 overflow-hidden rounded-full bg-zinc-100"
                            >
                              <div
                                className="h-full rounded-full bg-[#9d2449] transition-[width] motion-reduce:transition-none"
                                style={{ width: `${Math.min(100, (hours / (horas || 1)) * 100)}%` }}
                              />
                            </div>
                            {hours < horas && (
                              <p className="text-xs text-amber-700">
                                Faltan {Math.round((horas - hours) * 100) / 100} horas para cubrir
                                la duración oficial.
                              </p>
                            )}
                          </div>
                        </Panel>
                        <Panel title="Publicación">
                          <p className="mb-5 text-sm text-zinc-500">
                            La publicación se aplica al aula completa y a todos sus módulos. Guarda
                            el curso como borrador o publícalo. Antes de publicar se verifican los
                            videos, las preguntas y sus vínculos.
                          </p>
                          <div className="flex flex-wrap gap-3">
                            <ActionButton
                              disabled={editor.pending}
                              onClick={() => editor.save("BORRADOR")}
                            >
                              Guardar como borrador
                            </ActionButton>
                            <ActionButton
                              primary
                              disabled={editor.pending}
                              onClick={() => editor.save("PUBLICADO")}
                            >
                              <Send className="size-4" />
                              {editor.pending ? "Guardando…" : "Publicar aula"}
                            </ActionButton>
                          </div>
                        </Panel>
                      </>
                    )}
                  </>
                )}
                {preview && (
                  <Panel
                    title={`Vista previa: ${preview.titulo}`}
                    action={
                      <ActionButton onClick={() => setPreview(null)}>
                        Cerrar vista previa
                      </ActionButton>
                    }
                  >
                    <p className="mb-4 whitespace-pre-wrap text-sm text-zinc-600">
                      {preview.descripcion}
                    </p>
                    {preview.tipo === "video" && preview.videoSrc && (
                      <CourseVideo
                        controls
                        preload="metadata"
                        className="aspect-video min-h-[200px] w-full overflow-hidden rounded-2xl bg-zinc-950 object-contain"
                        src={fileHref(aulaId, preview.videoSrc)}
                      />
                    )}
                    {preview.tipo === "tarea" && (
                      <div className="space-y-2 text-sm">
                        <p>{preview.instrucciones}</p>
                        <p>Entrega: {preview.fechaEntrega?.replace("T", " ")}</p>
                        {preview.archivoGuiaUrl && (
                          <ResourceLink
                            url={fileHref(aulaId, preview.archivoGuiaUrl)}
                            title={preview.archivoGuiaNombre || "Guía de la tarea"}
                          />
                        )}
                      </div>
                    )}
                    {(preview.questions ?? preview.preguntas ?? []).map((q) => (
                      <div key={q.id} className="mt-4 rounded-xl border border-zinc-200 p-4">
                        <p className="text-sm font-medium">{q.question}</p>
                        <ol className="mt-2 space-y-1 text-sm">
                          {q.options.map((o, i) => (
                            <li
                              key={i}
                              className={
                                i === q.correctAnswer
                                  ? "font-medium text-green-700"
                                  : "text-zinc-600"
                              }
                            >
                              {String.fromCharCode(65 + i)}. {o}
                              {i === q.correctAnswer ? " ✓" : ""}
                            </li>
                          ))}
                        </ol>
                        {q.explanation && (
                          <p className="mt-3 text-xs text-zinc-500">{q.explanation}</p>
                        )}
                      </div>
                    ))}
                  </Panel>
                )}
              </div>
            </div>
            <AulaTimeline
              sessions={course.sesiones}
              selectedId={session?.id ?? preview?.id}
              onMove={move}
              onSelect={async (item) => {
                if ((session || material) && !(await confirmDiscard())) return;
                setMaterial(null);
                setSession(null);
                setPreview(item);
                setTab(
                  item.tipo === "video"
                    ? "videos"
                    : item.tipo === "tarea"
                      ? "tareas"
                      : "evaluaciones",
                );
              }}
            />
          </div>
        </>
      )}
    </div>
  );
}
function Summary({ label, value }: { label: string; value: number }) {
  return (
    <div className="rounded-xl bg-zinc-50 p-4">
      <p className="text-xs text-zinc-500">{label}</p>
      <p className="mt-1 text-2xl font-semibold">{value}</p>
    </div>
  );
}
