"use client";

import Link from "next/link";
import { useRouter } from "next/navigation";
import { useCallback, useEffect, useRef, useState } from "react";
import {
  ArrowLeft,
  Broadcast as Radio,
  CalendarBlank as CalendarClock,
  CaretLeft as ChevronLeft,
  CaretRight as ChevronRight,
  CheckCircle as CheckCircle2,
  Circle,
  CircleNotch as Loader2,
  LockSimple as Lock,
  Medal as Award,
} from "@phosphor-icons/react";

import { avisoDaLoja } from "@/components/AvisoDaLoja";
import { getReadableTextColor } from "@/lib/color-contrast";
import { capituloNoTempo, relogio, type Capitulo, type TipoDeAula } from "@/lib/digitais/curso";

import CabecalhoDosMembros from "./CabecalhoDosMembros";
import ComentariosDaAula from "./ComentariosDaAula";
import { IconeDaAula, rotuloDoTipo } from "./IconeDaAula";
import MateriaisDaAula, { type MaterialNaSala } from "./MateriaisDaAula";
import PlayerDoCurso, { type ControleDoPlayer } from "./PlayerDoCurso";
import { temaDosMembros } from "./tema";

/*
 * A sala de aula: o vídeo (ou o texto, os materiais, a aula ao vivo), o
 * botão de concluída, a aula anterior e a próxima, as abas Descrição,
 * Capítulos, Materiais e Comentários, e a lista do curso ao lado.
 *
 * O progresso vai para o servidor a cada 10 s tocando, ao pausar, ao acabar
 * e ao sair da página (sendBeacon). Na prévia da equipe nada é gravado.
 */

export type AulaNaSala = {
  id: string;
  titulo: string;
  tipo: TipoDeAula;
  descricao: string | null;
  texto: string | null;
  duracaoS: number | null;
  modulo: string;
  numero: number;
  total: number;
  comentarios: boolean;
  aoVivo: { quando: string; situacao: string; link: string | null; liberaEmMs: number | null } | null;
  /* Só no vídeo enviado para a loja: a legenda (botão CC) e os capítulos. */
  legenda: boolean;
  capitulos: Capitulo[];
};

export type AulaDaLista = { id: string; titulo: string; tipo: TipoDeAula; duracaoS: number | null; aberta: boolean; abre: string | null };
export type ModuloDaLista = { id: string; titulo: string; aberto: boolean; abre: string | null; aulas: AulaDaLista[] };
export type MarcaDaSala = { concluida: boolean; posicaoS: number; duracaoS: number | null };

type Aba = "descricao" | "capitulos" | "materiais" | "comentarios";

