"use client";

import Link from "next/link";
import { useCallback, useEffect, useRef, useState } from "react";
import { Toaster } from "sonner";
import { Check, CheckCircle2, Copy, CreditCard, Loader2, Lock, MessageCircle, QrCode, UserRound, Zap } from "lucide-react";

import { avisoDaLoja } from "@/components/AvisoDaLoja";
import CatalogMercadoPagoPanel from "@/components/CatalogMercadoPagoPanel";
import ListaDeAcessos from "@/components/digitais/ListaDeAcessos";
import { formatPhone } from "@/lib/client-portal-addresses";
import { ensureColorContrast, getReadableTextColor, withAlpha } from "@/lib/color-contrast";
import type { CampoDaCompra } from "@/lib/digitais/compra";
import { copiarTexto } from "@/lib/digitais/copiar";
import { ENTREGA_NA_HORA, textosDaEntrega, type EntregaNaVitrine } from "@/lib/digitais/produto";
import type { AcessoNaTela } from "@/lib/digitais/servidor/acessos";
import { TEXTO_DO_ACEITE, textoDasNovidades } from "@/lib/digitais/textos";
import { formatDocument } from "@/lib/document-utils";

/*
 * A compra rápida do produto digital (prévia 3).
 *
 * 1. dados: nome, e-mail, WhatsApp e CPF, sem senha e sem endereço (no
 *    grátis, só nome e e-mail, e a caixa de novidades desmarcada); sob
 *    encomenda, também o que a loja precisa saber para fazer;
 * 2. pagamento: Pix (código na tela) ou cartão (formulário do Mercado Pago,
 *    ou a fatura do Asaas, que se paga fora e volta para cá);
 * 3. a mesma tela vira a entrega assim que o pagamento cai.
 *
 * Quem prova que a compra é deste navegador é um cookie só HTTP que o servidor
 * grava no passo 1; a tela só guarda o número do pedido no endereço (?pedido=)
 * para retomar se a página recarregar.
 */

type Meio = "pix" | "cartao";

type Props = {
  slug: string;
  loja: { nome: string; logo: string | null; cor: string; whatsapp: string | null };
  produto: { id: string; nome: string; preco: number; imagem: string | null; resumo: string | null; itens: number; prazo: string };
  pagamento: {
    meios: Meio[];
    cartaoSaiDaLoja: boolean;
    mercadoPago: { ambiente: "sandbox" | "production"; chavePublica: string } | null;
  };
  pedidoRetomado: string | null;
  botaoWhatsapp: boolean;
  preenchido: { nome: string; email: string; whatsapp: string; documento: string } | null;
  /* Na hora, sob encomenda ou na pré-venda. */
  entrega?: EntregaNaVitrine;
  /* Sob encomenda: as perguntas da loja. */
  campos?: CampoDaCompra[];
  curso?: boolean;
};

type Dados = { nome: string; email: string; whatsapp: string; documento: string };
type Erros = Partial<Record<keyof Dados | "aceite", string>>;

type Cobranca = {
  status: string | null;
  qrCode: string | null;
  qrCodeBase64: string | null;
  expiraEm: string | null;
  urlDePagamento: string | null;
};

type Etapa = "dados" | "pagamento" | "entregue" | "outro_navegador";

const moeda = (valor: number) => new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(valor || 0);

function mensagemDoCartao(status: string | null, detalhe: string | null): string {
  if (status === "rejected") {
    if (detalhe === "cc_rejected_insufficient_amount") return "Pagamento recusado: limite insuficiente. Tente outro cartão ou o Pix.";
    if (detalhe === "cc_rejected_bad_filled_security_code") return "Código de segurança incorreto. Confira e tente de novo.";
    if (detalhe === "cc_rejected_bad_filled_date") return "Validade do cartão incorreta. Confira e tente de novo.";
    if (detalhe === "cc_rejected_call_for_authorize") return "O banco pediu autorização. Ligue para o seu banco ou use o Pix.";
    return "Pagamento recusado pelo banco do cartão. Tente outro cartão ou o Pix.";
  }
  if (status === "in_process" || status === "pending") return "Pagamento em análise. Assim que for aprovado, esta tela mostra a sua entrega.";
  return "Não foi possível concluir o pagamento. Tente de novo.";
}

function tempoRestante(expiraEm: string | null, agora: number): string | null {
  if (!expiraEm) return null;
  const fim = new Date(expiraEm).getTime();
  if (!Number.isFinite(fim)) return null;
  const segundos = Math.max(0, Math.floor((fim - agora) / 1000));
  if (segundos <= 0) return "venceu";
  const horas = Math.floor(segundos / 3600);
  const minutos = Math.floor((segundos % 3600) / 60);
  const resto = segundos % 60;
  return horas > 0 ? `vence em ${horas}h${String(minutos).padStart(2, "0")}` : `vence em ${minutos}:${String(resto).padStart(2, "0")}`;
}

