import { NextResponse } from "next/server";

import { lerVencimento, statusLibera } from "@/lib/assinatura";
import { PRODUTO_KTALOGU } from "@/lib/assinatura-cakto";
import { getCompanyContext } from "@/lib/company-context";
import { emailDeCobranca } from "@/lib/fiscal/servidor/assinatura-da-empresa";
import { tiposDosPagamentos } from "@/lib/historico-da-assinatura";
import { createAdminClient, createClient } from "@/lib/supabase-server";

export const runtime = "nodejs";

/**
 * A assinatura da empresa de quem está logado, para a tela de Assinatura e a
 * faixa do painel: plano, de onde veio (plano novo, plano antigo ou dado à
 * mão), se renova sozinha, crédito de dias e o histórico de pagamentos.
 * Responde também com a assinatura vencida: é daqui que ela renova.
 */

const STATUS_DO_HISTORICO = ["paid", "refunded", "chargedback", "refund_requested", "refused"];

export async function GET() {
  const supabase = await createClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();
  if (!user) return NextResponse.json({ error: "Não autenticado." }, { status: 401 });

  const ctx = await getCompanyContext(supabase, user);
  const admin = createAdminClient();
  const email = String((ctx.ownerId ? await emailDeCobranca(admin, ctx.ownerId) : user.email) ?? "").trim().toLowerCase();
  if (!email) return NextResponse.json({ error: "Conta sem e-mail de cobrança." }, { status: 400 });

  const [{ data: acesso }, { data: assinaturas }, { data: pagamentos }] = await Promise.all([
    admin.from("users_app").select("status,expires_at,plan").eq("email", email).maybeSingle(),
    admin
      .from("assinaturas_cakto")
      .select("cakto_subscription_id,produto_id,plano,situacao,metodo,pago_ate,proxima_cobranca,dias_de_credito,substituida_por,atualizada_em")
      .eq("email", email)
      .order("atualizada_em", { ascending: false })
      .limit(30),
    admin
      .from("pagamentos_cakto")
      .select("pedido_id,ref_id,assinatura_id,plano,valor,metodo,parcelas,status,criado_em,pago_em,reembolsado_em,contestado_em")
      .eq("email", email)
      .in("status", STATUS_DO_HISTORICO)
      .order("criado_em", { ascending: false })
      .limit(24),
  ]);

  type Linha = {
    cakto_subscription_id: string;
    produto_id: string | null;
    plano: string;
    situacao: string;
    metodo: string | null;
    pago_ate: string | null;
    proxima_cobranca: string | null;
    dias_de_credito: number | null;
    substituida_por: string | null;
  };
  const linhas = (assinaturas ?? []) as Linha[];
  const tipos = tiposDosPagamentos(
    (pagamentos ?? []).map((p) => ({ id: p.pedido_id, assinaturaId: p.assinatura_id, status: p.status, data: p.pago_em ?? p.criado_em })),
    linhas.map((l) => ({ id: l.cakto_subscription_id, plano: l.plano, substituidaPor: l.substituida_por, antiga: Boolean(l.produto_id && l.produto_id !== PRODUTO_KTALOGU) }))
  );
  /* A assinatura que manda: a do plano novo ainda de pé (ativa, atrasada ou
     pausada); senão a mais recente dele, se houver. */
  const doPlanoNovo = linhas.filter((l) => l.produto_id === PRODUTO_KTALOGU || !l.produto_id);
  const atual = doPlanoNovo.find((l) => ["ativa", "atrasada", "pausada"].includes(l.situacao)) ?? doPlanoNovo[0] ?? null;

  const venceEm = lerVencimento(acesso?.expires_at);
  const ativa = Boolean(venceEm && venceEm.getTime() > Date.now() && statusLibera(acesso?.status).libera);
  const planoDoAcesso = String(acesso?.plan ?? "").toLowerCase();
  const origem = atual ? "nova" : acesso ? (planoDoAcesso === "mensal" || planoDoAcesso === "anual" ? "antiga" : "manual") : "nenhuma";
  const renovaSozinha = Boolean(atual && atual.situacao === "ativa" && (atual.metodo === "credit_card" || atual.metodo === "pix_auto"));

  return NextResponse.json(
    {
      origem,
      plano: atual?.plano ?? (planoDoAcesso === "mensal" || planoDoAcesso === "anual" ? planoDoAcesso : null),
      ativa,
      venceEm: venceEm?.toISOString() ?? null,
      renovaSozinha,
      metodo: atual?.metodo ?? null,
      proximaCobranca: renovaSozinha ? atual?.proxima_cobranca ?? null : null,
      situacaoNaCakto: atual?.situacao ?? null,
      pagamentoRecusado: atual?.situacao === "atrasada",
      diasDeCredito: Math.max(0, Number(atual?.dias_de_credito ?? 0)),
      historico: (pagamentos ?? []).map((p) => ({
        /* O número curto é o que aparece no comprovante e no suporte da forma de pagamento. */
        pedido: p.ref_id ?? p.pedido_id,
        plano: p.plano,
        tipo: tipos.get(p.pedido_id) ?? null,
        valor: p.valor === null ? null : Number(p.valor),
        metodo: p.metodo,
        parcelas: p.parcelas,
        status: p.status,
        data: p.pago_em ?? p.criado_em,
        estornadoEm: p.contestado_em ?? p.reembolsado_em,
      })),
    },
    { headers: { "Cache-Control": "no-store" } }
  );
}