const URL_NO_TEXTO = /(https?:\/\/[^\s<>"')\]]+)/g;

/* O código deste navegador para a conta dos aparelhos (sorteado uma vez). */
function meuAparelho(): string | null {
  try {
    const guardado = window.localStorage.getItem("ks_aparelho");
    if (guardado && /^[A-Za-z0-9_-]{8,64}$/.test(guardado)) return guardado;
    const novo = Array.from(crypto.getRandomValues(new Uint8Array(12)), (n) => n.toString(36).padStart(2, "0")).join("").slice(0, 20);
    window.localStorage.setItem("ks_aparelho", novo);
    return novo;
  } catch {
    return null;
  }
}

/* Texto puro com os endereços viram links (nada de HTML de fora). */
function TextoComLinks({ texto, className }: { texto: string; className?: string }) {
  const partes = texto.split(URL_NO_TEXTO);
  return (
    <div className={className}>
      {partes.map((parte, i) =>
        i % 2 === 1 ? (
          <a key={i} href={parte} target="_blank" rel="noopener noreferrer nofollow" className="break-all font-semibold underline underline-offset-2">
            {parte}
          </a>
        ) : (
          <span key={i}>{parte}</span>
        )
      )}
    </div>
  );
}

export default function SalaDeAula({
  slug,
  cor,
  escuro,
  nomeDaArea,
  pessoa,
  previa,
  curso,
  aula,
  marca = null,
  materiais,
  modulos,
  marcas,
  inicio,
  concluida: concluidaNoComeco,
  anterior,
  proxima,
  player,
}: {
  slug: string;
  cor: string;
  escuro: boolean;
  nomeDaArea: string;
  pessoa: { nome: string } | null;
  previa: boolean;
  curso: { id: string; nome: string; capa: string | null };
  aula: AulaNaSala;
  /* A marca d'água no vídeo (o e-mail do aluno), quando a loja liga. */
  marca?: string | null;
  materiais: MaterialNaSala[];
  modulos: ModuloDaLista[];
  marcas: Record<string, MarcaDaSala>;
  inicio: number | null;
  concluida: boolean;
  anterior: { id: string; titulo: string } | null;
  proxima: { id: string; titulo: string; aberta: boolean; abre: string | null } | null;
  player: { continuar: boolean; velocidades: number[]; proximaSozinha: boolean };
}) {
  const router = useRouter();
  const tema = temaDosMembros(escuro);
  const corDoTexto = getReadableTextColor(cor);

  const [concluida, setConcluida] = useState(concluidaNoComeco);
  const [marcando, setMarcando] = useState(false);
  const [aba, setAba] = useState<Aba>(
    aula.descricao ? "descricao" : aula.capitulos.length ? "capitulos" : materiais.length && aula.tipo !== "materiais" ? "materiais" : "comentarios"
  );
  /* O capítulo que está tocando (o início dele, em segundos). */
  const [capituloAtual, setCapituloAtual] = useState<number | null>(null);
  const capituloVisto = useRef<number | null>(null);
  const controle = useRef<ControleDoPlayer | null>(null);
  const [quantosComentarios, setQuantosComentarios] = useState<number | null>(null);
  const [videoDeFora, setVideoDeFora] = useState(false);
  /* Concluiu a última aula agora: o código do certificado que acabou de nascer. */
  const [certificado, setCertificado] = useState<string | null>(null);
  /* O curso começou a tocar em outro aparelho (passou do limite): este parou. */
  const [outroAparelho, setOutroAparelho] = useState(false);
  const [assumindo, setAssumindo] = useState(false);
  const [proximaEm, setProximaEm] = useState<number | null>(null);

  const posicao = useRef(inicio ?? 0);
  const duracao = useRef(aula.duracaoS ?? 0);
  const salvoEm = useRef(inicio ?? 0);
  const tocando = useRef(false);

  const corpoDoProgresso = useCallback(
    (extra?: { concluir?: boolean; tocando?: boolean; assumir?: boolean }) =>
      JSON.stringify({
        slug,
        aulaId: aula.id,
        posicao: Math.floor(posicao.current),
        ...(duracao.current ? { duracao: Math.round(duracao.current) } : {}),
        ...(aula.tipo === "video" ? { dispositivo: meuAparelho(), tocando: tocando.current } : {}),
        ...(extra ?? {}),
      }),
    [slug, aula.id, aula.tipo]
  );

  const salvar = useCallback(async () => {
    if (previa) return;
    salvoEm.current = posicao.current;
    try {
      const resposta = await fetch("/api/digitais/progresso", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: corpoDoProgresso(),
        keepalive: true,
      });
      const corpo = (await resposta.json().catch(() => null)) as { concluida?: boolean; certificado?: { codigo?: string } | null; parar?: boolean } | null;
      if (resposta.ok && corpo?.concluida) setConcluida(true);
      if (resposta.ok && corpo?.certificado?.codigo) setCertificado(corpo.certificado.codigo);
      if (resposta.ok && corpo?.parar && tocando.current) {
        controle.current?.pausar();
        setOutroAparelho(true);
      }
    } catch {
      /* Sem rede: grava na próxima vez. */
    }
  }, [previa, corpoDoProgresso]);

  /* A cada 10 s tocando, grava onde está. */
  useEffect(() => {
    if (previa) return;
    const relogio = window.setInterval(() => {
      if (tocando.current && Math.abs(posicao.current - salvoEm.current) >= 1) void salvar();
    }, 10_000);
    return () => window.clearInterval(relogio);
  }, [previa, salvar]);

  /* Ao sair da página (ou trocar de aba do navegador), o último segundo vai junto. */
  useEffect(() => {
    if (previa) return;
    /* `saindo`: a aula fecha e este aparelho deixa de contar. Só trocar de
       aba não solta (o vídeo pode seguir tocando ao fundo). */
    function enviar(saindo: boolean) {
      if (Math.abs(posicao.current - salvoEm.current) < 1 && !(saindo && tocando.current)) return;
      salvoEm.current = posicao.current;
      const dados = corpoDoProgresso(saindo ? { tocando: false } : undefined);
      if (typeof navigator !== "undefined" && navigator.sendBeacon) {
        navigator.sendBeacon("/api/digitais/progresso", new Blob([dados], { type: "text/plain" }));
      } else {
        void fetch("/api/digitais/progresso", { method: "POST", body: dados, keepalive: true }).catch(() => undefined);
      }
    }
    const aoSair = () => enviar(true);
    function aoEsconder() {
      if (document.visibilityState === "hidden") enviar(false);
    }
    window.addEventListener("pagehide", aoSair);
    document.addEventListener("visibilitychange", aoEsconder);
    return () => {
      window.removeEventListener("pagehide", aoSair);
      document.removeEventListener("visibilitychange", aoEsconder);
      enviar(true);
    };
  }, [previa, corpoDoProgresso]);

  /* Aula sem vídeo: abrir já conta como "parou aqui" (o Continuar volta nela). */
  useEffect(() => {
    if (previa || aula.tipo === "video") return;
    void fetch("/api/digitais/progresso", { method: "POST", headers: { "content-type": "application/json" }, body: corpoDoProgresso() }).catch(() => undefined);
  }, [previa, aula.tipo, corpoDoProgresso]);

  /* A próxima aula sozinha: 5, 4, 3… */
  useEffect(() => {
    if (proximaEm === null || !proxima) return;
    if (proximaEm <= 0) {
      router.push(`/${slug}/membros/aula/${proxima.id}`);
      return;
    }
    const t = window.setTimeout(() => setProximaEm((n) => (n === null ? null : n - 1)), 1000);
    return () => window.clearTimeout(t);
  }, [proximaEm, proxima, router, slug]);

  /* A aula ao vivo libera o link 15 minutos antes: a página se atualiza nessa hora. */
  useEffect(() => {
    const falta = aula.aoVivo?.liberaEmMs;
    if (!falta || falta <= 0 || falta > 24 * 60 * 60 * 1000) return;
    const t = window.setTimeout(() => router.refresh(), falta + 1500);
    return () => window.clearTimeout(t);
  }, [aula.aoVivo?.liberaEmMs, router]);

  /* "Assistir aqui": este aparelho passa a ser o mais novo e o outro para. */
  async function assistirAqui() {
    if (assumindo) return;
    setAssumindo(true);
    try {
      await fetch("/api/digitais/progresso", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: corpoDoProgresso({ tocando: true, assumir: true }),
      });
    } catch {
      /* Sem rede: tenta tocar assim mesmo. */
    } finally {
      setAssumindo(false);
      setOutroAparelho(false);
      controle.current?.tocar();
    }
  }

  async function alternarConcluida() {
    if (previa) {
      avisoDaLoja.info("Na prévia nada é gravado: é assim que o cliente vê.");
      return;
    }
    if (marcando) return;
    const nova = !concluida;
    setConcluida(nova);
    setMarcando(true);
    try {
      const resposta = await fetch("/api/digitais/progresso", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: corpoDoProgresso({ concluir: nova }),
      });
      const corpo = (await resposta.json().catch(() => null)) as { concluida?: boolean; error?: string; certificado?: { codigo?: string } | null } | null;
      if (!resposta.ok) throw new Error(corpo?.error || "Não foi possível marcar agora.");
      salvoEm.current = posicao.current;
      setConcluida(Boolean(corpo?.concluida));
      if (corpo?.certificado?.codigo) setCertificado(corpo.certificado.codigo);
    } catch (e) {
      setConcluida(!nova);
      avisoDaLoja.erro(e instanceof Error ? e.message : "Não foi possível marcar agora.");
    } finally {
      setMarcando(false);
    }
  }

  const marcaDe = (id: string) => (id === aula.id ? { ...(marcas[id] ?? { posicaoS: 0, duracaoS: null }), concluida } : marcas[id]);
  const todas = modulos.flatMap((m) => m.aulas);
  const feitas = todas.filter((a) => marcaDe(a.id)?.concluida).length;
  const percentual = todas.length ? Math.round((feitas / todas.length) * 100) : 0;

  const fonteEm = `/api/digitais/aula/${aula.id}/video?slug=${encodeURIComponent(slug)}`;
  const legendaEm = aula.legenda ? `/api/digitais/aula/${aula.id}/legenda?slug=${encodeURIComponent(slug)}` : null;
  const abas: Array<{ id: Aba; rotulo: string }> = [
    ...(aula.descricao ? [{ id: "descricao" as const, rotulo: "Descrição" }] : []),
    ...(aula.capitulos.length && !videoDeFora ? [{ id: "capitulos" as const, rotulo: `Capítulos (${aula.capitulos.length})` }] : []),
    ...(materiais.length && aula.tipo !== "materiais" ? [{ id: "materiais" as const, rotulo: `Materiais (${materiais.length})` }] : []),
    ...(aula.comentarios ? [{ id: "comentarios" as const, rotulo: quantosComentarios ? `Comentários (${quantosComentarios})` : "Comentários" }] : []),
  ];
  const abaAberta = abas.some((a) => a.id === aba) ? aba : abas[0]?.id ?? null;

  const botaoDeConcluir = (
    <button
      type="button"
      onClick={() => void alternarConcluida()}
      disabled={marcando}
      className={`inline-flex h-10 items-center gap-2 rounded-xl border px-3.5 text-[13px] font-bold transition disabled:opacity-60 ${concluida ? "border-transparent" : tema.linha}`}
      style={concluida ? { backgroundColor: `${cor}26`, color: escuro ? "#fff" : cor } : undefined}
      aria-pressed={concluida}
    >
      {marcando ? <Loader2 className="h-4 w-4 animate-spin" /> : concluida ? <CheckCircle2 weight="fill" className="h-4 w-4" style={{ color: cor }} /> : <Circle className="h-4 w-4" />}
      {concluida ? "Concluída" : "Marcar como concluída"}
    </button>
  );

  return (
    <div className={`flex min-h-screen flex-col ${tema.fundo}`}>
      <CabecalhoDosMembros slug={slug} nomeDaArea={nomeDaArea} cor={cor} tema={tema} pessoa={pessoa} previa={previa} ativo="curso" />

      <div className="mx-auto grid w-full max-w-[1400px] flex-1 gap-6 pb-14 sm:px-6 sm:pt-6 lg:grid-cols-[minmax(0,1fr)_360px] lg:px-8">
        <div className="min-w-0">
          {/* O conteúdo principal da aula */}
          {aula.tipo === "video" ? (
            <div className="relative">
              <PlayerDoCurso
                ref={controle}
                fonteEm={fonteEm}
                legendaEm={legendaEm}
                capitulos={aula.capitulos}
                marca={marca}
                inicio={player.continuar && !concluidaNoComeco ? inicio : null}
                velocidades={player.velocidades}
                cor={cor}
                capa={curso.capa}
                autoplay={false}
                aoCarregar={(tipo) => setVideoDeFora(tipo === "link")}
                aoTocar={() => {
                  tocando.current = true;
                  setProximaEm(null);
                }}
                aoTempo={(p, d) => {
                  posicao.current = p;
                  duracao.current = d;
                  if (aula.capitulos.length) {
                    const inicio = capituloNoTempo(aula.capitulos, p)?.inicioS ?? null;
                    if (inicio !== capituloVisto.current) {
                      capituloVisto.current = inicio;
                      setCapituloAtual(inicio);
                    }
                  }
                }}
                aoPausar={(p, d) => {
                  tocando.current = false;
                  posicao.current = p;
                  duracao.current = d;
                  void salvar();
                }}
                aoTerminar={(d) => {
                  tocando.current = false;
                  if (Number.isFinite(d) && d > 0) {
                    posicao.current = d;
                    duracao.current = d;
                  }
                  void salvar();
                  if (player.proximaSozinha && proxima?.aberta) setProximaEm(5);
                }}
              />
              {outroAparelho ? (
                <div className="absolute inset-0 z-10 flex items-center justify-center bg-black/85 p-4 text-center text-white sm:rounded-[18px]">
                  <div className="max-w-[420px]">
                    <div className="text-[17px] font-bold leading-snug sm:text-[20px]">Este conteúdo começou a tocar em outro aparelho</div>
                    <p className="mt-2 text-[13.5px] leading-6 text-white/70">
                      A loja permite poucos aparelhos assistindo ao mesmo tempo com o mesmo login. Para assistir aqui, o outro para.
                    </p>
                    <button
                      type="button"
                      onClick={() => void assistirAqui()}
                      disabled={assumindo}
                      className="mt-5 inline-flex h-11 items-center gap-2 rounded-xl px-5 text-[14px] font-bold disabled:opacity-60"
                      style={{ backgroundColor: cor, color: corDoTexto }}
                    >
                      {assumindo ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
                      Assistir aqui
                    </button>
                  </div>
                </div>
              ) : null}
              {proximaEm !== null && proxima ? (
                <div className="absolute inset-0 z-10 flex items-center justify-center bg-black/80 p-4 text-center text-white sm:rounded-[18px]">
                  <div className="max-w-[420px]">
                    <div className="text-[12px] font-bold uppercase tracking-[0.14em] text-white/60">Próximo vídeo em {proximaEm}</div>
                    <div className="mt-2 text-[18px] font-bold leading-snug sm:text-[22px]">{proxima.titulo}</div>
                    <div className="mt-5 flex flex-wrap justify-center gap-2.5">
                      <Link
                        href={`/${slug}/membros/aula/${proxima.id}`}
                        className="inline-flex h-11 items-center gap-2 rounded-xl px-5 text-[14px] font-bold"
                        style={{ backgroundColor: cor, color: corDoTexto }}
                      >
                        Assistir agora
                      </Link>
                      <button type="button" onClick={() => setProximaEm(null)} className="h-11 rounded-xl border border-white/25 px-5 text-[14px] font-semibold">
                        Cancelar
                      </button>
                    </div>
                  </div>
                </div>
              ) : null}
            </div>
          ) : aula.tipo === "ao_vivo" && aula.aoVivo ? (
            <div className={`border-y p-6 sm:rounded-[18px] sm:border sm:p-8 ${tema.cartao}`}>
              <span className="inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-[11.5px] font-bold uppercase tracking-wide" style={{ backgroundColor: `${cor}26`, color: escuro ? "#fff" : cor }}>
                <Radio className="h-3.5 w-3.5" />
                Ao vivo
              </span>
              <div className="mt-4 flex items-start gap-3">
                <CalendarClock className={`mt-1 h-6 w-6 shrink-0 ${tema.suave}`} />
                <div>
                  <div className="text-[20px] font-bold leading-snug sm:text-[24px]">{aula.aoVivo.quando}</div>
                  <div className={`mt-1 text-[14px] ${tema.suave}`}>{aula.aoVivo.situacao}</div>
                </div>
              </div>
              <div className="mt-6">
                {aula.aoVivo.link ? (
                  <a
                    href={aula.aoVivo.link}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="inline-flex h-12 items-center gap-2 rounded-xl px-5 text-[15px] font-bold transition hover:opacity-90"
                    style={{ backgroundColor: cor, color: corDoTexto }}
                  >
                    Entrar na transmissão
                  </a>
                ) : (
                  <p className={`text-[13.5px] ${tema.suave}`}>O botão para entrar aparece aqui 15 minutos antes de começar.</p>
                )}
              </div>
            </div>
          ) : aula.tipo === "texto" ? (
            <article className={`border-y px-5 py-7 sm:rounded-[18px] sm:border sm:px-10 sm:py-10 ${tema.cartao}`}>
              <TextoComLinks texto={aula.texto ?? ""} className="mx-auto max-w-[720px] whitespace-pre-line break-words text-[16px] leading-8" />
            </article>
          ) : (
            <div className={`border-y px-5 py-5 sm:rounded-[18px] sm:border sm:px-6 ${tema.cartao}`}>
              <div className={`text-[11.5px] font-bold uppercase tracking-[0.12em] ${tema.apagado}`}>Materiais para baixar</div>
              <MateriaisDaAula slug={slug} materiais={materiais} cor={cor} tema={tema} />
            </div>
          )}

          {certificado ? (
            <div
              className="mx-4 mt-5 flex flex-wrap items-center gap-3 rounded-2xl px-4 py-4 sm:mx-0 sm:px-5"
              style={{ backgroundColor: `${cor}1f`, boxShadow: `inset 0 0 0 1px ${cor}55` }}
              role="status"
            >
              <span className="flex h-11 w-11 shrink-0 items-center justify-center rounded-xl" style={{ backgroundColor: cor, color: corDoTexto }}>
                <Award weight="fill" className="h-5 w-5" />
              </span>
              <span className="min-w-0 flex-1">
                <span className="block text-[15px] font-bold">Parabéns! Você concluiu o conteúdo.</span>
                <span className={`block text-[13px] ${tema.suave}`}>Seu certificado está pronto e também foi para o seu e-mail.</span>
              </span>
              <Link
                href={`/${slug}/certificado/${encodeURIComponent(certificado)}`}
                className="inline-flex h-10 items-center rounded-xl px-4 text-[13px] font-bold transition hover:opacity-90"
                style={{ backgroundColor: cor, color: corDoTexto }}
              >
                Ver meu certificado
              </Link>
            </div>
          ) : null}

          {/* Título, concluída, anterior e próxima */}
          <div className="px-4 pt-5 sm:px-0">
            <Link href={`/${slug}/membros/curso/${curso.id}`} className={`inline-flex items-center gap-1.5 text-[13px] font-semibold ${tema.suave} hover:opacity-80`}>
              <ArrowLeft weight="bold" className="h-4 w-4" />
              {curso.nome}
            </Link>
            <div className="mt-4 text-[12px] font-bold uppercase tracking-[0.14em] text-[var(--m-acento)]">
              {aula.modulo} · Vídeo {aula.numero} de {aula.total}
            </div>
            <h1 className="mb-titulo mt-2 text-[calc(var(--m-escala)*36px)] sm:text-[calc(var(--m-escala)*50px)]">{aula.titulo}</h1>
            {videoDeFora ? <p className={`mt-1.5 text-[12.5px] ${tema.apagado}`}>Este vídeo vem de fora da loja: ao terminar, marque como concluído.</p> : null}
            <div className="mt-4 flex flex-wrap items-center gap-2.5">
              {botaoDeConcluir}
              <div className="flex-1" />
              {anterior ? (
                <Link href={`/${slug}/membros/aula/${anterior.id}`} className={`inline-flex h-10 items-center gap-1 rounded-xl border px-3 text-[13px] font-semibold ${tema.linha}`} title={anterior.titulo}>
                  <ChevronLeft weight="bold" className="h-4 w-4" />
                  Anterior
                </Link>
              ) : null}
              {proxima ? (
                proxima.aberta ? (
                  <Link
                    href={`/${slug}/membros/aula/${proxima.id}`}
                    className="inline-flex h-10 items-center gap-1 rounded-xl px-3.5 text-[13px] font-bold transition hover:opacity-90"
                    style={{ backgroundColor: cor, color: corDoTexto }}
                    title={proxima.titulo}
                  >
                    Próximo vídeo
                    <ChevronRight weight="bold" className="h-4 w-4" />
                  </Link>
                ) : (
                  <span className={`inline-flex h-10 items-center gap-1.5 rounded-xl border px-3 text-[12.5px] font-semibold ${tema.linha} ${tema.apagado}`}>
                    <Lock weight="fill" className="h-3.5 w-3.5" />
                    Próxima {proxima.abre ?? "ainda não abriu"}
                  </span>
                )
              ) : null}
            </div>
          </div>

          {/* Descrição, materiais e comentários */}
          {abaAberta ? (
            <div className="mt-6 px-4 sm:px-0">
              <div className={`flex gap-5 overflow-x-auto overflow-y-hidden border-b ${tema.linha}`} role="tablist">
                {abas.map((a) => (
                  <button
                    key={a.id}
                    type="button"
                    role="tab"
                    aria-selected={abaAberta === a.id}
                    onClick={() => setAba(a.id)}
                    className={`whitespace-nowrap border-b-2 pb-3 text-[14px] font-semibold transition ${abaAberta === a.id ? "" : `border-transparent ${tema.suave} hover:opacity-80`}`}
                    style={abaAberta === a.id ? { borderColor: cor } : undefined}
                  >
                    {a.rotulo}
                  </button>
                ))}
              </div>
              <div className="pt-5">
                {abaAberta === "descricao" && aula.descricao ? (
                  <TextoComLinks texto={aula.descricao} className={`whitespace-pre-line break-words text-[14.5px] leading-7 ${escuro ? "text-white/85" : "text-[#2B3350]"}`} />
                ) : null}
                {abaAberta === "capitulos" ? (
                  <ol className="-mx-3 space-y-0.5">
                    {aula.capitulos.map((capitulo) => {
                      const tocandoAgora = capituloAtual === capitulo.inicioS;
                      return (
                        <li key={capitulo.inicioS}>
                          <button
                            type="button"
                            onClick={() => {
                              controle.current?.irPara(capitulo.inicioS);
                              window.scrollTo({ top: 0, behavior: "smooth" });
                            }}
                            aria-current={tocandoAgora ? "true" : undefined}
                            className={`flex w-full items-center gap-3 rounded-xl px-3 py-2.5 text-left transition ${
                              tocandoAgora ? tema.realce : escuro ? "hover:bg-white/[0.04]" : "hover:bg-[#F1F2F6]"
                            }`}
                          >
                            <span className="w-16 shrink-0 text-[13px] font-bold tabular-nums" style={{ color: escuro ? undefined : cor }}>
                              {relogio(capitulo.inicioS)}
                            </span>
                            <span className={`min-w-0 flex-1 text-[14px] leading-snug ${tocandoAgora ? "font-bold" : ""}`}>{capitulo.titulo}</span>
                          </button>
                        </li>
                      );
                    })}
                  </ol>
                ) : null}
                {abaAberta === "materiais" ? <MateriaisDaAula slug={slug} materiais={materiais} cor={cor} tema={tema} /> : null}
                <div hidden={abaAberta !== "comentarios"}>
                  {aula.comentarios ? (
                    <ComentariosDaAula slug={slug} aulaId={aula.id} cor={cor} tema={tema} previa={previa} aoContar={setQuantosComentarios} />
                  ) : null}
                </div>
              </div>
            </div>
          ) : null}
        </div>

        {/* A lista do curso */}
        <aside className="px-4 sm:px-0">
          <div className={`overflow-hidden rounded-[18px] border lg:sticky lg:top-24 ${tema.cartao}`}>
            <div className={`border-b px-4 py-4 ${tema.linha}`}>
              <div className="text-[14.5px] font-bold">O que tem dentro</div>
              {!previa ? (
                <>
                  <div className={`mt-2 h-1.5 overflow-hidden rounded-full ${escuro ? "bg-white/10" : "bg-[#E2E5EC]"}`}>
                    <div className="h-full rounded-full transition-all" style={{ width: `${percentual}%`, backgroundColor: cor }} />
                  </div>
                  <div className={`mt-1.5 text-[12px] ${tema.suave}`}>
                    {percentual}% · {feitas} de {todas.length} {todas.length === 1 ? "vídeo" : "vídeos"}
                  </div>
                </>
              ) : null}
            </div>
            <div className="max-h-[60vh] overflow-y-auto lg:max-h-[calc(100vh-14rem)]">
              {modulos.map((modulo, indice) => (
                <div key={modulo.id}>
                  <div className={`sticky top-0 z-[1] px-4 py-2.5 text-[11.5px] font-bold uppercase tracking-[0.1em] backdrop-blur bg-[var(--m-fundo-2)]/95 text-[var(--m-texto-3)]`}>
                    Módulo {indice + 1} · {modulo.titulo}
                  </div>
                  <ul>
                    {modulo.aulas.map((item) => {
                      const marca = marcaDe(item.id);
                      const atual = item.id === aula.id;
                      const linha = (
                        <>
                          <span className="flex h-6 w-6 shrink-0 items-center justify-center">
                            {!item.aberta ? (
                              <Lock weight="fill" className={`h-3.5 w-3.5 ${tema.apagado}`} />
                            ) : marca?.concluida ? (
                              <CheckCircle2 weight="fill" className="h-[18px] w-[18px]" style={{ color: cor }} />
                            ) : (
                              <IconeDaAula tipo={item.tipo} className={`h-[18px] w-[18px] ${atual ? "" : tema.apagado}`} style={atual ? { color: cor } : undefined} />
                            )}
                          </span>
                          <span className="min-w-0 flex-1">
                            <span className={`block text-[13.5px] leading-snug ${atual ? "font-bold" : ""} ${item.aberta ? "" : tema.apagado}`}>{item.titulo}</span>
                            <span className={`block text-[11.5px] ${tema.apagado}`}>{item.aberta ? rotuloDoTipo(item.tipo, item.duracaoS) : item.abre ? `Este vídeo ${item.abre}` : "Ainda não abriu"}</span>
                          </span>
                        </>
                      );
                      return (
                        <li key={item.id}>
                          {item.aberta && !atual ? (
                            <Link href={`/${slug}/membros/aula/${item.id}`} className={`flex items-start gap-2.5 px-4 py-2.5 transition ${escuro ? "hover:bg-white/[0.04]" : "hover:bg-[#F7F8FB]"}`}>
                              {linha}
                            </Link>
                          ) : (
                            <div
                              className={`flex items-start gap-2.5 px-4 py-2.5 ${atual ? tema.realce : "cursor-not-allowed"}`}
                              aria-current={atual ? "page" : undefined}
                              style={atual ? { boxShadow: `inset 3px 0 0 ${cor}` } : undefined}
                            >
                              {linha}
                            </div>
                          )}
                        </li>
                      );
                    })}
                  </ul>
                </div>
              ))}
            </div>
          </div>
        </aside>
      </div>
    </div>
  );
}

