import { situacaoDaAssinatura, type SituacaoDaAssinatura } from "@/lib/assinatura";

import type { Admin } from "./base";

/**
 * A assinatura do Ktalogu vista pela EMPRESA, não por quem está logado.
 *
 * O middleware confere a linha de `users_app` do e-mail de quem entrou — e
 * funcionário não tem linha, então nunca era barrado. Aqui a pergunta é outra:
 * a empresa dona destas notas está em dia? A resposta vale para o dono, para
 * o funcionário e para a fila, que emite sem ninguém logado.
 *
 * Sem registro nenhum é "fechada": é o mesmo que a tela já fazia.
 */

export type AssinaturaDaEmpresa = {
  ativa: boolean;
  situacao: SituacaoDaAssinatura;
  mensagem: string;
  lidaEm: number;
};

const VALE_POR_MS = 60_000;

declare global {
  var __assinaturasDasEmpresas: Map<string, AssinaturaDaEmpresa> | undefined;
}

function memoria() {
  globalThis.__assinaturasDasEmpresas ??= new Map();
  return globalThis.__assinaturasDasEmpresas;
}

export function mensagemDaAssinatura(situacao: SituacaoDaAssinatura) {
  if (situacao === "ativa" || situacao === "teste") return "";
  if (situacao === "expirada") return "A assinatura do Ktalogu desta empresa venceu. Renove em Assinatura para voltar a emitir notas.";
  return "A assinatura do Ktalogu desta empresa está inativa. Regularize em Assinatura para emitir notas.";
}

function texto(valor: unknown) {
  return typeof valor === "string" && valor.trim() ? valor.trim() : null;
}

export async function emailDeCobranca(admin: Admin, empresaId: string): Promise<string | null> {
  const { data } = await admin.from("companies").select("billing_email").eq("owner_id", empresaId).limit(1);
  const daEmpresa = texto((data as Array<{ billing_email?: unknown }> | null)?.[0]?.billing_email);
  if (daEmpresa) return daEmpresa;
  /* Conta que nunca cadastrou empresa: o e-mail de cobrança é o do próprio login. */
  const { data: usuario } = await admin.auth.admin.getUserById(empresaId);
  return texto(usuario?.user?.email);
}

export async function assinaturaDaEmpresa(admin: Admin, empresaId: string): Promise<AssinaturaDaEmpresa> {
  const lembrada = memoria().get(empresaId);
  if (lembrada && Date.now() - lembrada.lidaEm < VALE_POR_MS) return lembrada;

  const email = await emailDeCobranca(admin, empresaId);
  let linha: { status?: unknown; expires_at?: unknown } | null = null;
  if (email) {
    const { data } = await admin.from("users_app").select("status,expires_at").ilike("email", email).limit(1);
    linha = (data as Array<{ status?: unknown; expires_at?: unknown }> | null)?.[0] ?? null;
  }
  const situacao = situacaoDaAssinatura(linha ? { status: texto(linha.status), expires_at: texto(linha.expires_at) } : null);
  const resultado: AssinaturaDaEmpresa = {
    ativa: situacao.ativa,
    situacao: situacao.situacao,
    mensagem: mensagemDaAssinatura(situacao.situacao),
    lidaEm: Date.now(),
  };
  if (memoria().size > 5000) memoria().clear();
  memoria().set(empresaId, resultado);
  return resultado;
}

/** Depois de um pagamento ou de um ajuste manual: a próxima leitura vai ao banco. */
export function esquecerAssinaturaDaEmpresa(empresaId?: string) {
  if (empresaId) memoria().delete(empresaId);
  else memoria().clear();
}
