"use client";

import Link from "next/link";
import { useState } from "react";
import { CalendarClock, Check, Clock3, Copy, ExternalLink, Hammer, Loader2, Lock, PlayCircle } from "lucide-react";

import { avisoDaLoja } from "@/components/AvisoDaLoja";
import { copiarTexto } from "@/lib/digitais/copiar";
import { corDoSelo } from "@/lib/digitais/produto";
import type { AcessoNaTela } from "@/lib/digitais/servidor/acessos";

/*
 * O que o comprador recebeu, com o botão de baixar ou abrir cada item.
 *
 * Usada na tela da compra (prova: a chave da compra, no cookie), na página do
 * link do e-mail (prova: a chave da entrega) e na área de membros (prova: a
 * sessão do portal). O servidor confere a prova a cada clique e devolve um
 * endereço que vale poucos minutos.
 */

/* O curso abre na área de membros: a compra e o membro vão direto (o
   navegador já prova); o link do e-mail troca a chave por um cookie antes. */
export type ProvaDoAcesso = { tipo: "compra"; slug: string } | { tipo: "entrega"; chave: string } | { tipo: "membros"; slug: string };

function seloDoAcesso(acesso: AcessoNaTela): string {
  if (acesso.tipo === "arquivo") return (acesso.arquivo?.extensao || "ARQ").slice(0, 4).toUpperCase();
  if (acesso.tipo === "encomenda") return acesso.arquivo ? acesso.arquivo.extensao.slice(0, 4).toUpperCase() : "SOB";
  if (acesso.tipo === "link") return "LINK";
  if (acesso.tipo === "texto") return "TEXTO";
  if (acesso.tipo === "codigos") return "CÓD";
  if (acesso.tipo === "live") return "LIVE";
  return "VÍDEO";
}

function detalheDoAcesso(acesso: AcessoNaTela): string | null {
  if (acesso.situacao !== "liberado") return acesso.motivo;
  const partes: string[] = [];
  if (acesso.descricao) partes.push(acesso.descricao);
  if ((acesso.tipo === "arquivo" || acesso.tipo === "encomenda") && acesso.arquivo) partes.push(`${acesso.arquivo.extensao.toUpperCase()} · ${acesso.arquivo.tamanhoLegivel}`);
  if (acesso.tipo === "encomenda" && acesso.arquivo) partes.push("feito para você");
  if (acesso.tipo === "link") partes.push("Abre numa nova aba");
  if (acesso.tipo === "curso") partes.push("Assista na área de membros");
  if (acesso.tipo === "live" && acesso.live) partes.push(textoDaLiveNaLista(acesso.live));
  if (acesso.expiraEm) {
    const data = new Date(acesso.expiraEm);
    if (!Number.isNaN(data.getTime())) partes.push(`até ${data.toLocaleDateString("pt-BR")}`);
  }
  return partes.length ? partes.join(" · ") : null;
}

/* "Quinta, 16/10 às 20:00", "Ao vivo agora", "Aconteceu · gravação disponível". */
export function textoDaLiveNaLista(live: NonNullable<AcessoNaTela["live"]>): string {
  if (live.status === "ao_vivo") return "Ao vivo agora";
  if (live.status === "cancelada") return "Cancelada pela loja";
  if (live.status === "encerrada") return live.gravacao ? "Aconteceu · a gravação fica aqui" : "Aconteceu";
  try {
    const quando = new Intl.DateTimeFormat("pt-BR", { weekday: "short", day: "2-digit", month: "2-digit", hour: "2-digit", minute: "2-digit", timeZone: "America/Sao_Paulo" }).format(
      new Date(live.comecaEm),
    );
    return `Ao vivo ${quando}`;
  } catch {
    return "Live";
  }
}

