import { createClient } from '../../src/compat/supabase.js';
import { createLogger } from "./logger.tsx";
import * as kv from "./kv_store.tsx";

const logger = createLogger('Permissoes');

const supabaseUrl = Deno.env.get('SUPABASE_URL')!;
const supabaseServiceKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;

// ========== TIPOS E INTERFACES ==========

export type NivelUsuario = 'super_admin' | 'admin' | 'usuario';

export interface Permissoes {
  concederPermissoes: boolean;
  visualizarLogs: boolean;
  gerenciarUsuarios: boolean;
  exportarSAFT: boolean;
  configurarEmpresa: boolean;
}

export interface Usuario {
  id: string;
  empresaId: string;
  authUserId: string; // ID do Supabase Auth
  nome: string;
  email: string;
  nivel: NivelUsuario;
  codigoSupervisor?: string;
  permissoes: Permissoes;
  ativo: boolean;
  dataCriacao: string;
  ultimoAcesso?: string;
  criadoPor?: string;
}

function normalizarCodigoSupervisor(codigo?: string): string | undefined {
  const valor = codigo?.trim().toUpperCase();
  return valor ? valor : undefined;
}

// ========== PERMISSÕES PADRÃO POR NÍVEL ==========

export const PERMISSOES_SUPER_ADMIN: Permissoes = {
  concederPermissoes: true,
  visualizarLogs: true,
  gerenciarUsuarios: true,
  exportarSAFT: true,
  configurarEmpresa: true,
};

export const PERMISSOES_ADMIN: Permissoes = {
  concederPermissoes: true, // Apenas para usuários comuns
  visualizarLogs: true,
  gerenciarUsuarios: true,
  exportarSAFT: true,
  configurarEmpresa: true,
};

export const PERMISSOES_USUARIO: Permissoes = {
  concederPermissoes: false,
  visualizarLogs: false,
  gerenciarUsuarios: false,
  exportarSAFT: false,
  configurarEmpresa: false,
};

// ========== FUNÇÕES DE VERIFICAÇÃO ==========

/**
 * Verificar se um documento está bloqueado (emitido ou vinculado)
 */
export async function verificarDocumentoBloqueado(documentoId: string, tipo: string): Promise<boolean> {
  const supabase = createClient(supabaseUrl, supabaseServiceKey);

  try {
    // Buscar o documento
    const { data, error } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .eq('key', documentoId)
      .maybeSingle();

    if (error) {
      logger.error('❌ Erro ao verificar documento:', error);
      return true; // Por segurança, bloquear se houver erro
    }
    
    if (!data) {
      logger.warn('⚠️ Documento não encontrado:', documentoId);
      return false; // Se não existe, não está bloqueado
    }

    const documento = data.value;

    // Verificar estado do documento
    if (tipo === 'cotacao') {
      // Cotação está bloqueada se foi aprovada
      return documento.estado === 'aprovada';
    }

    // Outros documentos: bloqueados se estado for 'emitido' ou se tiverem vínculos
    if (documento.estado === 'emitido' || documento.estado === 'paga' || documento.estado === 'anulado') {
      return true;
    }

    // Verificar se há documentos vinculados (ex: recibo vinculado a factura)
    if (tipo === 'factura') {
      // Buscar recibos vinculados a esta factura
      const { data: recibos } = await supabase
        .from('kv_store_7249dcd9')
        .select('*')
        .like('key', `recibo:${documento.empresaId}:%`);

      const temRecibosVinculados = recibos?.some((r: any) =>
        r.value.facturasVinculadas?.includes(documentoId)
      );

      if (temRecibosVinculados) {
        return true;
      }
    }

    return false;
  } catch (error) {
    logger.error('❌ Erro ao verificar bloqueio:', error);
    return true; // Por segurança, bloquear se houver erro
  }
}

/**
 * Verificar se usuário tem permissão para uma operação
 */
export function verificarPermissao(
  usuario: Usuario,
  permissao: keyof Permissoes
): boolean {
  // Requisito Financas/AT: super_admin ja nao tem acesso incondicional -
  // tem a permissao concedida por omissao quando nao ha nada gravado, mas
  // uma permissao explicitamente negada (false) e sempre respeitada.
  if (usuario.nivel === 'super_admin') {
    return usuario.permissoes[permissao] !== false;
  }

  return usuario.permissoes[permissao] === true;
}

/**
 * Verificar se usuário pode editar um documento específico
 * NOTA: Esta função verifica apenas regras de bloqueio de documentos.
 * O controle de permissões granulares é feito via permissoesModulos.
 */
export async function verificarPodeEditar(
  usuario: Usuario,
  documentoId: string,
  tipoDocumento: string
): Promise<{ permitido: boolean; motivo?: string }> {
  // Requisito Financas/AT: a regra de bloqueio de documento (emitido/
  // vinculado) aplica-se sempre, mesmo a super_admin - nunca um bypass.
  // Verificar se documento está bloqueado (regra de negócio universal)
  const bloqueado = await verificarDocumentoBloqueado(documentoId, tipoDocumento);

  if (bloqueado) {
    return {
      permitido: false,
      motivo: 'Documento emitido ou vinculado não pode ser editado',
    };
  }

  // ✅ NOVO: Documento pendente pode ser editado (permissões granulares verificadas no frontend)
  return { permitido: true };
}

