import { cookies } from "next/headers";
import { NextResponse } from "next/server";

import { confirmarPedidoSemValor } from "@/lib/catalog-payment-processing";
import { camposDaCompra, conferirDadosDaCompra, conferirRespostas, nomeDoCookieDaCompra, sugestaoDeEmail } from "@/lib/digitais/compra";
import { lerConfigDigitalDaLoja } from "@/lib/digitais/produto";
import { criarChave, origemDoPedido } from "@/lib/digitais/servidor/acessos";
import { acharOuCriarCliente, codigosAVenda, gravarPedidoDigital, lerProdutoDigitalAVenda, registrarNovidades } from "@/lib/digitais/servidor/compra";
import { textoDasNovidades } from "@/lib/digitais/textos";
import { motivoParaNaoVenderALive } from "@/lib/live/servidor/venda";
import { lerVisaoDaLoja } from "@/lib/loja/visao.server";
import { resolveMercadoPagoPublicConfig } from "@/lib/mercado-pago";
import { carregarPagamento, meiosDoLocal } from "@/lib/provedor-de-pagamento";
import { createAdminClient } from "@/lib/supabase-admin";

/*
 * A compra rápida de um produto digital: nome, e-mail, WhatsApp e CPF, sem
 * senha e sem endereço (no grátis, só nome e e-mail). Grava o pedido da loja
 * e devolve o que a tela precisa para cobrar (Pix ou cartão, pelo provedor da
 * loja). Grátis entrega na hora. Sob encomenda, as respostas do comprador vão
 * no item do pedido; código sem estoque não vende.
 *
 * Quem paga e acompanha é o navegador que comprou, por uma chave guardada em
 * cookie (só HTTP) que vale só para ESTA compra.
 */

const resposta = (corpo: Record<string, unknown>, status = 200) =>
  NextResponse.json(corpo, { status, headers: { "cache-control": "no-store" } });