export default function CompraRapida({
  slug,
  loja,
  produto,
  pagamento,
  pedidoRetomado,
  botaoWhatsapp,
  preenchido,
  entrega = ENTREGA_NA_HORA,
  campos = [],
  curso = false,
}: Props) {
  const promessa = textosDaEntrega(entrega, curso);
  const cor = loja.cor;
  const corNoBranco = ensureColorContrast(cor, "#FFFFFF", { dark: "#111827", light: "#FFFFFF", minRatio: 4.5 });
  const textoNoBotao = getReadableTextColor(cor);
  const gratis = produto.preco <= 0;

  const [etapa, setEtapa] = useState<Etapa>(pedidoRetomado ? "pagamento" : "dados");
  const [dados, setDados] = useState<Dados>({
    nome: preenchido?.nome ?? "",
    email: preenchido?.email ?? "",
    whatsapp: preenchido?.whatsapp ? formatPhone(preenchido.whatsapp) : "",
    documento: preenchido?.documento ? formatDocument(preenchido.documento) : "",
  });
  const [aceite, setAceite] = useState(false);
  /* Produto grátis: receber novidades da loja (desmarcada; fica guardado o que a pessoa escolheu). */
  const [novidades, setNovidades] = useState(false);
  const [respostas, setRespostas] = useState<Record<string, string>>({});
  const [errosDosCampos, setErrosDosCampos] = useState<Record<string, string>>({});
  const [erros, setErros] = useState<Erros>({});
  const [sugestao, setSugestao] = useState<string | null>(null);
  const [enviando, setEnviando] = useState(false);
  const [pedido, setPedido] = useState<{ id: string; numero: number | null } | null>(
    pedidoRetomado ? { id: pedidoRetomado, numero: null } : null
  );
  const [meio, setMeio] = useState<Meio>(pagamento.meios[0] ?? "pix");
  const [cobranca, setCobranca] = useState<Cobranca | null>(null);
  const [gerando, setGerando] = useState(false);
  const [avisoDoCartao, setAvisoDoCartao] = useState<string | null>(null);
  const [acessos, setAcessos] = useState<AcessoNaTela[]>([]);
  const [entregando, setEntregando] = useState(false);
  const [carregandoRetomada, setCarregandoRetomada] = useState(Boolean(pedidoRetomado));
  const [agora, setAgora] = useState(() => Date.now());
  const [copiado, setCopiado] = useState(false);
  const [salvandoNoZap, setSalvandoNoZap] = useState(false);
  /* Compra retomada não gera Pix sozinha: pode haver um cartão sendo confirmado. */
  const pixPedidoRef = useRef<string | null>(pedidoRetomado);
  const vivoRef = useRef(true);

  useEffect(() => {
    vivoRef.current = true;
    return () => {
      vivoRef.current = false;
    };
  }, []);

  /* O relógio do Pix. */
  useEffect(() => {
    if (etapa !== "pagamento" || !cobranca?.expiraEm) return;
    const relogio = window.setInterval(() => setAgora(Date.now()), 1000);
    return () => window.clearInterval(relogio);
  }, [etapa, cobranca?.expiraEm]);

  /* Guarda o pedido no endereço: recarregar a página retoma a compra. */
  const lembrarPedido = useCallback(
    (id: string) => {
      try {
        const url = new URL(window.location.href);
        url.searchParams.set("pedido", id);
        window.history.replaceState(null, "", url.toString());
      } catch {
        /* Sem isso, recarregar volta ao formulário; a compra segue no e-mail. */
      }
    },
    []
  );

  /* A situação da compra no servidor (o pagamento é conferido no provedor). */
  const conferir = useCallback(async (): Promise<"pago" | "pendente" | "sem_acesso" | "erro"> => {
    if (!pedido) return "erro";
    try {
      const resposta = await fetch(`/api/digitais/situacao?pedido=${encodeURIComponent(pedido.id)}`, { cache: "no-store" });
      if (resposta.status === 401) return "sem_acesso";
      const corpo = (await resposta.json().catch(() => null)) as {
        numero?: number | null;
        pago?: boolean;
        cancelado?: boolean;
        entregando?: boolean;
        acessos?: AcessoNaTela[];
        pagamento?: { status?: string | null; qrCode?: string | null; qrCodeBase64?: string | null; expiraEm?: string | null; metodo?: string | null } | null;
      } | null;
      if (!resposta.ok || !corpo) return "erro";
      if (!vivoRef.current) return "erro";
      if (corpo.numero) setPedido((atual) => (atual && atual.numero !== corpo.numero ? { ...atual, numero: corpo.numero ?? atual.numero } : atual));
      if (corpo.pago) {
        setAcessos(corpo.acessos ?? []);
        setEntregando(Boolean(corpo.entregando));
        setEtapa("entregue");
        return "pago";
      }
      if (corpo.pagamento && corpo.pagamento.status === "pending" && !corpo.pagamento.qrCode && corpo.pagamento.metodo && corpo.pagamento.metodo !== "pix") {
        /* Cartão que se paga fora da loja (fatura do Asaas): a confirmação chega sozinha. */
        setMeio("cartao");
        setAvisoDoCartao("Se você já pagou, a confirmação aparece aqui em instantes.");
      }
      if (corpo.pagamento && corpo.pagamento.status === "pending" && corpo.pagamento.qrCode) {
        setCobranca((atual) => ({
          status: "pending",
          qrCode: corpo.pagamento?.qrCode ?? null,
          qrCodeBase64: corpo.pagamento?.qrCodeBase64 ?? null,
          expiraEm: corpo.pagamento?.expiraEm ?? null,
          urlDePagamento: atual?.urlDePagamento ?? null,
        }));
        setMeio("pix");
        pixPedidoRef.current = pedido.id;
      }
      return "pendente";
    } catch {
      return "erro";
    }
  }, [pedido]);

  /* Compra retomada (página recarregada, volta do cartão). */
  useEffect(() => {
    if (!pedidoRetomado) return;
    let cancelado = false;
    void conferir().then((resultado) => {
      if (cancelado) return;
      if (resultado === "sem_acesso") setEtapa("outro_navegador");
      setCarregandoRetomada(false);
    });
    return () => {
      cancelado = true;
    };
    // Só na chegada à página.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  /* Esperando o pagamento: pergunta a cada 4 s (por até 40 min). */
  const esperando =
    etapa === "pagamento" &&
    !carregandoRetomada &&
    (Boolean(pedidoRetomado) || Boolean(cobranca && (cobranca.qrCode || cobranca.status === "in_process" || cobranca.status === "pending")));
  useEffect(() => {
    if (!esperando) return;
    let parar = false;
    const inicio = Date.now();
    let espera: number | undefined;
    const rodar = () => {
      if (parar || Date.now() - inicio > 40 * 60 * 1000) return;
      void conferir().then((resultado) => {
        if (parar || resultado === "pago") return;
        espera = window.setTimeout(rodar, 4000);
      });
    };
    espera = window.setTimeout(rodar, 4000);
    return () => {
      parar = true;
      if (espera) window.clearTimeout(espera);
    };
  }, [esperando, conferir]);

  /* Pago, mas o acesso ainda nascendo no banco: confere de novo em instantes. */
  useEffect(() => {
    if (etapa !== "entregue" || !entregando) return;
    let parar = false;
    let tentativas = 0;
    let espera: number | undefined;
    const rodar = () => {
      if (parar || tentativas >= 20) return;
      tentativas += 1;
      void conferir().then(() => {
        if (!parar) espera = window.setTimeout(rodar, 2500);
      });
    };
    espera = window.setTimeout(rodar, 1500);
    return () => {
      parar = true;
      if (espera) window.clearTimeout(espera);
    };
  }, [etapa, entregando, conferir]);

  async function enviarDados(confirmarEmail = false) {
    if (enviando) return;
    const novos: Erros = {};
    if (dados.nome.trim().split(/\s+/).length < 2) novos.nome = "Escreva o nome completo.";
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(dados.email.trim())) novos.email = "Confira o e-mail: é para ele que o acesso vai.";
    const zap = dados.whatsapp.replace(/\D/g, "");
    if ((!gratis || zap) && zap.length < 10) novos.whatsapp = "Confira o WhatsApp com DDD.";
    if (!gratis) {
      const digitos = dados.documento.replace(/\D/g, "");
      if (digitos.length !== 11 && digitos.length !== 14) novos.documento = "Confira o CPF (ou CNPJ).";
      if (!aceite) novos.aceite = "Marque a caixinha para continuar.";
    }
    const faltando: Record<string, string> = {};
    for (const pergunta of campos) {
      if (pergunta.obrigatorio && !String(respostas[pergunta.id] || "").trim()) faltando[pergunta.id] = "Responda para a loja fazer o seu.";
    }
    setErros(novos);
    setErrosDosCampos(faltando);
    if (Object.keys(novos).length || Object.keys(faltando).length) return;

    setEnviando(true);
    setSugestao(null);
    try {
      const resposta = await fetch("/api/digitais/comprar", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({
          slug,
          produtoId: produto.id,
          ...dados,
          ...(gratis ? { documento: "", novidades } : { aceite: true }),
          ...(campos.length ? { campos: respostas } : {}),
          confirmarEmail,
        }),
      });
      const corpo = (await resposta.json().catch(() => null)) as {
        error?: string;
        erros?: Erros;
        errosDosCampos?: Record<string, string>;
        sugestaoDeEmail?: string;
        entrar?: boolean;
        fluxo?: "entregue" | "pagamento";
        pedidoId?: string;
        numero?: number | null;
      } | null;
      if (resposta.status === 409 && corpo?.sugestaoDeEmail) {
        setSugestao(corpo.sugestaoDeEmail);
        return;
      }
      if (resposta.status === 401 && corpo?.entrar) {
        window.location.href = `/${slug}/cliente/login?next=${encodeURIComponent(`/${slug}/comprar/${produto.id}`)}`;
        return;
      }
      if (!resposta.ok || !corpo?.pedidoId) {
        if (corpo?.erros) setErros(corpo.erros);
        if (corpo?.errosDosCampos) setErrosDosCampos(corpo.errosDosCampos);
        throw new Error(corpo?.error || "Não foi possível continuar. Tente de novo.");
      }
      setPedido({ id: corpo.pedidoId, numero: corpo.numero ?? null });
      lembrarPedido(corpo.pedidoId);
      if (corpo.fluxo === "entregue") {
        setEtapa("entregue");
        setEntregando(true);
        return;
      }
      setEtapa("pagamento");
    } catch (erro) {
      avisoDaLoja.erro(erro instanceof Error ? erro.message : "Não foi possível continuar.", { corDaLoja: cor });
    } finally {
      setEnviando(false);
    }
  }

  /* Pede a cobrança (Pix, cartão do Mercado Pago ou fatura do Asaas). */
  const cobrar = useCallback(
    async (corpo: Record<string, unknown>): Promise<{ status: string | null; detalhe: string | null } | null> => {
      if (!pedido) return null;
      const resposta = await fetch("/api/digitais/pagar", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ slug, pedidoId: pedido.id, produtoId: produto.id, ...corpo }),
      });
      const dadosDaResposta = (await resposta.json().catch(() => null)) as {
        error?: string;
        status?: string | null;
        status_detail?: string | null;
        qr_code?: string | null;
        qr_code_base64?: string | null;
        payment_url?: string | null;
      } | null;
      if (resposta.status === 409 && /paga/i.test(String(dadosDaResposta?.error || ""))) {
        await conferir();
        return { status: "approved", detalhe: null };
      }
      if (!resposta.ok || !dadosDaResposta || dadosDaResposta.error) {
        throw new Error(dadosDaResposta?.error || "Não foi possível gerar o pagamento. Tente de novo.");
      }
      setCobranca({
        status: dadosDaResposta.status ?? null,
        qrCode: dadosDaResposta.qr_code ?? null,
        qrCodeBase64: dadosDaResposta.qr_code_base64 ?? null,
        expiraEm: null,
        urlDePagamento: dadosDaResposta.payment_url ?? null,
      });
      return { status: dadosDaResposta.status ?? null, detalhe: dadosDaResposta.status_detail ?? null };
    },
    [pedido, slug, produto.id, conferir]
  );

  const gerarPix = useCallback(async () => {
    if (!pedido || gerando) return;
    setGerando(true);
    setAvisoDoCartao(null);
    try {
      const resultado = await cobrar({
        meio: "pix",
        paymentType: "bank_transfer",
        selectedPaymentMethod: "bank_transfer",
        formData: { payment_method_id: "pix", transaction_amount: produto.preco },
      });
      pixPedidoRef.current = pedido.id;
      if (resultado?.status === "approved") await conferir();
      else void conferir();
    } catch (erro) {
      avisoDaLoja.erro(erro instanceof Error ? erro.message : "Não foi possível gerar o Pix.", { corDaLoja: cor });
    } finally {
      setGerando(false);
    }
  }, [pedido, gerando, cobrar, produto.preco, conferir, cor]);

  /* O Pix sai sozinho ao chegar no pagamento (um por pedido). */
  useEffect(() => {
    if (etapa !== "pagamento" || meio !== "pix" || carregandoRetomada || !pedido) return;
    if (pixPedidoRef.current === pedido.id || cobranca?.qrCode) return;
    if (!pagamento.meios.includes("pix")) return;
    pixPedidoRef.current = pedido.id;
    void gerarPix();
  }, [etapa, meio, carregandoRetomada, pedido, cobranca?.qrCode, pagamento.meios, gerarPix]);

  async function pagarComCartaoDoMercadoPago(pagamentoDoCartao: Record<string, unknown>) {
    setAvisoDoCartao(null);
    try {
      const resultado = await cobrar({
        meio: "cartao",
        paymentType: String(pagamentoDoCartao.paymentType || "credit_card"),
        selectedPaymentMethod: String(pagamentoDoCartao.selectedPaymentMethod || "credit_card"),
        formData: pagamentoDoCartao.formData || {},
      });
      if (resultado?.status === "approved") {
        await conferir();
        return;
      }
      setAvisoDoCartao(mensagemDoCartao(resultado?.status ?? null, resultado?.detalhe ?? null));
    } catch (erro) {
      setAvisoDoCartao(erro instanceof Error ? erro.message : "Não foi possível concluir o pagamento.");
    }
  }

  async function pagarComCartaoForaDaLoja() {
    if (gerando) return;
    setGerando(true);
    try {
      await cobrar({ meio: "cartao", paymentType: "credit_card", selectedPaymentMethod: "credit_card", formData: { transaction_amount: produto.preco } });
    } catch (erro) {
      avisoDaLoja.erro(erro instanceof Error ? erro.message : "Não foi possível abrir o pagamento.", { corDaLoja: cor });
    } finally {
      setGerando(false);
    }
  }

  /* Quando a fatura do Asaas fica pronta, vai para ela (e volta para cá). */
  useEffect(() => {
    if (cobranca?.urlDePagamento) window.location.href = cobranca.urlDePagamento;
  }, [cobranca?.urlDePagamento]);

  async function copiarPix() {
    if (!cobranca?.qrCode) return;
    if (await copiarTexto(cobranca.qrCode)) {
      setCopiado(true);
      window.setTimeout(() => setCopiado(false), 2500);
    } else {
      avisoDaLoja.erro("Não foi possível copiar. Selecione o código e copie.", { corDaLoja: cor });
    }
  }

  async function salvarNoWhatsapp() {
    if (!pedido || salvandoNoZap) return;
    const janela = window.open("", "_blank");
    if (janela) janela.opener = null;
    setSalvandoNoZap(true);
    try {
      const resposta = await fetch("/api/digitais/link-da-entrega", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ pedidoId: pedido.id }),
      });
      const corpo = (await resposta.json().catch(() => null)) as { caminho?: string; error?: string } | null;
      if (!resposta.ok || !corpo?.caminho) throw new Error(corpo?.error || "Não foi possível gerar o link agora.");
      const link = `${window.location.origin}${corpo.caminho}`;
      const texto = `Minha compra na ${loja.nome}: ${produto.nome}\n${link}`;
      const destino = `https://wa.me/?text=${encodeURIComponent(texto)}`;
      if (janela) janela.location.href = destino;
      else window.location.href = destino;
    } catch (erro) {
      if (janela) janela.close();
      avisoDaLoja.erro(erro instanceof Error ? erro.message : "Não foi possível gerar o link.", { corDaLoja: cor });
    } finally {
      setSalvandoNoZap(false);
    }
  }

  const primeiroNome = dados.nome.trim().split(/\s+/)[0] || "";
  /* O título segue o que a pessoa tem: a encomenda pronta ou a pré-venda que liberou já são dela. */
  const modoDoTitulo = acessos.length
    ? acessos.some((a) => a.espera?.tipo === "encomenda")
      ? "encomenda"
      : acessos.some((a) => a.espera?.tipo === "pre_venda")
        ? "pre_venda"
        : "na_hora"
    : entrega.modo;
  const campo = "h-12 w-full rounded-xl border-[1.5px] border-[#E2E5EC] bg-white px-3.5 text-[14px] text-[#1B2440] outline-none transition focus:border-[var(--cor)]";

  const resumo = (
    <aside className="rounded-[18px] border border-[#ECEEF3] bg-white p-5 sm:p-6">
      <h2 className="text-lg font-bold text-[#1B2440]">Seu pedido</h2>
      <div className="mt-3 grid grid-cols-[64px_1fr] items-center gap-3">
        <div className="h-16 w-16 overflow-hidden rounded-xl bg-[#F7F8FB]">
          {produto.imagem ? (
            /* eslint-disable-next-line @next/next/no-img-element */
            <img src={produto.imagem} alt="" className="h-full w-full object-cover" />
          ) : null}
        </div>
        <div className="min-w-0">
          <div className="text-[13.5px] font-semibold leading-snug text-[#1B2440]">{produto.nome}</div>
          <div className="mt-0.5 text-[12px] text-[#5E6478]">
            {[produto.resumo, produto.itens ? `${produto.itens} ${produto.itens === 1 ? "item" : "itens"}` : null].filter(Boolean).join(" · ") || "Produto digital"}
          </div>
        </div>
      </div>
      <div className="mt-4 border-t border-[#ECEEF3] pt-3 text-[13px]">
        <div className="flex justify-between py-1 text-[#5E6478]">
          <span>Produto</span>
          <span>{gratis ? "Grátis" : moeda(produto.preco)}</span>
        </div>
        <div className="flex justify-between py-1 text-[#5E6478]">
          <span>Frete</span>
          <span>Não tem</span>
        </div>
        <div className="flex justify-between pt-2.5 text-[17px] font-bold text-[#1B2440]">
          <span>Total</span>
          <span>{gratis ? "Grátis" : moeda(produto.preco)}</span>
        </div>
      </div>
      <div className="mt-4 flex gap-2 rounded-xl bg-[#E7F7F0] px-3 py-2.5 text-[12px] leading-5 text-[#0B6E4F]">
        <Zap className="mt-0.5 h-3.5 w-3.5 shrink-0" />
        {promessa ? (
          <span>
            {promessa.linha} {produto.prazo}
          </span>
        ) : (
          <span>
            Entrega na hora: nesta tela, no seu e-mail e em <b>Minhas compras</b>. {produto.prazo}
          </span>
        )}
      </div>
    </aside>
  );

  return (
    <div className="min-h-screen bg-[#F7F8FB] text-[#1B2440]" style={{ ["--cor" as string]: cor }}>
      <Toaster position="top-center" expand={false} />
      <header className="border-b border-[#ECEEF3] bg-white">
        <div className="mx-auto flex h-16 max-w-[1200px] items-center justify-between px-4 sm:px-7">
          <Link href={`/${slug}`} className="flex min-w-0 items-center gap-2">
            {loja.logo ? (
              /* eslint-disable-next-line @next/next/no-img-element */
              <img src={loja.logo} alt={loja.nome} className="h-8 w-auto max-w-[180px] object-contain" />
            ) : (
              <span className="truncate text-base font-bold">{loja.nome}</span>
            )}
          </Link>
          <span className="flex items-center gap-1.5 text-[12px] text-[#5E6478]">
            <Lock className="h-3.5 w-3.5" />
            Compra segura
          </span>
        </div>
      </header>

      {etapa === "outro_navegador" ? (
        <main className="mx-auto max-w-[640px] px-4 py-10">
          <div className="rounded-[18px] border border-[#ECEEF3] bg-white p-6 text-center">
            <h1 className="text-xl font-bold">Esta compra foi feita em outro navegador</h1>
            <p className="mt-2 text-sm leading-6 text-[#5E6478]">
              Por segurança, o andamento só aparece no navegador em que ela começou. Assim que o pagamento é aprovado, o acesso chega no
              seu e-mail. Você também acha tudo em Minhas compras.
            </p>
            <div className="mt-5 flex flex-wrap justify-center gap-2">
              <Link href={`/${slug}/membros`} className="inline-flex h-11 items-center rounded-xl px-5 text-sm font-bold" style={{ backgroundColor: cor, color: textoNoBotao }}>
                Minhas compras
              </Link>
              <Link href={`/${slug}/p/${produto.id}`} className="inline-flex h-11 items-center rounded-xl border border-[#ECEEF3] px-5 text-sm font-semibold">
                Voltar ao produto
              </Link>
            </div>
          </div>
        </main>
      ) : etapa === "entregue" ? (
        <main className="mx-auto max-w-[1200px] px-4 py-6 sm:px-7 sm:py-8">
          <div className="flex items-center gap-4 rounded-t-[18px] border border-[#ECEEF3] bg-white px-5 py-5 sm:px-6">
            <span className="flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-[#E7F7F0] text-[#0E9E70]">
              <CheckCircle2 className="h-6 w-6" />
            </span>
            <div className="min-w-0">
              <h1 className="text-[19px] font-bold leading-tight sm:text-xl">
                {primeiroNome ? `Pronto, ${primeiroNome}! ` : "Pronto! "}
                {modoDoTitulo === "encomenda"
                  ? "Sua encomenda está feita."
                  : modoDoTitulo === "pre_venda"
                    ? "Sua pré-venda está garantida."
                    : gratis
                      ? "Já é seu."
                      : "Sua compra já é sua."}
              </h1>
              <p className="mt-1 text-[13px] text-[#5E6478]">
                {pedido?.numero ? `Pedido #${pedido.numero} · ` : ""}
                {gratis ? "confirmado" : "pagamento confirmado"}
                {dados.email ? (
                  <>
                    {" "}· enviamos também para <b className="text-[#1B2440]">{dados.email}</b>
                  </>
                ) : null}
              </p>
            </div>
          </div>
          <div className="rounded-b-[18px] border border-t-0 border-[#ECEEF3] bg-white px-5 pb-5 sm:px-6">
            {acessos.length ? (
              <ListaDeAcessos acessos={acessos} prova={{ tipo: "compra", slug }} />
            ) : (
              <div className="flex items-center gap-2 py-6 text-sm text-[#5E6478]">
                <Loader2 className="h-4 w-4 animate-spin" />
                Preparando o seu acesso…
              </div>
            )}
            <div className="mt-3 flex flex-wrap gap-2.5">
              {botaoWhatsapp ? (
                <button
                  type="button"
                  onClick={() => void salvarNoWhatsapp()}
                  disabled={salvandoNoZap}
                  className="inline-flex h-10 items-center gap-2 rounded-[10px] border-[1.5px] border-[#ECEEF3] bg-white px-3.5 text-[12.5px] font-semibold disabled:opacity-60"
                >
                  {salvandoNoZap ? <Loader2 className="h-4 w-4 animate-spin" /> : <MessageCircle className="h-4 w-4" />}
                  Salvar no meu WhatsApp
                </button>
              ) : null}
              <Link
                href={`/${slug}/membros`}
                className="inline-flex h-10 items-center gap-2 rounded-[10px] border-[1.5px] border-[#ECEEF3] bg-white px-3.5 text-[12.5px] font-semibold"
              >
                <UserRound className="h-4 w-4" />
                Minhas compras
              </Link>
            </div>
            <p className="mt-3 text-[12px] leading-5 text-[#5E6478]">
              {produto.prazo} Perdeu o e-mail? Entre em Minhas compras com um código que chega no seu e-mail, sem senha.
            </p>
          </div>
        </main>
      ) : (
        <main className="mx-auto grid max-w-[1200px] gap-5 px-4 py-6 sm:px-7 sm:py-8 lg:grid-cols-[minmax(0,1fr)_380px] lg:gap-7">
          <div className="space-y-5">
            <section className="rounded-[18px] border border-[#ECEEF3] bg-white p-5 sm:p-6">
              <h2 className="text-lg font-bold">Seus dados</h2>
              <p className="mt-1 text-[12.5px] text-[#5E6478]">
                {gratis ? "Só nome e e-mail: é para onde o seu produto vai." : "Sem senha e sem endereço: é só para a loja saber para quem enviar."}
              </p>

              {etapa === "dados" ? (
                <form
                  className="mt-4 grid gap-3 sm:grid-cols-2"
                  onSubmit={(evento) => {
                    evento.preventDefault();
                    void enviarDados(false);
                  }}
                  noValidate
                >
                  {campos.length ? (
                    <div className="rounded-xl border border-[#F3E2C4] bg-[#FFF8EC] p-4 sm:col-span-2">
                      <div className="text-[13.5px] font-bold">Para a loja fazer o seu</div>
                      {promessa ? <p className="mt-0.5 text-[12px] leading-5 text-[#5E6478]">{promessa.linha}</p> : null}
                      <div className="mt-3 grid gap-3">
                        {campos.map((pergunta) => (
                          <label key={pergunta.id}>
                            <span className="mb-1.5 block text-[12px] font-semibold">
                              {pergunta.titulo}
                              {pergunta.obrigatorio ? "" : <span className="font-normal text-[#8A90A2]"> (opcional)</span>}
                            </span>
                            {pergunta.tipo === "textarea" ? (
                              <textarea
                                className="min-h-[96px] w-full rounded-xl border-[1.5px] border-[#E2E5EC] bg-white px-3.5 py-2.5 text-[14px] text-[#1B2440] outline-none transition focus:border-[var(--cor)]"
                                value={respostas[pergunta.id] ?? ""}
                                placeholder={pergunta.dica || undefined}
                                maxLength={1000}
                                onChange={(e) => setRespostas({ ...respostas, [pergunta.id]: e.target.value })}
                              />
                            ) : (
                              <input
                                className={campo}
                                value={respostas[pergunta.id] ?? ""}
                                placeholder={pergunta.dica || undefined}
                                inputMode={pergunta.tipo === "number" ? "decimal" : undefined}
                                maxLength={pergunta.tipo === "number" ? 20 : 200}
                                onChange={(e) => setRespostas({ ...respostas, [pergunta.id]: e.target.value })}
                              />
                            )}
                            {errosDosCampos[pergunta.id] ? <span className="mt-1 block text-[11.5px] text-[#C2410C]">{errosDosCampos[pergunta.id]}</span> : null}
                          </label>
                        ))}
                      </div>
                    </div>
                  ) : null}
                  <label className="sm:col-span-2">
                    <span className="mb-1.5 block text-[12px] font-semibold">Nome completo</span>
                    <input
                      className={campo}
                      value={dados.nome}
                      onChange={(e) => setDados({ ...dados, nome: e.target.value })}
                      autoComplete="name"
                      maxLength={120}
                    />
                    {erros.nome ? <span className="mt-1 block text-[11.5px] text-[#C2410C]">{erros.nome}</span> : null}
                  </label>
                  <label className="sm:col-span-2">
                    <span className="mb-1.5 block text-[12px] font-semibold">E-mail</span>
                    <input
                      className={campo}
                      type="email"
                      inputMode="email"
                      value={dados.email}
                      onChange={(e) => {
                        setDados({ ...dados, email: e.target.value });
                        setSugestao(null);
                      }}
                      autoComplete="email"
                      maxLength={254}
                    />
                    {sugestao ? (
                      <span className="mt-1.5 block text-[12px] leading-5 text-[#B9700F]">
                        Você quis dizer <b>{sugestao}</b>? É nesse e-mail que o acesso chega.{" "}
                        <button
                          type="button"
                          className="font-semibold underline"
                          onClick={() => {
                            setDados({ ...dados, email: sugestao });
                            setSugestao(null);
                          }}
                        >
                          Usar este
                        </button>{" "}
                        ·{" "}
                        <button type="button" className="font-semibold underline" onClick={() => void enviarDados(true)}>
                          O meu está certo
                        </button>
                      </span>
                    ) : erros.email ? (
                      <span className="mt-1 block text-[11.5px] text-[#C2410C]">{erros.email}</span>
                    ) : (
                      <span className="mt-1 block text-[11.5px] text-[#5E6478]">O acesso chega neste e-mail.</span>
                    )}
                  </label>
                  <label className={gratis ? "sm:col-span-2" : undefined}>
                    <span className="mb-1.5 block text-[12px] font-semibold">
                      WhatsApp{gratis ? <span className="font-normal text-[#8A90A2]"> (opcional)</span> : null}
                    </span>
                    <input
                      className={campo}
                      inputMode="tel"
                      value={dados.whatsapp}
                      onChange={(e) => setDados({ ...dados, whatsapp: formatPhone(e.target.value) })}
                      autoComplete="tel-national"
                      placeholder="(00) 00000-0000"
                    />
                    {erros.whatsapp ? <span className="mt-1 block text-[11.5px] text-[#C2410C]">{erros.whatsapp}</span> : null}
                  </label>
                  <label hidden={gratis}>
                    <span className="mb-1.5 block text-[12px] font-semibold">CPF</span>
                    <input
                      className={campo}
                      inputMode="numeric"
                      value={dados.documento}
                      onChange={(e) => setDados({ ...dados, documento: formatDocument(e.target.value) })}
                      placeholder="000.000.000-00"
                    />
                    {erros.documento ? (
                      <span className="mt-1 block text-[11.5px] text-[#C2410C]">{erros.documento}</span>
                    ) : (
                      <span className="mt-1 block text-[11.5px] text-[#5E6478]">Para a nota fiscal.</span>
                    )}
                  </label>

                  {gratis ? (
                    <label className="flex cursor-pointer items-start gap-2.5 text-[12.5px] leading-5 text-[#5E6478] sm:col-span-2">
                      <input
                        type="checkbox"
                        checked={novidades}
                        onChange={(e) => setNovidades(e.target.checked)}
                        className="mt-0.5 h-[18px] w-[18px] shrink-0 accent-[var(--cor)]"
                      />
                      <span>{textoDasNovidades(loja.nome)}</span>
                    </label>
                  ) : (
                    <label className="flex cursor-pointer items-start gap-2.5 text-[12.5px] leading-5 text-[#5E6478] sm:col-span-2">
                      <input
                        type="checkbox"
                        checked={aceite}
                        onChange={(e) => setAceite(e.target.checked)}
                        className="mt-0.5 h-[18px] w-[18px] shrink-0 accent-[var(--cor)]"
                      />
                      <span>
                        {TEXTO_DO_ACEITE} <span className="text-[#8A90A2]">(Fica registrado com data e hora.)</span>
                        {erros.aceite ? <span className="block text-[11.5px] text-[#C2410C]">{erros.aceite}</span> : null}
                      </span>
                    </label>
                  )}

                  <div className="sm:col-span-2">
                    <button
                      type="submit"
                      disabled={enviando}
                      className="inline-flex h-12 w-full items-center justify-center gap-2 rounded-xl px-6 text-[15px] font-bold shadow-sm transition hover:opacity-90 disabled:opacity-60"
                      style={{ backgroundColor: cor, color: textoNoBotao }}
                    >
                      {enviando ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
                      {gratis ? (entrega.modo === "na_hora" ? "Receber agora" : promessa?.botao ?? "Receber agora") : "Continuar para o pagamento"}
                    </button>
                  </div>
                </form>
              ) : (
                <div className="mt-4 flex flex-wrap items-center justify-between gap-3 rounded-xl bg-[#F7F8FB] px-4 py-3 text-[13px]">
                  <div className="min-w-0">
                    {dados.nome ? <div className="font-semibold">{dados.nome}</div> : null}
                    <div className="truncate text-[#5E6478]">{dados.email || "Os dados desta compra estão guardados no pedido."}</div>
                  </div>
                  {!pedidoRetomado ? (
                    <button
                      type="button"
                      className="text-[12.5px] font-semibold underline-offset-2 hover:underline"
                      style={{ color: corNoBranco }}
                      onClick={() => {
                        setEtapa("dados");
                        setCobranca(null);
                        setPedido(null);
                        pixPedidoRef.current = null;
                      }}
                    >
                      Corrigir dados
                    </button>
                  ) : null}
                </div>
              )}
            </section>

            {etapa === "pagamento" ? (
              <section className="rounded-[18px] border border-[#ECEEF3] bg-white p-5 sm:p-6">
                <h2 className="text-lg font-bold">Pagamento</h2>
                {carregandoRetomada ? (
                  <div className="mt-4 flex items-center gap-2 text-sm text-[#5E6478]">
                    <Loader2 className="h-4 w-4 animate-spin" />
                    Conferindo o pagamento…
                  </div>
                ) : (
                  <>
                    {pagamento.meios.length > 1 ? (
                      <div className="mt-4 flex gap-2">
                        {pagamento.meios.map((opcao) => {
                          const ativo = meio === opcao;
                          return (
                            <button
                              key={opcao}
                              type="button"
                              onClick={() => {
                                setMeio(opcao);
                                setAvisoDoCartao(null);
                              }}
                              aria-pressed={ativo}
                              className="flex flex-1 items-center justify-center gap-2 rounded-xl border-[1.5px] px-3 py-3 text-[13px] font-semibold transition"
                              style={
                                ativo
                                  ? { borderColor: cor, color: corNoBranco, backgroundColor: withAlpha(cor, 0.08) }
                                  : { borderColor: "#E2E5EC", color: "#5E6478" }
                              }
                            >
                              {opcao === "pix" ? <QrCode className="h-4 w-4" /> : <CreditCard className="h-4 w-4" />}
                              {opcao === "pix" ? "Pix" : "Cartão de crédito"}
                            </button>
                          );
                        })}
                      </div>
                    ) : null}

                    {meio === "pix" ? (
                      <div className="mt-4">
                        {cobranca?.qrCode ? (
                          <div className="grid items-center gap-4 rounded-2xl bg-[#F7F8FB] p-4 sm:grid-cols-[160px_1fr]">
                            <div className="mx-auto h-[160px] w-[160px] overflow-hidden rounded-xl border-8 border-white bg-white shadow-[0_0_0_1px_#ECEEF3]">
                              {cobranca.qrCodeBase64 ? (
                                /* eslint-disable-next-line @next/next/no-img-element */
                                <img src={`data:image/png;base64,${cobranca.qrCodeBase64}`} alt="QR Code do Pix" className="h-full w-full" />
                              ) : (
                                <div className="flex h-full items-center justify-center text-[#8A90A2]">
                                  <QrCode className="h-10 w-10" />
                                </div>
                              )}
                            </div>
                            <div className="min-w-0 text-center sm:text-left">
                              <p className="text-[12.5px] leading-5 text-[#5E6478]">
                                Abra o app do seu banco e leia o QR, ou copie o código.{" "}
                                <b className="text-[#1B2440]">Assim que o pagamento cair, esta tela vira a sua entrega</b> — não precisa fazer mais nada.
                              </p>
                              <div className="mt-2.5 flex gap-2">
                                <span className="min-w-0 flex-1 truncate rounded-[10px] border border-dashed border-[#D5D9E2] px-2.5 py-2 text-[11px] text-[#8A90A2]">
                                  {cobranca.qrCode}
                                </span>
                                <button
                                  type="button"
                                  onClick={() => void copiarPix()}
                                  className="inline-flex shrink-0 items-center gap-1.5 rounded-[10px] px-3.5 text-[12.5px] font-bold"
                                  style={{ backgroundColor: cor, color: textoNoBotao }}
                                >
                                  {copiado ? <Check className="h-3.5 w-3.5" /> : <Copy className="h-3.5 w-3.5" />}
                                  {copiado ? "Copiado" : "Copiar"}
                                </button>
                              </div>
                              <div className="mt-2.5 flex items-center justify-center gap-2 text-[12px] font-semibold text-[#0E9E70] sm:justify-start">
                                <span className="h-2.5 w-2.5 rounded-full bg-[#0E9E70] shadow-[0_0_0_4px_#E7F7F0]" />
                                Aguardando o pagamento…
                                {tempoRestante(cobranca.expiraEm, agora) ? ` · ${tempoRestante(cobranca.expiraEm, agora)}` : ""}
                              </div>
                            </div>
                          </div>
                        ) : (
                          <button
                            type="button"
                            onClick={() => void gerarPix()}
                            disabled={gerando}
                            className="inline-flex h-12 w-full items-center justify-center gap-2 rounded-xl px-6 text-[15px] font-bold disabled:opacity-60"
                            style={{ backgroundColor: cor, color: textoNoBotao }}
                          >
                            {gerando ? <Loader2 className="h-4 w-4 animate-spin" /> : <QrCode className="h-4 w-4" />}
                            {gerando ? "Gerando o código Pix…" : "Gerar código Pix"}
                          </button>
                        )}
                      </div>
                    ) : null}

                    {meio === "cartao" ? (
                      <div className="mt-4 space-y-3">
                        {avisoDoCartao ? (
                          <div className="rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-[13px] text-amber-800">{avisoDoCartao}</div>
                        ) : null}
                        {pagamento.cartaoSaiDaLoja ? (
                          <>
                            <p className="text-[13px] leading-6 text-[#5E6478]">
                              O cartão é pago numa página segura do Asaas, o processador desta loja. Assim que for aprovado, você volta para cá
                              com a entrega pronta.
                            </p>
                            <button
                              type="button"
                              onClick={() => void pagarComCartaoForaDaLoja()}
                              disabled={gerando}
                              className="inline-flex h-12 w-full items-center justify-center gap-2 rounded-xl px-6 text-[15px] font-bold disabled:opacity-60"
                              style={{ backgroundColor: cor, color: textoNoBotao }}
                            >
                              {gerando ? <Loader2 className="h-4 w-4 animate-spin" /> : <CreditCard className="h-4 w-4" />}
                              {gerando ? "Abrindo o pagamento…" : "Pagar com cartão"}
                            </button>
                          </>
                        ) : pagamento.mercadoPago && pedido ? (
                          <CatalogMercadoPagoPanel
                            showHeader={false}
                            allowedPaymentTypes={["creditCard"]}
                            publicKey={pagamento.mercadoPago.chavePublica}
                            environment={pagamento.mercadoPago.ambiente}
                            amount={produto.preco}
                            payer={{ name: dados.nome, email: dados.email, document: dados.documento.replace(/\D/g, "") }}
                            primaryColor={cor}
                            onSubmitPayment={pagarComCartaoDoMercadoPago}
                          />
                        ) : (
                          <p className="text-[13px] text-[#5E6478]">O cartão não está disponível agora. Use o Pix.</p>
                        )}
                      </div>
                    ) : null}
                  </>
                )}
              </section>
            ) : null}
          </div>

          {resumo}
        </main>
      )}
    </div>
  );
}