/**
 * Verificar se usuário pode deletar um documento especfico
 * NOTA: Esta função verifica apenas regras de bloqueio de documentos.
 * O controle de permissões granulares é feito via permissoesModulos.
 */
export async function verificarPodeDeletar(
  usuario: Usuario,
  documentoId: string,
  tipoDocumento: string
): Promise<{ permitido: boolean; motivo?: string }> {
  // Requisito Financas/AT: a regra de bloqueio de documento (emitido/
  // vinculado) aplica-se sempre, mesmo a super_admin - nunca um bypass.
  // Verificar se documento está bloqueado (regra de negócio universal)
  const bloqueado = await verificarDocumentoBloqueado(documentoId, tipoDocumento);

  if (bloqueado) {
    return {
      permitido: false,
      motivo: 'Documento emitido ou vinculado não pode ser deletado',
    };
  }

  // ✅ NOVO: Documento pendente pode ser deletado (permissões granulares verificadas no frontend)
  return { permitido: true };
}

// ========== CRUD DE USUÁRIOS ==========

/**
 * Criar novo usuário
 */
export async function criarUsuario(
  dadosUsuario: Omit<Usuario, 'id' | 'dataCriacao'>,
  criadoPor: string
): Promise<{ success: boolean; data?: Usuario; error?: string }> {
  const supabase = createClient(supabaseUrl, supabaseServiceKey);

  try {
    const usuarioId = `usuario:${dadosUsuario.empresaId}:${crypto.randomUUID()}`;

    const novoUsuario: Usuario = {
      ...dadosUsuario,
      id: usuarioId,
      dataCriacao: new Date().toISOString(),
      criadoPor,
    };

    const { data, error } = await supabase
      .from('kv_store_7249dcd9')
      .insert({
        key: usuarioId,
        value: novoUsuario,
      })
      .select()
      .single();

    if (error) {
      logger.error('❌ Erro ao criar usuário:', error);
      return { success: false, error: error.message };
    }

    logger.info(`✅ Usuário ${dadosUsuario.nome} criado com sucesso`);
    return { success: true, data: data.value };
  } catch (error) {
    logger.error('❌ Erro ao criar usuário:', error);
    return { success: false, error: String(error) };
  }
}

/**
 * Buscar usuários de uma empresa
 */
export async function buscarUsuariosPorEmpresa(
  empresaId: string
): Promise<{ success: boolean; data?: Usuario[]; error?: string }> {
  const supabase = createClient(supabaseUrl, supabaseServiceKey);

  try {
    const { data, error } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .like('key', `usuario:${empresaId}:%`);

    if (error) {
      logger.error('❌ Erro ao buscar usuários:', error);
      return { success: false, error: error.message };
    }

    // ✅ CORREÇÃO CRÍTICA: Usar a chave do banco como ID
    const usuarios = data?.map((item: any) => {
      const usuario = item.value;
      return {
        ...usuario,
        id: item.key, // ← USAR A CHAVE DO BANCO COMO ID
      };
    }) || [];
    
    logger.info(`✅ ${usuarios.length} usuários encontrados para empresa ${empresaId}`);
    return { success: true, data: usuarios };
  } catch (error) {
    logger.error('❌ Erro ao buscar usuários:', error);
    return { success: false, error: String(error) };
  }
}

/**
 * Buscar TODOS os usuários do sistema de permissões (apenas Super Admin)
 */
export async function buscarTodosUsuariosPermissoes(): Promise<{ success: boolean; data?: Usuario[]; error?: string }> {
  const supabase = createClient(supabaseUrl, supabaseServiceKey);

  try {
    logger.info('🔍 [buscarTodosUsuariosPermissoes] Buscando todos os usuários...');
    
    // Buscar TODOS os usuários do sistema de permissões
    // Formato: usuario:empresaId:uuid ou usuario_permissoes:empresaId:uuid
    const { data, error } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .or('key.like.usuario:%,key.like.usuario_permissoes:%');

    if (error) {
      logger.error('❌ Erro ao buscar todos os usuários:', error);
      return { success: false, error: error.message };
    }

    // Filtrar apenas chaves válidas de usuários (não email lookups)
    const usuarios = data
      ?.filter((item: any) => {
        const key = item.key as string;
        const isEmailLookup = key.includes(':email:');
        const isValidUser = item.value && item.value.id && item.value.email && item.value.permissoes;
        
        if (isEmailLookup) {
          return false;
        }
        
        if (!isValidUser) {
          logger.warn(`⚠️ Usuário inválido em ${key}:`, item.value);
          return false;
        }
        
        return true;
      })
      .map((item: any) => {
        // ✅ CORREÇÃO CRÍTICA: Usar a CHAVE do banco como ID, não o value.id
        // Isso garante que o frontend sempre envie o ID correto ao backend
        const usuario = item.value as Usuario;
        return {
          ...usuario,
          id: item.key, // ← USAR A CHAVE DO BANCO COMO ID
        };
      })
      .sort((a, b) => new Date(b.dataCriacao).getTime() - new Date(a.dataCriacao).getTime()) || [];

    logger.info(`✅ ${usuarios.length} usuários do sistema de permissões encontrados`);
    usuarios.forEach(u => logger.info(`   - ${u.nome} (${u.email}) - ID: ${u.id} - Empresa: ${u.empresaId} - Nível: ${u.nivel}`));
    
    return { success: true, data: usuarios };
  } catch (error) {
    logger.error('❌ Erro ao buscar todos os usuários:', error);
    return { success: false, error: String(error) };
  }
}

