import * as kv from "./kv_store.tsx";
import * as kvAtomic from "./kv_atomic.tsx";
import { isValidNuit, normalizeNuit } from "./nuit.tsx";
import { listarUsuariosEmpresa } from "./usuarios.tsx";

// Tipo para Empresa
export type Empresa = {
  id: string;
  // Identificação
  nomeEmpresa: string;
  nomeComercial: string;
  nuit: string;
  codigoInterno?: string;
  tipoEmpresa?: string;
  dataConstituicao?: string;
  
  // Contacto
  email: string;
  telefone: string;
  telemovel?: string;
  fax?: string;
  website?: string;
  
  // Morada
  endereco: string;
  enderecoFiscal?: string;
  cidade: string;
  provincia: string;
  codigoPostal?: string;
  pais: string;
  
  // Dados Fiscais
  regimeFiscal?: string;
  regimeIva: string; // "normal", "isento", "nao-sujeito"
  regimeIVA?: string;
  tratamentoFiscalPadrao?: string;
  taxaIvaPadrao?: number; // 🆕 NOVA: Taxa padrão configurável (ex: 16.0)
  // Controla se a caixa "Não liquid." aparece nos formularios de
  // Factura/Nota/Cotacao quando uma linha tem "IVA incluido" marcado.
  // Omissao (campo em falta) e tratada como activo, para preservar o
  // comportamento actual de empresas ja existentes.
  ivaIncluidoNaoLiquidadoActivo?: boolean;
  ispcTipoAtividade?: string;
  ispcVolumeNegociosAnual?: number;
  ispcTaxaAplicavel?: number;
  ispcElegivel?: boolean;
  taxasIvaAdicionais?: Array<{ // 🆕 NOVA: Taxas adicionais (reduzida, etc)
    id: string;
    nome: string;
    taxa: number;
  }>;
  meiosPagamentoPersonalizados?: Array<{
    value: string;
    label: string;
    usaContaFinanceira: boolean;
  }>;
  condicoesPagamentoPersonalizadas?: Array<{
    value: string;
    label: string;
    dias: number | null;
  }>;
  actividadePrincipal?: string;
  cae?: string;
  alvara?: string;
  capitalSocial?: string;
  salarioMinimoSetorMzn?: number; // Salario minimo legal do sector de actividade desta empresa (MZN/mes) — usado no calculo de indemnizacao por rescisao por motivos estruturais (Art. 141 n.3 da Lei n.13/2023, ver cessacao-contrato.tsx)
  
  // Configurações Financeiras
  moedaPadrao: string;
  moedaBase?: string;
  anoFiscal: string;
  metodoInventario?: string;
  
  // Dados Bancários (múltiplos)
  bancos?: Array<{
    tipo?: "banco" | "mpesa" | "emola";
    banco: string;
    titular?: string;
    numeroConta: string;
    telefone?: string;
    nib?: string;
    iban?: string;
    swift?: string;
    moeda: string;
    contaPadrao: boolean;
  }>;
  contasBancarias?: Array<{
    tipo?: "banco" | "mpesa" | "emola";
    banco: string;
    titular?: string;
    numeroConta: string;
    telefone?: string;
    nib?: string;
    iban?: string;
    swift?: string;
    moeda?: string;
    contaPadrao?: boolean;
  }>;
  
  // Configurações do Sistema
  logotipo?: string;
  logo?: string;
  corCabecalho?: string;
  numeroSerieInicial?: string;
  formatoDocumentos?: string;
  seriesDocumentais?: Array<{
    id: string;
    tipoDocumento: "factura" | "factura_recibo";
    nome: string;
    codigo: string;
    prefixo?: string;
    formato?: string;
    ativa: boolean;
    padrao: boolean;
    dataCriacao?: string;
  }>;
  
  // Controle Multi-Tenant
  status: "ativa" | "suspensa" | "inativa";
  paymentStatus: "em-dia" | "pendente" | "atrasado";
  plano: string;
  taxaInscricao?: number; // NOVO: taxa de inscrição
  valorAvenca: number;
  proximoPagamento: string;
  diasEmAtraso?: number; // NOVO: dias em atraso
  
  // Credenciais de Acesso (para Tonline gerenciar)
  emailAcesso?: string; // Email gerado automaticamente para login
  senhaGerada?: string; // Senha gerada automaticamente (guardada para Tonline)

  // Dados administrativos do formulário
  nomeRepresentante?: string;
  biRepresentante?: string;
  cargoRepresentante?: string;
  observacoes?: string;
  
  // Auditoria
  dataCadastro: string;
  dataUltimaAtualizacao?: string;
  ultimoAcesso?: string;
  criadoPor?: string;

  // Programa de Revendedores: id do Revendedor cujo link/codigo de
  // referencia foi usado no cadastro desta empresa (ver revendedores.tsx).
  // Nunca muda depois de definido - a comissao e vitalicia por desenho.
  referidoPor?: string;
};

// Prefixo para as chaves do KV Store
const EMPRESA_PREFIX = "empresa:";
const EMPRESA_NUIT_INDEX = "empresa_nuit_index:";
const EMPRESA_EMAIL_INDEX = "empresa_email_index:";
const LIMITE_ISPC_VOLUME_ANUAL = 4_000_000;