export async function POST(request: Request) {
  try {
    const corpo = (await request.json().catch(() => null)) as Record<string, unknown> | null;
    const slug = typeof corpo?.slug === "string" ? corpo.slug.trim().toLowerCase().slice(0, 120) : "";
    const produtoId = typeof corpo?.produtoId === "string" ? corpo.produtoId : "";
    if (!slug || !produtoId) return resposta({ error: "Compra inválida." }, 400);

    const admin = createAdminClient();
    const { data: perfil } = await admin.from("profiles").select("*").eq("slug", slug).maybeSingle();
    if (!perfil) return resposta({ error: "Loja não encontrada." }, 404);
    const lojaId = String((perfil as { id: string }).id);

    /* As regras da loja valem igual: loja pausada, só para clientes, cadastro
       esperando aprovação... */
    const { visao, cliente } = await lerVisaoDaLoja(slug, perfil as Record<string, unknown>);
    if (visao.exigeLoginNaLoja || visao.precisaEntrar) {
      return resposta({ error: "Entre na sua conta da loja para comprar.", entrar: true }, 401);
    }
    if (!visao.podeComprar || visao.lojaPausada || visao.lojaFechada) {
      return resposta({ error: visao.motivoDoBloqueio || "A loja não está vendendo agora." }, 403);
    }
    /* Preço escondido para este visitante: a compra é pela conversa com a loja. */
    if (!visao.mostrarPreco) {
      return resposta({ error: "Fale com a loja para comprar este produto.", semPagamento: true }, 403);
    }

    const produto = await lerProdutoDigitalAVenda(admin, lojaId, produtoId);
    if (!produto) return resposta({ error: "Este produto não está mais à venda." }, 404);

    const gratis = produto.price <= 0;
    const config = lerConfigDigitalDaLoja(produto.digital_config);
    const conferencia = conferirDadosDaCompra(corpo, { gratis });
    if (!conferencia.ok) return resposta({ error: "Confira os campos marcados.", erros: conferencia.erros }, 400);
    const dados = conferencia.dados;
    /* Sob encomenda: o que a loja precisa saber para fazer. */
    const campos = config.entrega.modo === "encomenda" ? camposDaCompra(produto.custom_fields_config) : [];
    const respostas = conferirRespostas(campos, corpo?.campos);
    if (!respostas.ok) return resposta({ error: "Responda o que a loja precisa para fazer o seu.", errosDosCampos: respostas.erros }, 400);
    /* Códigos e licenças: sem código livre, não vende. */
    if (config.tipo === "codigo" && (await codigosAVenda(admin, lojaId, produto.id)) <= 0) {
      return resposta({ error: "Esgotado: os códigos deste produto acabaram. Fale com a loja.", esgotado: true }, 409);
    }
    /* Live: vagas, live já começou (e não vende durante), já aconteceu sem gravação. */
    if (config.tipo === "live") {
      const motivo = await motivoParaNaoVenderALive(admin, lojaId, produto.id);
      if (motivo) return resposta({ error: motivo, esgotado: true }, 409);
    }
    if (corpo?.confirmarEmail !== true) {
      const sugestao = sugestaoDeEmail(dados.email);
      if (sugestao) return resposta({ error: `Você quis dizer ${sugestao}?`, sugestaoDeEmail: sugestao }, 409);
    }

    const meios = produto.price > 0 ? await carregarPagamento(admin as never, lojaId).then((estado) => meiosDoLocal(estado, "loja")).catch(() => []) : [];
    if (produto.price > 0 && meios.length === 0) {
      return resposta({ error: "Esta loja ainda não recebe pagamento online. Fale com ela pelo WhatsApp.", semPagamento: true }, 409);
    }
    /* A compra rápida cobra Pix e cartão (boleto demora dias e a entrega é na hora). */
    const meiosDaCompra = meios.filter((m) => m.meio === "pix" || m.meio === "cartao");
    if (produto.price > 0 && meiosDaCompra.length === 0) {
      return resposta({ error: "Esta loja ainda não recebe Pix nem cartão online. Fale com ela pelo WhatsApp.", semPagamento: true }, 409);
    }

    const clienteLogado = cliente && cliente.status === "approved" ? cliente.id : null;
    const comprador = await acharOuCriarCliente(admin, lojaId, dados, clienteLogado);
    const pedido = await gravarPedidoDigital(admin, {
      slug,
      produto,
      clienteId: comprador.id,
      dados,
      provedor: meiosDaCompra[0]?.provedor ?? null,
      respostas: respostas.respostas,
    });
    if (gratis) {
      const nomeDaLoja = String((perfil as { catalog_name?: string | null; store_name?: string | null }).catalog_name || (perfil as { store_name?: string | null }).store_name || "loja");
      await registrarNovidades(admin, {
        lojaId,
        clienteId: comprador.id,
        produtoId: produto.id,
        catalogOrderId: pedido.id,
        novidades: corpo?.novidades === true,
        texto: textoDasNovidades(nomeDaLoja),
        ip: origemDoPedido(request).ip,
      });
    }

    const chave = await criarChave(admin, { lojaId, clienteId: comprador.id, finalidade: "compra", catalogOrderId: pedido.id });
    (await cookies()).set(nomeDoCookieDaCompra(pedido.id), chave, {
      httpOnly: true,
      sameSite: "lax",
      secure: process.env.NODE_ENV === "production",
      path: "/",
      maxAge: 7 * 24 * 60 * 60,
    });

    if (produto.price <= 0) {
      /* Grátis: confirma na hora, e o banco libera a entrega. */
      await confirmarPedidoSemValor(admin as never, pedido.id);
      return resposta({ ok: true, fluxo: "entregue", pedidoId: pedido.id, numero: pedido.number });
    }

    const linhaDoMercadoPago = meiosDaCompra.find((m) => m.provedor === "mercado_pago")?.integracao ?? null;
    const mercadoPago = linhaDoMercadoPago ? resolveMercadoPagoPublicConfig(linhaDoMercadoPago as never) : null;
    return resposta({
      ok: true,
      fluxo: "pagamento",
      pedidoId: pedido.id,
      numero: pedido.number,
      pagamento: {
        valor: produto.price,
        pagador: { name: dados.nome, email: dados.email, document: dados.documento },
        meios: meiosDaCompra.map((m) => ({ meio: m.meio, provedor: m.provedor })),
        mercadoPago: mercadoPago ? { ambiente: mercadoPago.environment, chavePublica: mercadoPago.publicKey } : null,
      },
    });
  } catch (erro) {
    console.error("[digitais] comprar", erro);
    return resposta({ error: erro instanceof Error ? erro.message : "Não foi possível concluir. Tente de novo." }, 500);
  }
}