/**
 * Buscar usuário por Auth ID
 */
export async function buscarUsuarioPorAuthId(
  authUserId: string
): Promise<{ success: boolean; data?: Usuario; error?: string }> {
  const supabase = createClient(supabaseUrl, supabaseServiceKey);

  try {
    logger.info(`[buscarUsuarioPorAuthId] 🔍 Buscando usuário com authUserId: ${authUserId}`);
    
    const { data, error } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .like('key', 'usuario:%');

    if (error) {
      logger.error('❌ Erro ao buscar usuário por Auth ID:', error);
      return { success: false, error: error.message };
    }

    logger.info(`[buscarUsuarioPorAuthId] 📊 Total de usuários no banco: ${data?.length || 0}`);
    
    // ✅ CORREÇÃO: Buscar por authUserId OU por id (UUID)
    // Alguns usuários podem ter authUserId, outros podem ter apenas id
    const usuarioItem = data?.find((item: any) => {
      const value = item.value;
      const temAuthUserId = value?.authUserId === authUserId;
      const idBateComAuthUserId = value?.id === authUserId;
      
      // Log para debug
      if (value?.email) {
        logger.info(`[buscarUsuarioPorAuthId]   Verificando ${value.email}: authUserId=${value.authUserId}, id=${value.id}`);
      }
      
      return temAuthUserId || idBateComAuthUserId;
    });

    if (!usuarioItem) {
      logger.error(`[buscarUsuarioPorAuthId] ❌ Usuário não encontrado com authUserId: ${authUserId}`);
      logger.info(`[buscarUsuarioPorAuthId] ℹ Dica: Verifique se o usuário foi criado antes da implementação do authUserId`);
      logger.info(`[buscarUsuarioPorAuthId] ℹ️ Execute a rota de migração: POST /usuarios-permissoes/migrar-auth-ids`);
      return { success: false, error: 'Usuário não encontrado' };
    }

    // ✅ CRÍTICO: Garantir que permissoes existe
    let permissoes = usuarioItem.value.permissoes;
    let permissoesForamCriadas = false;
    
    if (!permissoes) {
      logger.warn(`⚠️ [buscarUsuarioPorAuthId] Usuário ${usuarioItem.value.email} sem permissoes! Criando padrão...`);
      
      // Criar permissões padrão baseado no nível
      const nivel = usuarioItem.value.nivel;
      if (nivel === 'super_admin') {
        permissoes = PERMISSOES_SUPER_ADMIN;
      } else if (nivel === 'admin') {
        permissoes = PERMISSOES_ADMIN;
      } else {
        permissoes = PERMISSOES_USUARIO;
      }
      
      permissoesForamCriadas = true;
      logger.info(`✅ [buscarUsuarioPorAuthId] Permissões padrão criadas para nível: ${nivel}`);
      
      // ✅ CRÍTICO: SALVAR as permissões padrão no KV
      try {
        await kv.set(usuarioItem.key, {
          ...usuarioItem.value,
          permissoes,
        });
        logger.info(`✅ [buscarUsuarioPorAuthId] Permissões padrão salvas no KV para ${usuarioItem.value.email}`);
      } catch (saveError) {
        logger.error(`❌ [buscarUsuarioPorAuthId] Erro ao salvar permissões padrão:`, saveError);
      }
    }

    // ✅ CRÍTICO: Retornar a chave KV completa como ID
    const usuario = {
      ...usuarioItem.value,
      id: usuarioItem.key, // ✅ Substituir UUID simples pela key completa
      authUserId: usuarioItem.value.authUserId || usuarioItem.value.id, // ✅ Garantir que authUserId existe
      permissoes, // ✅ Garantir que permissoes existe
    };

    logger.info('[buscarUsuarioPorAuthId] ✅ Usuário encontrado:', {
      authUserId,
      key: usuarioItem.key,
      email: usuario.email,
      empresaId: usuario.empresaId,
      nivel: usuario.nivel,
      temPermissoes: !!usuario.permissoes,
      permissoesForamCriadas,
      temPermissoesModulos: !!usuario.permissoesModulos
    });

    return { success: true, data: usuario };
  } catch (error) {
    logger.error('❌ Erro ao buscar usuário:', error);
    return { success: false, error: String(error) };
  }
}

