import type { Metadata } from "next";
import { notFound } from "next/navigation";

import Avisos from "@/components/digitais/Avisos";
import AvisoDosMembros from "@/components/digitais/membros/AvisoDosMembros";
import EntrarNosMembros from "@/components/digitais/membros/EntrarNosMembros";
import type { MaterialNaSala } from "@/components/digitais/membros/MateriaisDaAula";
import SalaDeAula, { type AulaNaSala, type MarcaDaSala, type ModuloDaLista } from "@/components/digitais/membros/SalaDeAula";
import FontesDaLoja from "@/components/FontesDaLoja";
import { lerCapitulos, linkGuardado } from "@/lib/digitais/curso";
import { tamanhoLegivel } from "@/lib/digitais/nome-do-arquivo";
import { vizinhas } from "@/lib/digitais/progresso-do-curso";
import { aoVivoNaTela } from "@/lib/digitais/ao-vivo";
import { estruturaParaAluno, lerAulaDaLoja, lerCursoDaLoja, progressoDoAluno, quemAssiste } from "@/lib/digitais/servidor/curso";
import { ajustesDosDigitais, corDaArea } from "@/lib/digitais/servidor/ajustes-do-pedido";
import { miniatura, TAMANHO } from "@/lib/foto";
import { carregarLoja } from "@/lib/loja/dados-da-loja";
import { lerClienteLogado } from "@/lib/loja/visao.server";
import { normalizeWhatsappForLink } from "@/lib/phone";
import { createAdminClient } from "@/lib/supabase-admin";

/*
 * A sala de aula. O servidor confere tudo antes de mostrar: a aula é desta
 * loja, está publicada, quem chegou pode ver o curso e a aula já abriu para
 * ele. O vídeo em si vem depois, pela rota que assina o endereço.
 */

export const dynamic = "force-dynamic";
export const revalidate = 0;

type Props = { params: Promise<{ slug: string; aulaId: string }> };

export async function generateMetadata(props: Props): Promise<Metadata> {
  const { slug } = await props.params;
  const dados = await carregarLoja(slug);
  const nome = dados?.profile?.catalog_name || dados?.profile?.store_name || "Loja";
  return { title: { absolute: `Vídeo | ${nome}` }, robots: { index: false, follow: false } };
}

