import { NextResponse } from "next/server";

import { origemDoPedido } from "@/lib/digitais/servidor/acessos";
import {
  CODIGOS_POR_CLIENTE_POR_HORA,
  CODIGOS_POR_IP_POR_HORA,
  VALIDADE_DO_CODIGO_MS,
  clienteDosMembros,
  emailValido,
  novoCodigo,
  resumoDoCodigo,
} from "@/lib/digitais/servidor/membros";
import { emailDaLojaConfigurado, enviarEmailDaLoja, montarEmailDaLoja } from "@/lib/email-da-loja";
import { lerAjustesDigitais } from "@/lib/digitais/servidor/vitrine";
import { createAdminClient } from "@/lib/supabase-admin";

/*
 * Pede o código de entrada da área de membros. A resposta é a mesma para
 * qualquer e-mail (não revela quem tem cadastro); o código só sai para quem
 * tem compras digitais nesta loja com este e-mail no cadastro.
 */

const RESPOSTA_NEUTRA = "Se este e-mail tiver compras nesta loja, o código chega em até 1 minuto. Confira também o spam.";

export async function POST(request: Request) {
  const semCache = { headers: { "cache-control": "no-store" } };
  try {
    const corpo = (await request.json().catch(() => null)) as { slug?: unknown; email?: unknown } | null;
    const slug = typeof corpo?.slug === "string" ? corpo.slug.trim().toLowerCase().slice(0, 120) : "";
    const email = typeof corpo?.email === "string" ? corpo.email.trim().toLowerCase().slice(0, 254) : "";
    if (!slug || !emailValido(email)) return NextResponse.json({ error: "Confira o e-mail." }, { status: 400, ...semCache });

    if (!emailDaLojaConfigurado()) {
      console.error("[digitais] código da área de membros sem e-mail configurado (RESEND_API_KEY / EMAIL_REMETENTE no apps/public).");
      return NextResponse.json(
        { error: "A loja ainda não consegue mandar o código por e-mail. Use o link do e-mail da sua compra." },
        { status: 503, ...semCache }
      );
    }

    const admin = createAdminClient();
    const { data: perfil } = await admin
      .from("profiles")
      .select("id,store_name,catalog_name,catalog_logo_url,logo_url,primary_color,company_email")
      .eq("slug", slug)
      .maybeSingle();
    const loja = perfil as {
      id: string;
      store_name: string | null;
      catalog_name: string | null;
      catalog_logo_url: string | null;
      logo_url: string | null;
      primary_color: string | null;
      company_email: string | null;
    } | null;
    if (!loja?.id) return NextResponse.json({ error: "Loja não encontrada." }, { status: 404, ...semCache });

    const cliente = await clienteDosMembros(admin, loja.id, email);
    if (!cliente) return NextResponse.json({ ok: true, message: RESPOSTA_NEUTRA }, semCache);

    /* Freios: por cliente e por endereço de rede. Passou, a resposta é a mesma. */
    const umaHoraAtras = new Date(Date.now() - 60 * 60 * 1000).toISOString();
    const { ip } = origemDoPedido(request);
    const { count: doCliente } = await admin
      .from("client_portal_codes")
      .select("id", { count: "exact", head: true })
      .eq("client_id", cliente.id)
      .eq("tipo", "entrar")
      .gte("criado_em", umaHoraAtras);
    if ((doCliente ?? 0) >= CODIGOS_POR_CLIENTE_POR_HORA) return NextResponse.json({ ok: true, message: RESPOSTA_NEUTRA }, semCache);
    if (ip) {
      const { count: doIp } = await admin
        .from("client_portal_codes")
        .select("id", { count: "exact", head: true })
        .eq("ip", ip.slice(0, 64))
        .gte("criado_em", umaHoraAtras);
      if ((doIp ?? 0) >= CODIGOS_POR_IP_POR_HORA) return NextResponse.json({ ok: true, message: RESPOSTA_NEUTRA }, semCache);
    }

    /* Um código vale por vez: os anteriores deste cliente deixam de valer. */
    const agora = new Date().toISOString();
    await admin.from("client_portal_codes").update({ usado_em: agora }).eq("client_id", cliente.id).eq("tipo", "entrar").is("usado_em", null);

    const codigo = novoCodigo();
    const { error } = await admin.from("client_portal_codes").insert({
      store_id: loja.id,
      client_id: cliente.id,
      tipo: "entrar",
      codigo_hash: resumoDoCodigo(cliente.id, codigo),
      expira_em: new Date(Date.now() + VALIDADE_DO_CODIGO_MS).toISOString(),
      ip: ip?.slice(0, 64) ?? null,
    });
    if (error) return NextResponse.json({ error: "Não foi possível mandar o código agora. Tente de novo." }, { status: 503, ...semCache });

    const nomeDaLoja = String(loja.catalog_name || loja.store_name || "Loja").trim();
    /* O nome da área de membros (Configurações dos digitais), quando a loja deu um. */
    const nomeDaArea = (await lerAjustesDigitais(admin, loja.id).catch(() => null))?.area.nome || "Minhas compras";
    const primeiroNome = String(cliente.name || "").trim().split(/\s+/)[0] || "";
    const separado = `${codigo.slice(0, 3)} ${codigo.slice(3)}`;
    const conteudo = montarEmailDaLoja({
      loja: { nome: nomeDaLoja, logo: loja.catalog_logo_url || loja.logo_url, cor: loja.primary_color },
      resumo: `Seu código para entrar em ${nomeDaArea}: ${separado}`,
      titulo: `Seu código: ${separado}`,
      paragrafos: [
        primeiroNome ? `Olá, ${primeiroNome}.` : "Olá.",
        `Use este código para entrar em ${nomeDaArea === "Minhas compras" ? `Minhas compras na ${nomeDaLoja}` : nomeDaArea}. Ele vale por 10 minutos e funciona uma vez só.`,
      ],
      observacao: "Se não foi você que pediu, é só ignorar este e-mail: ninguém entra sem o código.",
    });
    const envio = await enviarEmailDaLoja({
      para: email,
      assunto: `${separado} é o seu código na ${nomeDaLoja}`,
      html: conteudo.html,
      texto: conteudo.texto,
      nomeDaLoja,
      responderPara: loja.company_email,
    });
    if (!envio.ok) {
      console.error("[digitais] o código da área de membros não saiu:", envio.erro);
      return NextResponse.json({ error: "Não foi possível mandar o código agora. Tente de novo em instantes." }, { status: 503, ...semCache });
    }
    return NextResponse.json({ ok: true, message: RESPOSTA_NEUTRA }, semCache);
  } catch (erro) {
    console.error("[digitais] membros/codigo", erro);
    return NextResponse.json({ error: "Não foi possível mandar o código agora." }, { status: 500, ...semCache });
  }
}