/**
 * Atualizar permissões de um usuário
 */
export async function atualizarPermissoes(
  usuarioId: string,
  novasPermissoes: Partial<Permissoes>,
  atualizadoPor: string
): Promise<{ success: boolean; error?: string }> {
  const supabase = createClient(supabaseUrl, supabaseServiceKey);

  try {
    logger.info(`🔄 [atualizarPermissoes] Iniciando atualização...`);
    logger.info(`   UsuarioId: ${usuarioId}`);
    logger.info(`   UsuarioId tipo: ${typeof usuarioId}`);
    logger.info(`   UsuarioId é chave completa?: ${usuarioId.includes(':')}`);
    logger.info(`   Novas Permissões:`, novasPermissoes);
    logger.info(`   Atualizado Por: ${atualizadoPor}`);

    // ✅ CORREÇÃO CRÍTICA: Buscar DIRETAMENTE pela chave (que é o próprio usuarioId)
    // O usuarioId É a chave: usuario:empresaId:uuid
    const { data: usuarioItem, error: erroGet } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .eq('key', usuarioId)
      .maybeSingle();

    if (erroGet) {
      logger.error(`❌ [atualizarPermissoes] Erro ao buscar usuário:`, erroGet);
      return { success: false, error: erroGet.message };
    }

    if (!usuarioItem) {
      logger.error(`❌ [atualizarPermissoes] Usuário não encontrado com chave: ${usuarioId}`);
      
      // ✅ FALLBACK MELHORADO: Tentar busca alternativa
      logger.info(`🔄 [atualizarPermissoes] Tentando busca alternativa...`);
      const { data: todosUsuarios, error: erroAlt } = await supabase
        .from('kv_store_7249dcd9')
        .select('*')
        .or('key.like.usuario:%,key.like.usuario_permissoes:%');
      
      if (erroAlt) {
        logger.error(`❌ [atualizarPermissoes] Erro na busca alternativa:`, erroAlt);
        return { success: false, error: 'Usuário não encontrado' };
      }
      
      logger.info(`📊 [atualizarPermissoes] Total de usuários no sistema: ${todosUsuarios?.length || 0}`);
      
      // Log de todos os usuários para debug
      todosUsuarios?.forEach((item: any) => {
        logger.info(`   🔍 Usuário: ${item.key}`);
        logger.info(`      - value.id: ${item.value?.id}`);
        logger.info(`      - value.authUserId: ${item.value?.authUserId}`);
        logger.info(`      - value.email: ${item.value?.email}`);
      });
      
      // Procurar o usuário de 3 formas diferentes:
      // 1. Por chave exata
      // 2. Por value.id (UUID simples)
      // 3. Por chave terminando com UUID
      // 4. Por authUserId
      const usuarioEncontrado = todosUsuarios?.find((item: any) => {
        const key = item.key as string;
        
        // 1. Match exato pela chave
        if (key === usuarioId) {
          logger.info(`   ✅ Match por chave exata: ${item.key}`);
          return true;
        }
        
        // 2. Match por value.id (UUID simples)
        if (item.value?.id === usuarioId) {
          logger.info(`   ✅ Match por value.id: ${item.key}`);
          return true;
        }
        
        // 3. Match por chave terminando com UUID (quando frontend envia apenas UUID)
        if (key.endsWith(`:${usuarioId}`)) {
          logger.info(`   ✅ Match por chave terminando com UUID: ${item.key}`);
          return true;
        }
        
        // 4. Match por authUserId
        if (item.value?.authUserId === usuarioId) {
          logger.info(`   ✅ Match por authUserId: ${item.key}`);
          return true;
        }
        
        return false;
      });
      
      if (!usuarioEncontrado) {
        logger.error(`❌ [atualizarPermissoes] Usuário não encontrado em nenhuma busca`);
        logger.error(`   ID buscado: ${usuarioId}`);
        logger.error(`   Total de usuários verificados: ${todosUsuarios?.length || 0}`);
        logger.error(`   Usuários disponíveis:`, todosUsuarios?.map((u: any) => u.key).join(', '));
        return { success: false, error: 'Usuário não encontrado' };
      }
      
      logger.info(`✅ [atualizarPermissoes] Usuário encontrado na busca alternativa!`);
      logger.info(`   Chave real: ${usuarioEncontrado.key}`);
      logger.info(`   Nome: ${usuarioEncontrado.value.nome}`);
      
      // Atualizar usando a chave encontrada
      const usuarioAtualizado = {
        ...usuarioEncontrado.value,
        permissoes: {
          ...usuarioEncontrado.value.permissoes,
          ...novasPermissoes,
        },
      };

      const { error: erroUpdate } = await supabase
        .from('kv_store_7249dcd9')
        .update({ value: usuarioAtualizado })
        .eq('key', usuarioEncontrado.key);

      if (erroUpdate) {
        logger.error(`❌ [atualizarPermissoes] Erro ao atualizar:`, erroUpdate);
        return { success: false, error: erroUpdate.message };
      }

      logger.info(`✅ [atualizarPermissoes] Permissões atualizadas com sucesso via fallback!`);
      return { success: true };
    }

    logger.info(`✅ [atualizarPermissoes] Usuário encontrado: ${usuarioItem.key}`);
    logger.info(`   Nome: ${usuarioItem.value.nome}`);
    logger.info(`   Email: ${usuarioItem.value.email}`);
    logger.info(`   Permissões Atuais:`, usuarioItem.value.permissoes);

    // Atualizar permissões
    const usuarioAtualizado = {
      ...usuarioItem.value,
      permissoes: {
        ...usuarioItem.value.permissoes,
        ...novasPermissoes,
      },
    };

    logger.info(`📝 [atualizarPermissoes] Permissões Após Merge:`, usuarioAtualizado.permissoes);

    const { error: erroUpdate } = await supabase
      .from('kv_store_7249dcd9')
      .update({ value: usuarioAtualizado })
      .eq('key', usuarioId);

    if (erroUpdate) {
      logger.error(`❌ [atualizarPermissoes] Erro ao atualizar:`, erroUpdate);
      return { success: false, error: erroUpdate.message };
    }

    logger.info(`✅ [atualizarPermissoes] Permissões do usuário ${usuarioId} atualizadas por ${atualizadoPor}`);
    return { success: true };
  } catch (error) {
    logger.error(`❌ [atualizarPermissoes] Erro geral:`, error);
    return { success: false, error: String(error) };
  }
}