export default function ListaDeAcessos({
  acessos,
  prova,
  corDoBotao = "#1B2440",
  mostrarProduto = false,
  escuro = false,
}: {
  acessos: AcessoNaTela[];
  prova: ProvaDoAcesso;
  corDoBotao?: string;
  /* Na área de membros a lista mistura produtos: o nome de cada um aparece. */
  mostrarProduto?: boolean;
  /* A área de membros escura. */
  escuro?: boolean;
}) {
  const cores = escuro
    ? { linha: "divide-white/10", titulo: "text-white", detalhe: "text-white/60", produto: "text-white/45", aviso: "text-amber-300", caixa: "bg-white/5 text-white/90", fechado: "text-white/50" }
    : { linha: "divide-[#ECEEF3]", titulo: "text-[#1B2440]", detalhe: "text-[#5E6478]", produto: "text-[#8A90A2]", aviso: "text-[#B9700F]", caixa: "bg-[#F7F8FB] text-[#1B2440]", fechado: "text-[#8A90A2]" };
  const [abrindo, setAbrindo] = useState<string | null>(null);
  const [copiado, setCopiado] = useState<string | null>(null);
  /* O que fechou no clique (o freio pausou, o prazo venceu): o motivo fica na linha, não só no aviso que some. */
  const [fechadosAgora, setFechadosAgora] = useState<Record<string, string>>({});

  async function copiar(acesso: AcessoNaTela) {
    if (!acesso.codigo) return;
    if (await copiarTexto(acesso.codigo)) {
      setCopiado(acesso.id);
      window.setTimeout(() => setCopiado((atual) => (atual === acesso.id ? null : atual)), 2500);
    } else {
      avisoDaLoja.info("Não deu para copiar sozinho: selecione o código e copie.");
    }
  }

  async function assistir(acesso: AcessoNaTela) {
    if (prova.tipo !== "entrega" || abrindo) return;
    setAbrindo(acesso.id);
    try {
      const resposta = await fetch("/api/digitais/entrar-no-curso", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ chave: prova.chave, produtoId: acesso.produtoId }),
      });
      const corpo = (await resposta.json().catch(() => null)) as { destino?: string; error?: string } | null;
      if (!resposta.ok || !corpo?.destino) throw new Error(corpo?.error || "Não foi possível abrir o conteúdo agora.");
      window.location.href = corpo.destino;
    } catch (erro) {
      avisoDaLoja.erro(erro instanceof Error ? erro.message : "Não foi possível abrir o conteúdo agora.");
      setAbrindo(null);
    }
  }

  async function usar(acesso: AcessoNaTela) {
    if (abrindo) return;
    /* O link abre numa aba nova. Ela nasce JÁ no clique (depois da resposta o
       navegador bloquearia como janela não pedida) e recebe o endereço depois. */
    const janela = acesso.tipo === "link" ? window.open("", "_blank") : null;
    if (janela) janela.opener = null;
    setAbrindo(acesso.id);
    try {
      const resposta = await fetch("/api/digitais/usar", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({
          acessoId: acesso.id,
          ...(prova.tipo === "entrega" ? { chaveDaEntrega: prova.chave } : {}),
          ...(prova.tipo === "membros" ? { slug: prova.slug } : {}),
        }),
      });
      const corpo = (await resposta.json().catch(() => null)) as { url?: string; error?: string; fechado?: boolean } | null;
      if (corpo?.fechado && corpo.error) {
        const motivo = corpo.error;
        setFechadosAgora((atual) => ({ ...atual, [acesso.id]: motivo }));
      }
      if (!resposta.ok || !corpo?.url) throw new Error(corpo?.error || "Não foi possível abrir agora. Tente de novo.");
      if (janela) janela.location.href = corpo.url;
      else window.location.href = corpo.url;
    } catch (erro) {
      if (janela) janela.close();
      avisoDaLoja.erro(erro instanceof Error ? erro.message : "Não foi possível abrir agora.");
    } finally {
      setAbrindo(null);
    }
  }

  if (!acessos.length) return null;

  return (
    <ul className={`divide-y ${cores.linha}`}>
      {acessos.map((original) => {
        const motivoAgora = fechadosAgora[original.id];
        const acesso: AcessoNaTela = motivoAgora ? { ...original, situacao: "fechado", motivo: motivoAgora } : original;
        const selo = seloDoAcesso(acesso);
        const detalhe = detalheDoAcesso(acesso);
        const liberado = acesso.situacao === "liberado";
        const baixavel = liberado && (acesso.tipo === "arquivo" || acesso.tipo === "link" || (acesso.tipo === "encomenda" && Boolean(acesso.arquivo)));
        const curso = liberado && (acesso.tipo === "curso" || (acesso.tipo === "live" && Boolean(acesso.live)));
        const ehLive = acesso.tipo === "live";
        const rotuloDoCurso = ehLive ? (acesso.live?.status === "encerrada" ? "Assistir" : "Entrar na live") : "Assistir";
        const destinoDoCurso = ehLive && acesso.live ? `/${prova.tipo === "entrega" ? "" : prova.slug}/live/${acesso.live.salaId}` : `/${prova.tipo === "entrega" ? "" : prova.slug}/membros/curso/${acesso.produtoId}`;
        const classeDoBotao =
          "inline-flex h-10 shrink-0 items-center justify-center gap-1.5 rounded-[10px] px-4 text-[12.5px] font-bold text-white transition hover:opacity-90 disabled:opacity-60";
        return (
          <li key={acesso.id} className="py-4">
            <div className="flex items-center gap-3.5">
              <span
                className="flex h-11 w-11 shrink-0 items-center justify-center rounded-xl text-[10px] font-extrabold tracking-wide text-white"
                style={{ backgroundColor: liberado ? corDoSelo(selo) : "#A3A9B8" }}
              >
                {selo}
              </span>
              <div className="min-w-0 flex-1">
                {mostrarProduto ? <div className={`truncate text-[11.5px] font-medium ${cores.produto}`}>{acesso.produto}</div> : null}
                <div className={`text-[14.5px] font-semibold leading-snug ${cores.titulo}`}>{acesso.titulo}</div>
                {detalhe ? (
                  <div className={`mt-0.5 text-[12.5px] leading-5 ${liberado ? cores.detalhe : cores.aviso}`}>{detalhe}</div>
                ) : null}
              </div>
              {curso ? (
                prova.tipo === "entrega" ? (
                  <button type="button" onClick={() => void assistir(acesso)} disabled={Boolean(abrindo)} className={classeDoBotao} style={{ backgroundColor: corDoBotao }}>
                    {abrindo === acesso.id ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <PlayCircle className="h-3.5 w-3.5" />}
                    {rotuloDoCurso}
                  </button>
                ) : (
                  <Link href={destinoDoCurso} className={classeDoBotao} style={{ backgroundColor: corDoBotao }}>
                    <PlayCircle className="h-3.5 w-3.5" />
                    {rotuloDoCurso}
                  </Link>
                )
              ) : baixavel ? (
                <button
                  type="button"
                  onClick={() => void usar(acesso)}
                  disabled={Boolean(abrindo)}
                  className="inline-flex h-10 shrink-0 items-center justify-center gap-1.5 rounded-[10px] px-4 text-[12.5px] font-bold text-white transition hover:opacity-90 disabled:opacity-60"
                  style={{ backgroundColor: corDoBotao }}
                >
                  {abrindo === acesso.id ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : acesso.tipo === "link" ? <ExternalLink className="h-3.5 w-3.5" /> : null}
                  {acesso.tipo === "link" ? "Abrir" : "Baixar"}
                </button>
              ) : !liberado ? (
                <span className={`inline-flex shrink-0 items-center gap-1 text-[12px] font-medium ${cores.fechado}`}>
                  {acesso.situacao !== "preparando" ? (
                    <Lock className="h-3.5 w-3.5" />
                  ) : acesso.espera?.tipo === "encomenda" ? (
                    <Hammer className="h-3.5 w-3.5" />
                  ) : acesso.espera?.tipo === "pre_venda" ? (
                    <CalendarClock className="h-3.5 w-3.5" />
                  ) : (
                    <Clock3 className="h-3.5 w-3.5" />
                  )}
                  {acesso.situacao !== "preparando"
                    ? "Fechado"
                    : acesso.espera?.tipo === "encomenda"
                      ? "Em produção"
                      : acesso.espera?.tipo === "pre_venda"
                        ? "Pré-venda"
                        : "Em preparo"}
                </span>
              ) : null}
            </div>
            {liberado && acesso.codigo ? (
              <div className={`ml-[58px] mt-2 flex items-center gap-2 rounded-xl px-3.5 py-2.5 ${cores.caixa}`}>
                <code className="min-w-0 flex-1 select-all break-all font-mono text-[14px] font-bold tracking-wide">{acesso.codigo}</code>
                <button
                  type="button"
                  onClick={() => void copiar(acesso)}
                  className="inline-flex h-8 shrink-0 items-center gap-1.5 rounded-lg px-2.5 text-[12px] font-bold text-white transition hover:opacity-90"
                  style={{ backgroundColor: corDoBotao }}
                  aria-label="Copiar o código"
                >
                  {copiado === acesso.id ? <Check className="h-3.5 w-3.5" /> : <Copy className="h-3.5 w-3.5" />}
                  {copiado === acesso.id ? "Copiado" : "Copiar"}
                </button>
              </div>
            ) : null}
            {liberado && acesso.instrucoes ? (
              <div className={`ml-[58px] mt-2 whitespace-pre-line rounded-xl px-3.5 py-3 text-[13px] leading-6 ${cores.caixa}`}>
                {acesso.instrucoes}
              </div>
            ) : null}
          </li>
        );
      })}
    </ul>
  );
}