export function normalizarRegimeFiscalServidor(valor: unknown): string {
  const regime = String(valor || "").toLowerCase();

  if (["ispc", "regime-ispc"].includes(regime)) return "ispc";
  if (["isento", "isento-iva", "iva-isento"].includes(regime)) return "isento-iva";
  if (["nao-sujeito", "nao-sujeito-iva", "não-sujeito", "nao_sujeito"].includes(regime)) {
    return "nao-sujeito-iva";
  }
  if (["especial", "regime-especial", "outro"].includes(regime)) return "regime-especial";

  return "regime-geral-iva";
}

function tratamentoPadraoPorRegimeServidor(regimeFiscal: string): string {
  if (regimeFiscal === "ispc") return "ispc";
  if (regimeFiscal === "isento-iva") return "isento";
  if (regimeFiscal === "nao-sujeito-iva") return "nao-sujeito";
  if (regimeFiscal === "regime-especial") return "especial";
  return "iva-normal";
}

function taxaIvaPorTratamentoServidor(
  regimeFiscal: string,
  tratamentoFiscal: string,
  taxaPersonalizada?: unknown,
): number {
  if (regimeFiscal === "ispc" || regimeFiscal === "isento-iva" || regimeFiscal === "nao-sujeito-iva") {
    return 0;
  }

  if (tratamentoFiscal === "iva-reduzida") return 5;
  if (tratamentoFiscal === "iva-exportacao" || tratamentoFiscal === "isento" || tratamentoFiscal === "nao-sujeito") return 0;
  if (tratamentoFiscal === "especial") {
    const taxa = Number(taxaPersonalizada);
    return Number.isFinite(taxa) ? taxa : 0;
  }

  return 16;
}

function calcularTaxaIspcServidor(tipoAtividade?: string, volumeAnual?: unknown): number {
  const volume = Number(volumeAnual || 0);

  if (!Number.isFinite(volume) || volume <= 0 || volume > LIMITE_ISPC_VOLUME_ANUAL) {
    return 0;
  }

  if (tipoAtividade === "servicos-gerais") return 12;
  if (tipoAtividade === "profissoes-liberais") return 15;
  if (volume > 2_500_000) return 5;
  if (volume > 1_000_000) return 4;
  return 3;
}

/**
 * Gerar ID único para empresa
 */