/**
 * Desativar usuário
 */
export async function desativarUsuario(
  usuarioId: string,
  desativadoPor: string
): Promise<{ success: boolean; error?: string }> {
  const supabase = createClient(supabaseUrl, supabaseServiceKey);

  try {
    logger.info(`🔄 Desativando usuário ${usuarioId}...`);

    // ✅ CORREÇÃO: Buscar o usuário pelo ID em todas as chaves possíveis
    const { data: todosUsuarios, error: erroGet } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .like('key', `%${usuarioId}%`);

    if (erroGet) {
      logger.error('❌ Erro ao buscar usuário:', erroGet);
      return { success: false, error: erroGet.message };
    }

    // Filtrar para encontrar o usuário correto
    const usuarioItem = todosUsuarios?.find((item: any) => {
      const key = item.key as string;
      return (
        key === `usuario_permissoes:${usuarioId}` ||
        key.includes(`usuario:`) && key.endsWith(`:${usuarioId}`) ||
        item.value?.id === usuarioId
      );
    });

    if (!usuarioItem) {
      logger.error(`❌ Usuário não encontrado com ID: ${usuarioId}`);
      return { success: false, error: 'Usuário não encontrado' };
    }

    const chaveUsuario = usuarioItem.key as string;
    const atual = usuarioItem;
    logger.info(`✅ Usuário encontrado com chave: ${chaveUsuario}`);

    const usuarioAtualizado = {
      ...atual.value,
      ativo: false,
    };

    const { error: erroUpdate } = await supabase
      .from('kv_store_7249dcd9')
      .update({ value: usuarioAtualizado })
      .eq('key', chaveUsuario);

    if (erroUpdate) {
      logger.error('❌ Erro ao desativar usuário:', erroUpdate);
      return { success: false, error: erroUpdate.message };
    }

    // ✅ Impede que a sessao Supabase Auth ja emitida continue valida apos a
    // desactivacao (sem isto, ativo:false so era verificado nas rotas que
    // passam por requirePermission/checkPermission).
    await supabase.auth.admin.updateUserById(usuarioId, { ban_duration: "876000h" }).catch((error: any) => {
      logger.error('❌ Erro ao banir utilizador no Supabase Auth:', error);
    });

    logger.info(`✅ Usuário ${usuarioId} desativado por ${desativadoPor}`);
    return { success: true };
  } catch (error) {
    logger.error('❌ Erro ao desativar usuário:', error);
    return { success: false, error: String(error) };
  }
}

/**
 * Sincronizar usuários do sistema (empresas) com o sistema de permissões
 * Busca usuários cadastrados nas empresas e cria registros de permissões para eles
 */