export default async function PaginaDaAula(props: Props) {
  const { slug, aulaId } = await props.params;
  const dados = await carregarLoja(slug);
  const perfil = dados?.profile;
  if (!dados || !perfil) return notFound();
  const lojaId = String(perfil.id);

  const admin = createAdminClient();
  const [ajustes, aula, cliente] = await Promise.all([ajustesDosDigitais(lojaId), lerAulaDaLoja(admin, lojaId, aulaId), lerClienteLogado(slug)]);
  if (!aula || !aula.publicada) return notFound();
  const curso = await lerCursoDaLoja(admin, lojaId, aula.product_id);
  if (!curso) return notFound();

  const nomeDaLoja = String(perfil.catalog_name || perfil.store_name || "Loja");
  const nomeDaArea = ajustes.area.nome || nomeDaLoja;
  const cor = corDaArea(ajustes, perfil);
  const escuro = ajustes.area.fundo !== "claro";
  const whatsapp = normalizeWhatsappForLink(perfil.whatsapp) || null;
  const pessoa = cliente ? { nome: cliente.name || "" } : null;
  const doCurso = `/${slug}/membros/curso/${curso.id}`;

  const quem = await quemAssiste(admin, { slug, lojaId, produtoId: curso.id });
  if (!quem) {
    if (!cliente) {
      return (
        <>
          <FontesDaLoja perfil={perfil} />
          <EntrarNosMembros slug={slug} nomeDaArea={nomeDaArea} nomeDaLoja={nomeDaLoja} cor={cor} escuro={escuro} titulo="Entre para assistir" destino={`/${slug}/membros/aula/${aula.id}`} />
        </>
      );
    }
    return (
      <>
        <FontesDaLoja perfil={perfil} />
        <AvisoDosMembros
          slug={slug}
          nomeDaArea={nomeDaArea}
          cor={cor}
          escuro={escuro}
          pessoa={pessoa}
          titulo="Este conteúdo não está nas suas compras"
          texto={`Você entrou como ${cliente.name || "cliente"}. Se comprou com outro e-mail, saia e entre com ele.`}
          acao={curso.ativo ? { rotulo: "Conhecer o conteúdo", href: `/${slug}/p/${curso.id}` } : null}
          whatsapp={whatsapp}
        />
      </>
    );
  }
  if (quem.tipo === "fechado") {
    return (
      <>
        <FontesDaLoja perfil={perfil} />
        <AvisoDosMembros slug={slug} nomeDaArea={nomeDaArea} cor={cor} escuro={escuro} pessoa={pessoa} titulo="O conteúdo está fechado para você" texto={quem.motivo} whatsapp={whatsapp} />
      </>
    );
  }

  const equipe = quem.tipo === "equipe";
  /* A marca d'água (Configurações): o e-mail de quem assiste, por cima do vídeo. */
  let marca: string | null = null;
  if (ajustes.protecao.marcaDagua && quem.tipo === "aluno" && aula.tipo === "video") {
    const { data: aluno } = await admin.from("clients").select("email,name").eq("id", quem.clienteId).maybeSingle();
    const linhaDoAluno = aluno as { email?: string | null; name?: string | null } | null;
    marca = String(linhaDoAluno?.email || linhaDoAluno?.name || "").trim() || null;
  }
  const [modulos, progresso, materiaisBrutos] = await Promise.all([
    estruturaParaAluno(admin, { lojaId, produtoId: curso.id, inicio: quem.tipo === "aluno" ? quem.inicio : null, equipe }),
    quem.tipo === "aluno" ? progressoDoAluno(admin, quem.clienteId, curso.id) : Promise.resolve(new Map()),
    admin
      .from("digital_course_materials")
      .select("id,titulo,url,digital_files(nome,extensao,categoria,tamanho_bytes,status)")
      .eq("user_id", lojaId)
      .eq("lesson_id", aula.id)
      .order("posicao", { ascending: true })
      .order("criado_em", { ascending: true })
      .limit(100),
  ]);

  const ordem = modulos.flatMap((m) => m.aulas);
  const daAula = ordem.find((a) => a.id === aula.id);
  if (!daAula) {
    return (
      <>
        <FontesDaLoja perfil={perfil} />
        <AvisoDosMembros
          slug={slug}
          nomeDaArea={nomeDaArea}
          cor={cor}
          escuro={escuro}
          pessoa={pessoa}
          titulo="Este vídeo ainda está sendo preparado"
          texto="A loja ainda está terminando este vídeo. Ele aparece aqui assim que ficar pronto."
          acao={{ rotulo: "Voltar ao conteúdo", href: doCurso }}
        />
      </>
    );
  }
  if (!daAula.aberta) {
    return (
      <>
        <FontesDaLoja perfil={perfil} />
        <AvisoDosMembros
          slug={slug}
          nomeDaArea={nomeDaArea}
          cor={cor}
          escuro={escuro}
          pessoa={pessoa}
          titulo="Este vídeo ainda não abriu"
          texto={daAula.abre ? `Ele ${daAula.abre}. Enquanto isso, siga pelos vídeos que já estão abertos.` : "Ele abre em breve. Enquanto isso, siga pelos vídeos que já estão abertos."}
          acao={{ rotulo: "Voltar ao conteúdo", href: doCurso }}
        />
      </>
    );
  }

  const modulo = modulos.find((m) => m.id === daAula.moduloId);
  const { anterior, proxima } = vizinhas(ordem, aula.id);
  const proximaNaLista = proxima ? ordem.find((a) => a.id === proxima.id) ?? null : null;
  const anteriorNaLista = anterior ? ordem.find((a) => a.id === anterior.id) ?? null : null;
  const minha = progresso.get(aula.id);

  /* Legenda e capítulos só valem no vídeo enviado para a loja (o de fora tem o player dele). */
  const videoProprio = aula.tipo === "video" && Boolean(aula.video_file_id) && !linkGuardado(aula.video_link);

  /* A aula ao vivo: o link só sai 15 minutos antes. */
  const aoVivo: AulaNaSala["aoVivo"] = aula.tipo === "ao_vivo" && aula.ao_vivo_em ? aoVivoNaTela(aula.ao_vivo_em, aula.ao_vivo_link) : null;

  type LinhaDoMaterial = {
    id: string;
    titulo: string;
    url: string | null;
    digital_files: { nome: string; extensao: string; categoria: string; tamanho_bytes: number; status: string } | null;
  };
  const materiais: MaterialNaSala[] = ((materiaisBrutos.data ?? []) as unknown as LinhaDoMaterial[]).flatMap((m): MaterialNaSala[] => {
    if (m.url) return [{ id: m.id, titulo: m.titulo, link: true, selo: "LINK", detalhe: "Abre numa nova aba" }];
    const arquivo = m.digital_files;
    if (!arquivo || arquivo.status !== "pronto") return [];
    const extensao = (arquivo.extensao || "ARQ").toUpperCase();
    return [{ id: m.id, titulo: m.titulo, link: false, selo: extensao.slice(0, 4), detalhe: `${extensao} · ${tamanhoLegivel(Number(arquivo.tamanho_bytes) || 0)}` }];
  });

  const lista: ModuloDaLista[] = modulos.map((m) => ({
    id: m.id,
    titulo: m.titulo,
    aberto: m.aberto,
    abre: m.abre,
    aulas: m.aulas.map((a) => ({ id: a.id, titulo: a.titulo, tipo: a.tipo, duracaoS: a.duracaoS, aberta: a.aberta, abre: a.abre })),
  }));
  const marcas: Record<string, MarcaDaSala> = {};
  for (const item of ordem) {
    const p = progresso.get(item.id);
    if (p) marcas[item.id] = { concluida: p.concluida, posicaoS: p.posicaoS, duracaoS: p.duracaoS };
  }

  return (
    <>
      <FontesDaLoja perfil={perfil} />
      <Avisos />
      <SalaDeAula
        key={aula.id}
        slug={slug}
        cor={cor}
        escuro={escuro}
        nomeDaArea={nomeDaArea}
        pessoa={pessoa}
        previa={equipe}
        curso={{ id: curso.id, nome: curso.nome, capa: miniatura(curso.capa, TAMANHO.produto) || curso.capa }}
        marca={marca}
        aula={{
          id: aula.id,
          titulo: aula.titulo,
          tipo: aula.tipo,
          descricao: aula.descricao,
          texto: aula.tipo === "texto" ? aula.texto : null,
          duracaoS: aula.duracao_s,
          modulo: modulo?.titulo ?? "",
          numero: ordem.findIndex((a) => a.id === aula.id) + 1,
          total: ordem.length,
          comentarios: aula.comentarios,
          aoVivo,
          legenda: videoProprio && aula.legenda?.status === "pronto",
          capitulos: videoProprio ? lerCapitulos(aula.capitulos) : [],
        }}
        materiais={materiais}
        modulos={lista}
        marcas={marcas}
        inicio={minha && !minha.concluida ? minha.posicaoS : null}
        concluida={Boolean(minha?.concluida)}
        anterior={anteriorNaLista ? { id: anteriorNaLista.id, titulo: anteriorNaLista.titulo } : null}
        proxima={proximaNaLista ? { id: proximaNaLista.id, titulo: proximaNaLista.titulo, aberta: proximaNaLista.aberta, abre: proximaNaLista.abre } : null}
        player={{ continuar: ajustes.player.continuar, velocidades: ajustes.player.velocidades, proximaSozinha: ajustes.player.proximaSozinha }}
      />
    </>
  );
}