function gerarIdEmpresa(): string {
  return `emp_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
}

/**
 * Validar email
 */
function validarEmail(email: string): boolean {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}

function criarSnapshotEmpresa(empresa: Empresa) {
  return {
    empresaId: empresa.id,
    capturadoEm: new Date().toISOString(),
    nome: empresa.nomeComercial || empresa.nomeEmpresa || "",
    nomeEmpresa: empresa.nomeEmpresa || "",
    nomeComercial: empresa.nomeComercial || "",
    slogan: empresa.actividadePrincipal || "",
    nuit: empresa.nuit || "",
    email: empresa.email || "",
    telefone: empresa.telefone || "",
    telemovel: empresa.telemovel || "",
    fax: empresa.fax || "",
    website: empresa.website || "",
    endereco: empresa.endereco || "",
    cidade: empresa.cidade || "",
    provincia: empresa.provincia || "",
    codigoPostal: empresa.codigoPostal || "",
    pais: empresa.pais || "",
    regimeFiscal: empresa.regimeFiscal || empresa.regimeIva || "",
    regimeIva: empresa.regimeIva || "",
    tratamentoFiscalPadrao: empresa.tratamentoFiscalPadrao || "",
    taxaIvaPadrao: Number(empresa.taxaIvaPadrao || 0) || 0,
    ispcTipoAtividade: empresa.ispcTipoAtividade || "",
    ispcTaxaAplicavel: Number(empresa.ispcTaxaAplicavel || 0) || 0,
    moedaPadrao: empresa.moedaPadrao || "",
    actividadePrincipal: empresa.actividadePrincipal || "",
    logotipo: empresa.logotipo || "",
    corCabecalho: empresa.corCabecalho || "",
    bancos: empresa.bancos || [],
    formatoDocumentos: empresa.formatoDocumentos || "",
  };
}

async function congelarDocumentosSemSnapshot(empresa: Empresa): Promise<number> {
  const snapshot = criarSnapshotEmpresa(empresa);
  const prefixes = [
    `factura:${empresa.id}:`,
    `recibo:${empresa.id}:`,
    `cotacao:${empresa.id}:`,
    `nota:${empresa.id}:`,
    `adiantamento:${empresa.id}:`,
    `vd:${empresa.id}:`,
  ];

  let atualizados = 0;

  for (const prefix of prefixes) {
    const documentos = await kv.getByPrefixWithKeys(prefix);

    for (const documento of documentos) {
      if (!documento?.value || documento.value.empresaSnapshot) {
        continue;
      }

      await kv.set(documento.key, {
        ...documento.value,
        empresaSnapshot: snapshot,
      });
      atualizados += 1;
    }
  }

  return atualizados;
}

export async function congelarSnapshotsDocumentosEmpresa(
  id: string,
): Promise<{ success: boolean; data?: { documentosCongelados: number }; error?: string }> {
  try {
    const empresa = await buscarEmpresaPorId(id);

    if (!empresa) {
      return { success: false, error: "Empresa não encontrada" };
    }

    const documentosCongelados = await congelarDocumentosSemSnapshot(empresa);
    return { success: true, data: { documentosCongelados } };
  } catch (error) {
    return {
      success: false,
      error: `Erro ao congelar snapshots dos documentos: ${error.message}`,
    };
  }
}

/**
 * Criar nova empresa
 */
export async function criarEmpresa(dados: Partial<Empresa>): Promise<{ success: boolean; data?: Empresa; error?: string }> {
  const indicesReservados: string[] = [];
  let empresaSalva = false;

  try {
    console.log(`[EMPRESAS] 🆕 CRIAR EMPRESA - Iniciando...`);
    console.log(`[EMPRESAS] Dados recebidos:`, JSON.stringify(dados, null, 2));
    
    // ⚠️ VALIDAÇÕES MÍNIMAS (frontend já validou tudo)
    // Apenas verificar se os campos essenciais existem
    if (!dados.nomeEmpresa || !dados.nomeComercial || !dados.nuit || !dados.email) {
      console.error(`[EMPRESAS] ❌ Dados essenciais faltando`);
      return { success: false, error: "Dados essenciais faltando (nome, NUIT, email)" };
    }
    
    const nuitNormalizado = normalizeNuit(dados.nuit);
    if (!isValidNuit(nuitNormalizado)) {
      return { success: false, error: "NUIT inválido (deve ter 9 dígitos)" };
    }
    
    // Verificar se NUIT já existe
    console.log(`[EMPRESAS] 🔍 Verificando se NUIT ${nuitNormalizado} já existe...`);
    const nuitIndex = await kv.get(`${EMPRESA_NUIT_INDEX}${nuitNormalizado}`);
    console.log(`[EMPRESAS] Resultado índice NUIT:`, nuitIndex);
    if (nuitIndex) {
      console.error(`[EMPRESAS] ❌ NUIT já cadastrado no sistema`);
      return { success: false, error: "NUIT já cadastrado no sistema" };
    }
    
    // Verificar se email já existe
    console.log(`[EMPRESAS] 🔍 Verificando se email ${dados.email} já existe...`);
    const emailIndex = await kv.get(`${EMPRESA_EMAIL_INDEX}${dados.email.toLowerCase()}`);
    console.log(`[EMPRESAS] Resultado índice Email:`, emailIndex);
    if (emailIndex) {
      console.error(`[EMPRESAS] ❌ Email já cadastrado no sistema`);
      return { success: false, error: "Email já cadastrado no sistema" };
    }
    
    // Criar empresa
    const id = gerarIdEmpresa();
    const emailNormalizado = dados.email.trim().toLowerCase();
    const nuitIndexKey = `${EMPRESA_NUIT_INDEX}${nuitNormalizado}`;
    const emailIndexKey = `${EMPRESA_EMAIL_INDEX}${emailNormalizado}`;

    const reservaNuit = await kvAtomic.createIfAbsent(nuitIndexKey, id);
    if (!reservaNuit.created) {
      return { success: false, error: "NUIT ja cadastrado no sistema" };
    }
    indicesReservados.push(nuitIndexKey);

    const reservaEmail = await kvAtomic.createIfAbsent(emailIndexKey, id);
    if (!reservaEmail.created) {
      await kvAtomic.deleteKey(nuitIndexKey).catch(() => {});
      indicesReservados.pop();
      return { success: false, error: "Email ja cadastrado no sistema" };
    }
    indicesReservados.push(emailIndexKey);

    const agora = new Date().toISOString();
    const endereco = dados.endereco || dados.enderecoFiscal || "";
    const regimeFiscal = normalizarRegimeFiscalServidor(dados.regimeFiscal || dados.regimeIva || dados.regimeIVA);
    const tratamentoFiscalPadrao =
      dados.tratamentoFiscalPadrao || tratamentoPadraoPorRegimeServidor(regimeFiscal);
    const moedaPadrao = dados.moedaPadrao || dados.moedaBase || "MZN";
    const bancos = dados.bancos || dados.contasBancarias || [];
    const logotipo = dados.logotipo || dados.logo || "";
    const taxaIvaRecebida = Number(dados.taxaIvaPadrao);
    const taxaIvaPadrao = taxaIvaPorTratamentoServidor(
      regimeFiscal,
      tratamentoFiscalPadrao,
      Number.isFinite(taxaIvaRecebida) ? taxaIvaRecebida : 16.0,
    );
    const ispcTipoAtividade = dados.ispcTipoAtividade || "bens-comercio-industria-agricultura";
    const ispcVolumeNegociosAnual = Number(dados.ispcVolumeNegociosAnual || 0);
    const ispcTaxaAplicavel = calcularTaxaIspcServidor(ispcTipoAtividade, ispcVolumeNegociosAnual);
    
    const empresa: Empresa = {
      id,
      nomeEmpresa: dados.nomeEmpresa.trim(),
      nomeComercial: dados.nomeComercial.trim(),
      nuit: nuitNormalizado,
      email: emailNormalizado,
      codigoInterno: dados.codigoInterno?.trim() || "",
      tipoEmpresa: dados.tipoEmpresa || "",
      dataConstituicao: dados.dataConstituicao || "",
      telefone: dados.telefone?.trim() || "",
      telemovel: dados.telemovel?.trim() || "",
      fax: dados.fax?.trim() || "",
      website: dados.website?.trim() || "",
      endereco: endereco.trim(),
      enderecoFiscal: endereco.trim(),
      cidade: dados.cidade?.trim() || "",
      provincia: dados.provincia?.trim() || "",
      codigoPostal: dados.codigoPostal?.trim() || "",
      pais: dados.pais?.trim() || "Moçambique",
      regimeFiscal,
      regimeIva: regimeFiscal,
      regimeIVA: regimeFiscal,
      tratamentoFiscalPadrao,
      taxaIvaPadrao, // 🆕 NOVA: Taxa padrão configurável (ex: 16.0)
      ivaIncluidoNaoLiquidadoActivo: dados.ivaIncluidoNaoLiquidadoActivo !== false,
      ispcTipoAtividade,
      ispcVolumeNegociosAnual,
      ispcTaxaAplicavel,
      ispcElegivel:
        regimeFiscal === "ispc" &&
        ispcVolumeNegociosAnual > 0 &&
        ispcVolumeNegociosAnual <= LIMITE_ISPC_VOLUME_ANUAL,
      taxasIvaAdicionais: dados.taxasIvaAdicionais || [], // 🆕 NOVA: Taxas adicionais (reduzida, etc)
      actividadePrincipal: dados.actividadePrincipal?.trim() || "",
      cae: dados.cae?.trim() || "",
      alvara: dados.alvara?.trim() || "",
      capitalSocial: dados.capitalSocial?.trim() || "",
      moedaPadrao,
      moedaBase: moedaPadrao,
      anoFiscal: dados.anoFiscal || new Date().getFullYear().toString(),
      metodoInventario: dados.metodoInventario || "FIFO",
      bancos,
      contasBancarias: bancos,
      logotipo,
      logo: logotipo,
      corCabecalho: dados.corCabecalho || "#1e3a8a",
      numeroSerieInicial: dados.numeroSerieInicial || "1",
      formatoDocumentos: dados.formatoDocumentos || "FAT{YYYY}{MM}{NNNN}",
      nomeRepresentante: dados.nomeRepresentante?.trim() || "",
      biRepresentante: dados.biRepresentante?.trim() || "",
      cargoRepresentante: dados.cargoRepresentante?.trim() || "",
      observacoes: dados.observacoes?.trim() || "",
      status: "ativa",
      paymentStatus: "em-dia",
      plano: dados.plano || "",
      taxaInscricao: dados.taxaInscricao || 0, // NOVO: taxa de inscrição
      valorAvenca: dados.valorAvenca || 0,
      proximoPagamento: dados.proximoPagamento || new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString().split("T")[0],
      dataCadastro: agora,
      dataUltimaAtualizacao: agora,
      ultimoAcesso: agora,
      criadoPor: dados.criadoPor || "Tonline Admin",
      referidoPor: dados.referidoPor || undefined,
    };
    
    console.log(`[EMPRESAS] 💾 Objeto empresa criado:`, JSON.stringify(empresa, null, 2));
    console.log(`[EMPRESAS] 💾 Salvando empresa com chave: ${EMPRESA_PREFIX}${id}`);
    
    // Salvar empresa
    const setResult = await kv.set(`${EMPRESA_PREFIX}${id}`, empresa);
    empresaSalva = true;
    console.log(`[EMPRESAS] 💾 Resultado do kv.set():`, setResult);
    
    // VERIFICAÇÃO: Ler imediatamente o que foi salvo
    console.log(`[EMPRESAS] 🔍 Verificando se foi realmente salvo...`);
    const verificacao = await kv.get(`${EMPRESA_PREFIX}${id}`);
    console.log(`[EMPRESAS] 🔍 Dados lidos após salvar:`, verificacao ? JSON.stringify(verificacao, null, 2) : 'NULL');
    
    // Criar índices
    console.log(`[EMPRESAS] 📇 Criando índices...`);
    await kv.set(`${EMPRESA_NUIT_INDEX}${empresa.nuit}`, id);
    await kv.set(`${EMPRESA_EMAIL_INDEX}${empresa.email}`, id);
    console.log(`[EMPRESAS] 📇 Índices criados: NUIT e Email`);
    
    // VERIFICAÇÃO: Ler índices
    const verificacaoNuit = await kv.get(`${EMPRESA_NUIT_INDEX}${empresa.nuit}`);
    const verificacaoEmail = await kv.get(`${EMPRESA_EMAIL_INDEX}${empresa.email}`);
    console.log(`[EMPRESAS] 🔍 Índice NUIT:`, verificacaoNuit);
    console.log(`[EMPRESAS] 🔍 Índice Email:`, verificacaoEmail);
    
    console.log(`[EMPRESAS] ✅ Empresa criada com sucesso: ${id} - ${empresa.nomeComercial}`);
    
    return { success: true, data: empresa };
  } catch (error) {
    if (!empresaSalva) {
      await Promise.all(indicesReservados.map((key) => kvAtomic.deleteKey(key).catch(() => {})));
    }
    console.error("[EMPRESAS] ❌ Erro ao criar empresa:", error);
    return { success: false, error: `Erro ao criar empresa: ${error.message}` };
  }
}

/**
 * Buscar empresa por ID
 */
export async function buscarEmpresaPorId(id: string): Promise<Empresa | null> {
  try {
    // Normalizar ID: remover prefixo se já existir
    const idNormalizado = id.startsWith(EMPRESA_PREFIX) ? id.replace(EMPRESA_PREFIX, '') : id;
    
    console.log(`[EMPRESAS] 🔍 Buscando empresa por ID: ${id}`);
    console.log(`[EMPRESAS] 🔍 ID normalizado: ${idNormalizado}`);
    console.log(`[EMPRESAS] 🔍 Key completa: ${EMPRESA_PREFIX}${idNormalizado}`);
    
    let empresa = await kv.get(`${EMPRESA_PREFIX}${idNormalizado}`);
    
    // Se não encontrou, tentar buscar SEM o prefixo (fallback para IDs antigos)
    if (!empresa && !id.startsWith(EMPRESA_PREFIX)) {
      console.log(`[EMPRESAS] ⚠️ Não encontrado com prefixo, tentando ID direto: ${id}`);
      empresa = await kv.get(id);
    }
    
    // Se AINDA não encontrou, tentar adicionar prefixo se não tiver
    if (!empresa && id.startsWith(EMPRESA_PREFIX)) {
      console.log(`[EMPRESAS] ⚠️ Não encontrado, tentando sem prefixo: ${id.replace(EMPRESA_PREFIX, '')}`);
      empresa = await kv.get(id.replace(EMPRESA_PREFIX, ''));
    }
    
    if (empresa) {
      console.log(`[EMPRESAS] ✅ Empresa encontrada: ${(empresa as Empresa).nomeComercial}`);
    } else {
      console.log(`[EMPRESAS] ❌ Empresa não encontrada com ID: ${id}`);
      
      // ✅ DIAGNÓSTICO COMPLETO: Listar todas as empresas disponíveis
      console.log(`[EMPRESAS] 🔍 Iniciando diagnóstico completo do KV Store...`);
      
      // Tentar buscar com prefixo empresa:
      const todasEmpresas = await kv.getByPrefix(EMPRESA_PREFIX);
      console.log(`[EMPRESAS] 📊 Total de empresas com prefixo '${EMPRESA_PREFIX}': ${todasEmpresas.length}`);
      if (todasEmpresas.length > 0) {
        console.log(`[EMPRESAS] 📋 Empresas com prefixo 'empresa:':`)
        todasEmpresas.forEach((e: any, idx: number) => {
          console.log(`  ${idx + 1}. ID: ${e.id} | NUIT: ${e.nuit} | Nome: ${e.nomeComercial}`);
        });
      }
      
      // Tentar buscar sem prefixo também (apenas "emp_")
      const empresasSemPrefixo = await kv.getByPrefix('emp_');
      console.log(`[EMPRESAS] 📊 Empresas com prefixo 'emp_' (sem 'empresa:'): ${empresasSemPrefixo.length}`);
      if (empresasSemPrefixo.length > 0) {
        console.log(`[EMPRESAS] 📋 Empresas sem prefixo correto:`)
        empresasSemPrefixo.forEach((e: any, idx: number) => {
          console.log(`  ${idx + 1}. ID: ${e.id} | NUIT: ${e.nuit} | Nome: ${e.nomeComercial}`);
        });
      }
      
      // ✅ TENTATIVA DE RECUPERAÇÃO: Se existe empresa mas com chave errada, tentar encontrar
      if (empresasSemPrefixo.length > 0) {
        const empresaEncontrada = empresasSemPrefixo.find((e: any) => e.id === id || e.id === idNormalizado);
        if (empresaEncontrada) {
          console.log(`[EMPRESAS] ✅ RECUPERAÇÃO: Empresa encontrada com chave incorreta!`);
          console.log(`[EMPRESAS] ✅ Retornando empresa: ${empresaEncontrada.nomeComercial}`);
          return empresaEncontrada as Empresa;
        }
      }
      
      // ✅ TENTATIVA FINAL: Buscar em todas as empresas pelo ID
      const todasAsPossiveisEmpresas = [...todasEmpresas, ...empresasSemPrefixo];
      const empresaPorId = todasAsPossiveisEmpresas.find((e: any) => 
        e.id === id || 
        e.id === idNormalizado || 
        e.id === `${EMPRESA_PREFIX}${id}` ||
        e.id === `${EMPRESA_PREFIX}${idNormalizado}`
      );
      
      if (empresaPorId) {
        console.log(`[EMPRESAS] ✅ RECUPERAÇÃO FINAL: Empresa encontrada em varredura completa!`);
        console.log(`[EMPRESAS] ✅ Retornando empresa: ${empresaPorId.nomeComercial}`);
        return empresaPorId as Empresa;
      }
    }
    
    return empresa as Empresa | null;
  } catch (error) {
    console.error("[EMPRESAS] Erro ao buscar empresa:", error);
    return null;
  }
}

/**
 * Buscar empresa por NUIT
 */
export async function buscarEmpresaPorNuit(nuit: string): Promise<Empresa | null> {
  try {
    const id = await kv.get(`${EMPRESA_NUIT_INDEX}${nuit}`);
    if (!id) return null;
    return await buscarEmpresaPorId(id as string);
  } catch (error) {
    console.error("[EMPRESAS] Erro ao buscar empresa por NUIT:", error);
    return null;
  }
}

/**
 * Buscar empresa por email
 */
export async function buscarEmpresaPorEmail(email: string): Promise<Empresa | null> {
  try {
    const emailNormalizado = String(email || "").trim().toLowerCase();
    if (!emailNormalizado) return null;

    const id = await kv.get(`${EMPRESA_EMAIL_INDEX}${emailNormalizado}`);
    if (!id) return null;
    return await buscarEmpresaPorId(id as string);
  } catch (error) {
    console.error("[EMPRESAS] Erro ao buscar empresa por email:", error);
    return null;
  }
}

/**
 * Listar todas as empresas
 */
export async function listarEmpresas(): Promise<Empresa[]> {
  try {
    const resultados = await kv.getByPrefix(EMPRESA_PREFIX);
    console.log(`[EMPRESAS] ✅ getByPrefix retornou ${resultados.length} resultados`);
    
    // CRÍTICO: getByPrefix() retorna os valores DIRETAMENTE, não {key, value}
    const empresas = resultados
      .filter((emp: any) => emp !== null && emp !== undefined); // Apenas remover null/undefined
    
    console.log(`[EMPRESAS] ✅ Retornando ${empresas.length} empresas (TODAS do banco)`);
    
    // Log detalhado de cada empresa
    empresas.forEach((emp: any, idx: number) => {
      console.log(`[EMPRESAS] ${idx + 1}. ${emp.nomeComercial || 'SEM NOME'} (ID: ${emp.id || 'SEM ID'})`);
    });
    
    return empresas as Empresa[];
  } catch (error) {
    console.error("[EMPRESAS] ❌ Erro ao listar empresas:", error);
    return [];
  }
}

/**
 * Atualizar empresa
 */
export async function atualizarEmpresa(id: string, dados: Partial<Empresa>): Promise<{ success: boolean; data?: Empresa; error?: string }> {
  try {
    console.log(`[EMPRESAS] ===== ATUALIZAR EMPRESA =====`);
    console.log(`[EMPRESAS] ID: ${id}`);
    console.log(`[EMPRESAS] Dados recebidos:`, JSON.stringify(dados, null, 2));
    console.log(`[EMPRESAS] Logotipo recebido?`, !!dados.logotipo);
    console.log(`[EMPRESAS] Logotipo (primeiros 100 chars):`, dados.logotipo?.substring(0, 100));
    console.log(`[EMPRESAS] Bancos recebidos:`, JSON.stringify(dados.bancos, null, 2));
    
    // ✅ PROTEÇÃO CRÍTICA: Campos de subscrição não podem ser alterados via PUT
    const CAMPOS_PROTEGIDOS_SUBSCRICAO = [
      'plano',
      'valorAvenca',
      'taxaInscricao',
      'paymentStatus',
      'proximoPagamento',
      'diasEmAtraso',
      // ✅ status e exclusivo do endpoint PATCH /empresas/:id/status
      // (alterarStatusEmpresa). Sem esta protecao, qualquer gravacao geral
      // da empresa (ex: editar morada) reenviava o valor de status que
      // estava carregado no formulario no momento em que foi aberto,
      // revertendo silenciosamente uma suspensao manual para "ativa".
      'status',
    ];
    
    for (const campo of CAMPOS_PROTEGIDOS_SUBSCRICAO) {
      if (campo in dados) {
        console.error(`[EMPRESAS] ❌ Tentativa de alterar campo protegido: ${campo}`);
        return {
          success: false,
          error: `Campo '${campo}' é protegido e não pode ser alterado via atualização geral. Use o endpoint específico de subscrição.`
        };
      }
    }
    
    const empresaExistente = await buscarEmpresaPorId(id);
    
    if (!empresaExistente) {
      return { success: false, error: "Empresa não encontrada" };
    }
    
    console.log(`[EMPRESAS] Empresa existente - Logotipo atual:`, empresaExistente.logotipo?.substring(0, 100));
    console.log(`[EMPRESAS] Empresa existente - Bancos atuais:`, JSON.stringify(empresaExistente.bancos, null, 2));

    const dadosNormalizados: Partial<Empresa> = { ...dados };

    if (
      dados.regimeFiscal !== undefined ||
      dados.regimeIva !== undefined ||
      dados.regimeIVA !== undefined ||
      dados.tratamentoFiscalPadrao !== undefined ||
      dados.taxaIvaPadrao !== undefined
    ) {
      const regimeFiscal = normalizarRegimeFiscalServidor(
        dados.regimeFiscal || dados.regimeIva || dados.regimeIVA || empresaExistente.regimeFiscal || empresaExistente.regimeIva,
      );
      const tratamentoFiscalPadrao =
        dados.tratamentoFiscalPadrao ||
        empresaExistente.tratamentoFiscalPadrao ||
        tratamentoPadraoPorRegimeServidor(regimeFiscal);
      const taxaIvaBase =
        dados.taxaIvaPadrao !== undefined ? dados.taxaIvaPadrao : empresaExistente.taxaIvaPadrao;

      dadosNormalizados.regimeFiscal = regimeFiscal;
      dadosNormalizados.regimeIva = regimeFiscal;
      dadosNormalizados.regimeIVA = regimeFiscal;
      dadosNormalizados.tratamentoFiscalPadrao = tratamentoFiscalPadrao;
      dadosNormalizados.taxaIvaPadrao = taxaIvaPorTratamentoServidor(
        regimeFiscal,
        tratamentoFiscalPadrao,
        taxaIvaBase,
      );
    }

    if (
      dados.ispcTipoAtividade !== undefined ||
      dados.ispcVolumeNegociosAnual !== undefined ||
      dadosNormalizados.regimeFiscal === "ispc"
    ) {
      const ispcTipoAtividade =
        dados.ispcTipoAtividade ||
        empresaExistente.ispcTipoAtividade ||
        "bens-comercio-industria-agricultura";
      const ispcVolumeNegociosAnual = Number(
        dados.ispcVolumeNegociosAnual ?? empresaExistente.ispcVolumeNegociosAnual ?? 0,
      );
      const ispcTaxaAplicavel = calcularTaxaIspcServidor(ispcTipoAtividade, ispcVolumeNegociosAnual);

      dadosNormalizados.ispcTipoAtividade = ispcTipoAtividade;
      dadosNormalizados.ispcVolumeNegociosAnual = Number.isFinite(ispcVolumeNegociosAnual)
        ? ispcVolumeNegociosAnual
        : 0;
      dadosNormalizados.ispcTaxaAplicavel = ispcTaxaAplicavel;
      dadosNormalizados.ispcElegivel =
        dadosNormalizados.regimeFiscal === "ispc" &&
        ispcVolumeNegociosAnual > 0 &&
        ispcVolumeNegociosAnual <= LIMITE_ISPC_VOLUME_ANUAL;
    }

    if (dados.enderecoFiscal !== undefined && dados.endereco === undefined) {
      dadosNormalizados.endereco = dados.enderecoFiscal;
    }
    if (dadosNormalizados.endereco !== undefined) {
      dadosNormalizados.enderecoFiscal = dadosNormalizados.endereco;
    }

    if (dados.regimeIVA !== undefined && dados.regimeIva === undefined && dados.regimeFiscal === undefined) {
      dadosNormalizados.regimeIva = dados.regimeIVA;
    }
    if (dadosNormalizados.regimeIva !== undefined) {
      dadosNormalizados.regimeIVA = dadosNormalizados.regimeIva;
    }

    if (dados.moedaBase !== undefined && dados.moedaPadrao === undefined) {
      dadosNormalizados.moedaPadrao = dados.moedaBase;
    }
    if (dadosNormalizados.moedaPadrao !== undefined) {
      dadosNormalizados.moedaBase = dadosNormalizados.moedaPadrao;
    }

    if (dados.contasBancarias !== undefined && dados.bancos === undefined) {
      dadosNormalizados.bancos = dados.contasBancarias;
    }
    if (dadosNormalizados.bancos !== undefined) {
      dadosNormalizados.contasBancarias = dadosNormalizados.bancos;
    }

    if (dados.logo !== undefined && dados.logotipo === undefined) {
      dadosNormalizados.logotipo = dados.logo;
    }
    if (dadosNormalizados.logotipo !== undefined) {
      dadosNormalizados.logo = dadosNormalizados.logotipo;
    }

    if (dadosNormalizados.taxaIvaPadrao !== undefined) {
      const taxaIvaRecebida = Number(dadosNormalizados.taxaIvaPadrao);
      dadosNormalizados.taxaIvaPadrao = Number.isFinite(taxaIvaRecebida)
        ? taxaIvaRecebida
        : empresaExistente.taxaIvaPadrao;
    }

    const camposQueExigemCongelamento: Array<keyof Empresa> = [
      'nomeEmpresa',
      'nomeComercial',
      'nuit',
      'email',
      'telefone',
      'telemovel',
      'fax',
      'website',
      'endereco',
      'cidade',
      'provincia',
      'codigoPostal',
      'pais',
      'regimeFiscal',
      'regimeIva',
      'tratamentoFiscalPadrao',
      'taxaIvaPadrao',
      'actividadePrincipal',
      'moedaPadrao',
      'logotipo',
      'corCabecalho',
      'bancos',
      'formatoDocumentos',
    ];

    const houveMudancaEstrutural = camposQueExigemCongelamento.some((campo) => {
      if (!(campo in dadosNormalizados)) return false;
      return JSON.stringify(empresaExistente[campo]) !== JSON.stringify(dadosNormalizados[campo]);
    });
    
    // Se NUIT mudou, verificar se o novo já existe
    if (dadosNormalizados.nuit && normalizeNuit(dadosNormalizados.nuit) !== empresaExistente.nuit) {
      const nuitNormalizado = normalizeNuit(dadosNormalizados.nuit);
      if (!isValidNuit(nuitNormalizado)) {
        return { success: false, error: "NUIT inválido (deve ter 9 dígitos)" };
      }
      
      const nuitIndex = await kv.get(`${EMPRESA_NUIT_INDEX}${nuitNormalizado}`);
      if (nuitIndex) {
        return { success: false, error: "NUIT já cadastrado no sistema" };
      }
      
      // Remover índice antigo
      await kv.del(`${EMPRESA_NUIT_INDEX}${empresaExistente.nuit}`);
      // Criar novo índice
      await kv.set(`${EMPRESA_NUIT_INDEX}${nuitNormalizado}`, id);
      dadosNormalizados.nuit = nuitNormalizado;
    }
    
    // Se email mudou, verificar se o novo já existe
    if (dadosNormalizados.email && dadosNormalizados.email.toLowerCase() !== empresaExistente.email) {
      if (!validarEmail(dadosNormalizados.email)) {
        return { success: false, error: "Email inválido" };
      }
      
      const emailIndex = await kv.get(`${EMPRESA_EMAIL_INDEX}${dadosNormalizados.email.toLowerCase()}`);
      if (emailIndex) {
        return { success: false, error: "Email já cadastrado no sistema" };
      }
      
      // Remover índice antigo
      await kv.del(`${EMPRESA_EMAIL_INDEX}${empresaExistente.email}`);
      // Criar novo índice
      await kv.set(`${EMPRESA_EMAIL_INDEX}${dadosNormalizados.email.toLowerCase()}`, id);
    }
    
    if (houveMudancaEstrutural) {
      const documentosCongelados = await congelarDocumentosSemSnapshot(empresaExistente);
      console.log(`[EMPRESAS] Documentos congelados antes da alteracao: ${documentosCongelados}`);
    }

    // Atualizar empresa (campos protegidos são preservados automaticamente)
    const empresaAtualizada: Empresa = {
      ...empresaExistente,
      ...dadosNormalizados,
      id, // Garantir que ID não muda
      dataUltimaAtualizacao: new Date().toISOString(),
    };
    
    console.log(`[EMPRESAS] Empresa atualizada (antes de salvar):`);
    console.log(`[EMPRESAS] - Logotipo na empresa atualizada:`, empresaAtualizada.logotipo?.substring(0, 100));
    console.log(`[EMPRESAS] - Bancos na empresa atualizada:`, JSON.stringify(empresaAtualizada.bancos, null, 2));
    console.log(`[EMPRESAS] - Plano preservado:`, empresaAtualizada.plano);
    
    await kv.set(`${EMPRESA_PREFIX}${id}`, empresaAtualizada);
    
    // Verificar o que foi salvo
    const empresaSalva = await kv.get(`${EMPRESA_PREFIX}${id}`);
    console.log(`[EMPRESAS] Empresa salva (confirmação):`);
    console.log(`[EMPRESAS] - Logotipo salvo:`, (empresaSalva as any)?.logotipo?.substring(0, 100));
    console.log(`[EMPRESAS] - Bancos salvos:`, JSON.stringify((empresaSalva as any)?.bancos, null, 2));
    console.log(`[EMPRESAS] - Plano salvo:`, (empresaSalva as any)?.plano);
    
    console.log(`[EMPRESAS] ✅ Empresa atualizada: ${id} - ${empresaAtualizada.nomeComercial}`);
    
    return { success: true, data: empresaAtualizada };
  } catch (error) {
    // console.error("[EMPRESAS] Erro ao atualizar empresa:", error);
    return { success: false, error: `Erro ao atualizar empresa: ${error.message}` };
  }
}

/**
 * ✅ FUNÇÃO INTERNA: Atualizar empresa sem validação de campos protegidos
 * Uso exclusivo para endpoints específicos de subscrição
 * NUNCA expor diretamente via API
 */
export async function atualizarEmpresaSemValidacao(
  id: string, 
  dados: Partial<Empresa>
): Promise<{ success: boolean; data?: Empresa; error?: string }> {
  try {
    console.log(`[EMPRESAS] ⚙️ Atualização interna (sem validação) - ID: ${id}`);
    
    const empresaExistente = await buscarEmpresaPorId(id);
    
    if (!empresaExistente) {
      return { success: false, error: "Empresa não encontrada" };
    }
    
    // Atualizar diretamente (função interna privilegiada)
    const empresaAtualizada: Empresa = {
      ...empresaExistente,
      ...dados,
      id,
      dataUltimaAtualizacao: new Date().toISOString(),
    };
    
    await kv.set(`${EMPRESA_PREFIX}${id}`, empresaAtualizada);
    
    console.log(`[EMPRESAS] ✅ Atualização interna concluída: ${id}`);
    
    return { success: true, data: empresaAtualizada };
  } catch (error) {
    return { success: false, error: `Erro na atualização interna: ${error.message}` };
  }
}

/**
 * Deletar empresa
 */
export async function deletarEmpresa(id: string): Promise<{ success: boolean; error?: string }> {
  try {
    const empresa = await buscarEmpresaPorId(id);
    
    if (!empresa) {
      return { success: false, error: "Empresa não encontrada" };
    }

    // ✅ Sem isto, eliminar a empresa deixava os utilizadores dela orfaos:
    // continuavam a autenticar-se normalmente (o login so avisa com um
    // warning se a empresa nao existir), mas qualquer operacao que dependa
    // de dados da empresa (regime fiscal, series documentais, etc.) falhava
    // de forma inesperada. Obriga a remover/realocar os utilizadores primeiro.
    const usuariosDaEmpresa = await listarUsuariosEmpresa(id);
    if (usuariosDaEmpresa.length > 0) {
      return {
        success: false,
        error: `Nao e possivel eliminar: esta empresa tem ${usuariosDaEmpresa.length} utilizador(es) associado(s). Remova ou realoque os utilizadores primeiro.`,
      };
    }

    // Remover empresa
    await kv.del(`${EMPRESA_PREFIX}${id}`);
    
    // Remover índices
    await kv.del(`${EMPRESA_NUIT_INDEX}${empresa.nuit}`);
    await kv.del(`${EMPRESA_EMAIL_INDEX}${empresa.email}`);
    
    // console.log(`[EMPRESAS] Empresa deletada: ${id} - ${empresa.nomeComercial}`);
    
    return { success: true };
  } catch (error) {
    // console.error("[EMPRESAS] Erro ao deletar empresa:", error);
    return { success: false, error: `Erro ao deletar empresa: ${error.message}` };
  }
}

/**
 * Alterar status da empresa
 */
export async function alterarStatusEmpresa(id: string, status: "ativa" | "suspensa" | "inativa"): Promise<{ success: boolean; error?: string }> {
  try {
    const empresa = await buscarEmpresaPorId(id);
    
    if (!empresa) {
      return { success: false, error: "Empresa não encontrada" };
    }
    
    empresa.status = status;
    empresa.dataUltimaAtualizacao = new Date().toISOString();
    
    await kv.set(`${EMPRESA_PREFIX}${id}`, empresa);
    
    // console.log(`[EMPRESAS] Status alterado: ${id} - ${status}`);
    
    return { success: true };
  } catch (error) {
    // console.error("[EMPRESAS] Erro ao alterar status:", error);
    return { success: false, error: `Erro ao alterar status: ${error.message}` };
  }
}

/**
 * Registrar acesso da empresa
 */
export async function registrarAcesso(id: string): Promise<void> {
  try {
    const empresa = await buscarEmpresaPorId(id);
    
    if (empresa) {
      empresa.ultimoAcesso = new Date().toISOString();
      await kv.set(`${EMPRESA_PREFIX}${id}`, empresa);
    }
  } catch (error) {
    // console.error("[EMPRESAS] Erro ao registrar acesso:", error);
  }
}