export async function sincronizarUsuariosEmpresa(
  empresaId: string
): Promise<{ success: boolean; data?: Usuario[]; error?: string; criados?: number; existentes?: number }> {
  const supabase = createClient(supabaseUrl, supabaseServiceKey);

  try {
    logger.info(`🔄 Sincronizando usuários da empresa ${empresaId}...`);
    logger.info(`📍 EmpresaId tipo: ${typeof empresaId}, valor:`, empresaId);

    // 1. Buscar a empresa - tentar como chave direta primeiro, depois como ID
    let empresaData = null;
    let empresaKey = empresaId;
    
    // Tentativa 1: Tentar buscar diretamente pela chave
    logger.info(`🔍 Tentativa 1: Buscando empresa com chave direta: ${empresaId}`);
    const { data: empresaDirecta, error: erroDirecta } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .eq('key', empresaId)
      .maybeSingle();

    if (empresaDirecta) {
      logger.info(`✅ Empresa encontrada na tentativa 1`);
      empresaData = empresaDirecta;
      empresaKey = empresaId;
    } else {
      logger.warn(`⚠️ Tentativa 1 falhou:`, erroDirecta?.message || 'Não encontrada');
      
      // Tentativa 2: Se não encontrou, tentar buscar com prefixo 'empresa:'
      const empresaIdComPrefixo = empresaId.startsWith('empresa:') ? empresaId : `empresa:${empresaId}`;
      logger.info(`🔍 Tentativa 2: Buscando com prefixo: ${empresaIdComPrefixo}`);
      
      const { data: empresaComPrefixo, error: erroPrefixo } = await supabase
        .from('kv_store_7249dcd9')
        .select('*')
        .eq('key', empresaIdComPrefixo)
        .maybeSingle();
      
      if (empresaComPrefixo) {
        logger.info(`✅ Empresa encontrada na tentativa 2`);
        empresaData = empresaComPrefixo;
        empresaKey = empresaIdComPrefixo;
      } else {
        logger.warn(`⚠️ Tentativa 2 falhou:`, erroPrefixo?.message || 'Não encontrada');
        
        // Tentativa 3: Última tentativa: buscar todas as empresas e procurar pelo ID no value
        logger.info(`🔍 Tentativa 3: Buscando em todas as empresas...`);
        const { data: todasEmpresas, error: erroTodas } = await supabase
          .from('kv_store_7249dcd9')
          .select('*')
          .like('key', 'empresa:%');
        
        logger.info(`📊 Total de empresas encontradas: ${todasEmpresas?.length || 0}`);
        
        if (todasEmpresas && todasEmpresas.length > 0) {
          logger.info(`🔎 Procurando empresa com value.id = ${empresaId}...`);
          const empresaEncontrada = todasEmpresas.find((e: any) => {
            const match = e.value.id === empresaId;
            logger.info(`  - Empresa ${e.key}: value.id = ${e.value.id}, match = ${match}`);
            return match;
          });
          
          if (empresaEncontrada) {
            logger.info(`✅ Empresa encontrada na tentativa 3: ${empresaEncontrada.key}`);
            empresaData = empresaEncontrada;
            empresaKey = empresaEncontrada.key;
          } else {
            logger.warn(`⚠️ Tentativa 3 falhou: Nenhuma empresa com value.id = ${empresaId}`);
          }
        } else {
          logger.warn(`⚠️ Tentativa 3 falhou:`, erroTodas?.message || 'Nenhuma empresa cadastrada');
        }
      }
    }

    if (!empresaData) {
      logger.error('❌ Empresa não encontrada após 3 tentativas:', { 
        empresaId, 
        tipo: typeof empresaId,
        tentativas: ['chave direta', 'com prefixo empresa:', 'por value.id'] 
      });
      return { success: false, error: 'Empresa não encontrada' };
    }

    const empresa = empresaData.value;
    logger.info(`✅ Empresa encontrada: ${empresa.nomeEmpresa || empresa.nomeComercial} (${empresaKey})`);

    // Extrair o ID real da empresa (sem prefixo 'empresa:' se houver)
    const empresaIdReal = empresaKey.replace('empresa:', '');

    // 2. Buscar usuários já cadastrados no sistema de permissões
    const { data: usuariosPermissoesData } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .like('key', `usuario:${empresaIdReal}:%`);

    // ✅ CORREÇÃO CRÍTICA: Usar a CHAVE do banco como ID, não o value.id
    const usuariosPermissoes = usuariosPermissoesData?.map((item: any) => ({
      ...item.value,
      id: item.key, // ← USAR A CHAVE DO BANCO COMO ID
    })) || [];
    const authIdsExistentes = new Set(usuariosPermissoes.map((u: Usuario) => u.authUserId));

    // 3. Buscar todos os usuários cadastrados na empresa (na estrutura antiga)
    const { data: usuariosSistema } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .like('key', `usuario-empresa:${empresaIdReal}:%`);

    const usuariosParaCriar: Usuario[] = [];
    let contadorCriados = 0;

    // 4. Para cada usuário do sistema, verificar se já existe no sistema de permissões
    if (usuariosSistema && usuariosSistema.length > 0) {
      for (const userItem of usuariosSistema) {
        const userSistema = userItem.value;
        
        // Se já existe no sistema de permissões, pular
        if (authIdsExistentes.has(userSistema.id || userSistema.authUserId)) {
          continue;
        }

        // Criar novo registro de permissão
        const usuarioId = `usuario:${empresaIdReal}:${crypto.randomUUID()}`;
        const nivel: NivelUsuario = userSistema.isAdmin ? 'admin' : 'usuario';
        const permissoes = nivel === 'admin' ? PERMISSOES_ADMIN : PERMISSOES_USUARIO;

        const novoUsuario: Usuario = {
          id: usuarioId,
          empresaId: empresaIdReal,
          authUserId: userSistema.id || userSistema.authUserId || crypto.randomUUID(),
          nome: userSistema.nome || userSistema.email?.split('@')[0] || 'Usuário',
          email: userSistema.email || `usuario${Date.now()}@example.com`,
          nivel: nivel,
          permissoes: permissoes,
          ativo: userSistema.ativo !== false,
          dataCriacao: userSistema.dataCriacao || new Date().toISOString(),
          criadoPor: 'sistema-sincronizacao',
        };

        // Inserir no banco
        const { error: insertError } = await supabase
          .from('kv_store_7249dcd9')
          .insert({
            key: usuarioId,
            value: novoUsuario,
          });

        if (!insertError) {
          usuariosParaCriar.push(novoUsuario);
          contadorCriados++;
          logger.info(`✅ Usuário ${novoUsuario.email} sincronizado`);
        } else {
          logger.error(`❌ Erro ao sincronizar ${userSistema.email}:`, insertError);
        }
      }
    }

    // 5. Se não houver usurios no sistema antigo, criar um usuário padrão baseado na empresa
    if (usuariosSistema && usuariosSistema.length === 0 && usuariosPermissoes.length === 0) {
      logger.warn('⚠️ Nenhum usuário encontrado. Criando usuário admin padrão...');
      
      const usuarioId = `usuario:${empresaIdReal}:${crypto.randomUUID()}`;
      const usuarioPadrao: Usuario = {
        id: usuarioId,
        empresaId: empresaIdReal,
        authUserId: crypto.randomUUID(),
        nome: empresa.nomeComercial || empresa.nomeEmpresa || 'Administrador',
        email: empresa.email || `admin@${empresaId}.com`,
        nivel: 'admin',
        permissoes: PERMISSOES_ADMIN,
        ativo: true,
        dataCriacao: new Date().toISOString(),
        criadoPor: 'sistema-auto',
      };

      const { error: insertError } = await supabase
        .from('kv_store_7249dcd9')
        .insert({
          key: usuarioId,
          value: usuarioPadrao,
        });

      if (!insertError) {
        usuariosParaCriar.push(usuarioPadrao);
        contadorCriados++;
        logger.info(`✅ Usuário admin padrão criado: ${usuarioPadrao.email}`);
      }
    }

    // 6. Retornar todos os usuários (existentes + novos)
    const todosUsuarios = [...usuariosPermissoes, ...usuariosParaCriar];

    logger.info(`✅ Sincronização concluída: ${contadorCriados} novos, ${usuariosPermissoes.length} existentes`);
    
    return {
      success: true,
      data: todosUsuarios,
      criados: contadorCriados,
      existentes: usuariosPermissoes.length,
    };
  } catch (error) {
    logger.error('❌ Erro ao sincronizar usuários:', error);
    return { success: false, error: String(error) };
  }
}

