import { createAdminClient } from "@/lib/supabase-server";

import { assistentesLiberados } from "./liberacao";

/*
 * Os ajustes dos assistentes por empresa (migration 185):
 * - `liberado`: a empresa pode usar assistentes mesmo fora da variável
 *   ASSISTENTES_LIBERADOS (vale um OU outro);
 * - `confirmacao`: 'sensivel' (padrão) pede prévia com código só no que mexe
 *   em dinheiro, nota fiscal, exclusão, cancelamento e domínio; 'sempre' pede
 *   em toda criação e alteração.
 *
 * O assistente chama muitas vezes seguidas: os ajustes ficam lembrados por um
 * minuto, e quem muda pela tela apaga a lembrança na hora.
 */

export type Confirmacao = "sensivel" | "sempre";
export type AjustesDosAssistentes = { liberado: boolean; confirmacao: Confirmacao };

const PADRAO: AjustesDosAssistentes = { liberado: false, confirmacao: "sensivel" };
const LEMBRAR_POR_MS = 60_000;

declare global {
  var __ajustesDosAssistentes: Map<string, { valor: AjustesDosAssistentes; ate: number }> | undefined;
}

function lembranca() {
  globalThis.__ajustesDosAssistentes ??= new Map();
  return globalThis.__ajustesDosAssistentes;
}

function lerLinha(linha: { liberado?: unknown; confirmacao?: unknown } | null | undefined): AjustesDosAssistentes {
  if (!linha) return PADRAO;
  return { liberado: linha.liberado === true, confirmacao: linha.confirmacao === "sempre" ? "sempre" : "sensivel" };
}

/** Os ajustes da empresa (o primeiro id que tiver linha vale: empresa ou dono). */
export async function ajustesDaEmpresa(ids: Array<string | null | undefined>): Promise<AjustesDosAssistentes> {
  const validos = Array.from(new Set(ids.filter((id): id is string => Boolean(id))));
  if (!validos.length) return PADRAO;
  const chave = validos.join(",");
  const agora = Date.now();
  const guardado = lembranca().get(chave);
  if (guardado && guardado.ate > agora) return guardado.valor;

  const { data, error } = await createAdminClient().from("assistentes_ajustes").select("company_id,liberado,confirmacao").in("company_id", validos);
  if (error) {
    console.error("[assistentes] ler ajustes", error.message);
    return guardado?.valor ?? PADRAO;
  }
  const linhas = (data ?? []) as Array<{ company_id: string; liberado: boolean; confirmacao: string }>;
  const linha = validos.map((id) => linhas.find((l) => l.company_id === id)).find(Boolean) ?? null;
  const valor = lerLinha(linha);
  lembranca().set(chave, { valor, ate: agora + LEMBRAR_POR_MS });
  return valor;
}

/** A empresa pode usar assistentes? Variável do servidor OU liberação no banco. */
export async function assistentesLiberadosAgora(ids: Array<string | null | undefined>): Promise<boolean> {
  if (assistentesLiberados(ids)) return true;
  return (await ajustesDaEmpresa(ids)).liberado;
}

/**
 * Grava a escolha de confirmação da empresa e esquece a lembrança. Atualiza a
 * linha que já existir (pelo id da empresa ou do dono); sem nenhuma, cria com o
 * primeiro id.
 */
export async function gravarConfirmacao(ids: Array<string | null | undefined>, confirmacao: Confirmacao, quem: string): Promise<void> {
  const validos = Array.from(new Set(ids.filter((id): id is string => Boolean(id))));
  if (!validos.length) throw new Error("empresa sem id");
  const admin = createAdminClient();
  const { data: existentes } = await admin.from("assistentes_ajustes").select("company_id").in("company_id", validos);
  const alvo = validos.find((id) => (existentes ?? []).some((l: { company_id: string }) => l.company_id === id)) ?? validos[0];
  const { error } = await admin
    .from("assistentes_ajustes")
    .upsert({ company_id: alvo, confirmacao, atualizado_em: new Date().toISOString(), atualizado_por: quem }, { onConflict: "company_id" });
  if (error) throw new Error(error.message);
  for (const chave of lembranca().keys()) if (validos.some((id) => chave.split(",").includes(id))) lembranca().delete(chave);
}