// ========== PERMISSÕES POR MÓDULO ==========

/**
 * Atualizar permissões por módulo de um usuário
 */

export async function buscarSupervisorPorCodigo(
  empresaId: string,
  codigoSupervisor: string
): Promise<{ success: boolean; data?: Usuario; error?: string }> {
  const supabase = createClient(supabaseUrl, supabaseServiceKey);

  try {
    const codigoNormalizado = normalizarCodigoSupervisor(codigoSupervisor);
    if (!codigoNormalizado) {
      return { success: false, error: 'Codigo do supervisor e obrigatorio' };
    }

    const { data, error } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .like('key', 'usuario:%');

    if (error) {
      logger.error('Erro ao buscar supervisor por codigo:', error);
      return { success: false, error: error.message };
    }

    const usuarioItem = data?.find((item: any) => {
      const key = String(item.key || '');
      const value = item.value || {};
      if (key.includes(':email:')) return false;
      if (value.ativo === false) return false;

      const nivel = value.nivel;
      const isSupervisor = nivel === 'admin' || nivel === 'admin_empresa' || nivel === 'super_admin';
      if (!isSupervisor) return false;

      const pertenceEmpresa = value.empresaId === empresaId || nivel === 'super_admin';
      if (!pertenceEmpresa) return false;

      return normalizarCodigoSupervisor(value.codigoSupervisor) === codigoNormalizado;
    });

    if (!usuarioItem) {
      return { success: false, error: 'Codigo de supervisor invalido ou nao configurado' };
    }

    return {
      success: true,
      data: {
        ...usuarioItem.value,
        id: usuarioItem.key,
        authUserId: usuarioItem.value.authUserId || usuarioItem.value.id,
      },
    };
  } catch (error) {
    logger.error('Erro ao validar codigo do supervisor:', error);
    return { success: false, error: String(error) };
  }
}

export async function atualizarPermissoesModulos(
  usuarioId: string,
  permissoesModulos: any,
  atualizadoPor: string,
  atualizadoPorNome: string,
  atualizadoPorEmail: string,
  empresaId: string
): Promise<{ success: boolean; error?: string }> {
  const supabase = createClient(supabaseUrl, supabaseServiceKey);

  try {
    logger.info(`🔄 [atualizarPermissoesModulos] Iniciando...`);
    logger.info(`   UsuarioId: ${usuarioId}`);
    logger.info(`   UsuarioId tipo: ${typeof usuarioId}`);
    logger.info(`   EmpresaId: ${empresaId}`);
    logger.info(`   Atualizado por: ${atualizadoPorNome} (${atualizadoPor})`);

    // ✅ CORREÇÃO: Buscar o usuário pelo ID em todas as chaves possíveis
    const { data: todosUsuarios, error: erroGet } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .like('key', `%${usuarioId}%`);

    if (erroGet) {
      logger.error('❌ [atualizarPermissoesModulos] Erro ao buscar usuário:', erroGet);
      return { success: false, error: erroGet.message };
    }

    logger.info(`📊 [atualizarPermissoesModulos] Total de chaves encontradas: ${todosUsuarios?.length || 0}`);
    
    // Log de todas as chaves encontradas
    todosUsuarios?.forEach((item: any) => {
      logger.info(`   🔍 Chave: ${item.key}`);
      logger.info(`      - value.id: ${item.value?.id}`);
      logger.info(`      - value.email: ${item.value?.email}`);
    });

    // Filtrar para encontrar o usuário correto
    const usuarioItem = todosUsuarios?.find((item: any) => {
      const key = item.key as string;
      const match1 = key === `usuario_permissoes:${usuarioId}`;
      const match2 = key.includes(`usuario:`) && key.endsWith(`:${usuarioId}`);
      const match3 = item.value?.id === usuarioId;
      const match4 = key === `usuario:${usuarioId}`;
      const match5 = key === usuarioId; // ✅ NOVO: Teste direto quando usuarioId já é a chave completa
      
      logger.info(`   🎯 Testando ${item.key}:`);
      logger.info(`      - Match exato usuario_permissoes: ${match1}`);
      logger.info(`      - Match usuario com suffix: ${match2}`);
      logger.info(`      - Match por value.id: ${match3}`);
      logger.info(`      - Match exato usuario: ${match4}`);
      logger.info(`      - Match direto (chave completa): ${match5}`);
      
      return match1 || match2 || match3 || match4 || match5;
    });

    if (!usuarioItem) {
      logger.error(`❌ [atualizarPermissoesModulos] Usuário não encontrado com ID: ${usuarioId}`);
      logger.error(`   Chaves disponíveis:`, todosUsuarios?.map(u => u.key).join(', '));
      return { success: false, error: 'Usuário não encontrado' };
    }

    const chaveUsuario = usuarioItem.key as string;
    const usuario = usuarioItem.value;
    logger.info(`✅ [atualizarPermissoesModulos] Usuário encontrado!`);
    logger.info(`   Chave: ${chaveUsuario}`);
    logger.info(`   Nome: ${usuario.nome}`);
    logger.info(`   Email: ${usuario.email}`);

    // 2. Atualizar permissões por módulo
    const usuarioAtualizado = {
      ...usuario,
      permissoesModulos,
      dataAtualizacao: new Date().toISOString(),
    };

    logger.info(`📝 [atualizarPermissoesModulos] Salvando permissões...`);

    // 3. Salvar no banco
    const { error: erroUpdate } = await supabase
      .from('kv_store_7249dcd9')
      .update({
        value: usuarioAtualizado,
      })
      .eq('key', chaveUsuario);

    if (erroUpdate) {
      logger.error('❌ [atualizarPermissoesModulos] Erro ao atualizar permissões por módulo:', erroUpdate);
      return { success: false, error: erroUpdate.message };
    }

    logger.info(`✅ [atualizarPermissoesModulos] Permissões por módulo atualizadas com sucesso para ${usuarioId}`);

    // 4. Registrar log de auditoria
    const logId = `log_auditoria:${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
    const logEntry = {
      id: logId,
      empresaId,
      tipo: 'permissoes_modulos',
      acao: 'atualizacao',
      entidade: 'usuario_permissoes',
      entidadeId: usuarioId,
      descricao: `Permissões por módulo atualizadas para ${usuario.nome} (${usuario.email})`,
      usuarioId: atualizadoPor,
      usuarioNome: atualizadoPorNome,
      usuarioEmail: atualizadoPorEmail,
      metadata: {
        usuarioAfetado: {
          id: usuarioId,
          nome: usuario.nome,
          email: usuario.email,
          nivel: usuario.nivel,
        },
        permissoesModulos,
      },
      dataHora: new Date().toISOString(),
    };

    await supabase.from('kv_store_7249dcd9').insert({
      key: logId,
      value: logEntry,
    });

    return { success: true };
  } catch (error) {
    logger.error('❌ [atualizarPermissoesModulos] Erro ao atualizar permissões por módulo:', error);
    return { success: false, error: String(error) };
  }
}
