package com.social.media;

import com.social.media.repository.UserCredentialsRepository;
import com.social.media.domain.entity.UserCredentials;
import com.social.media.service.UserService;
import com.social.media.dto.UserDto;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Teste para encontrar o usuário específico com o hash da senha
 */
@SpringBootTest
@Transactional
public class FindUserByPasswordHashTest {
    
    @Autowired
    private UserCredentialsRepository userCredentialsRepository;
    
    @Autowired
    private UserService userService;
    
    // Hash específico encontrado no banco
    private static final String TARGET_HASH = "$2a$10$CQVd5R6UaFV2xRSIt3BhJO2KklkaWGKCYDhR1D1S/jl3xtsWyMYSu";
    
    @Test
    public void findUserWithSpecificPasswordHash() {
        System.out.println("=== PROCURANDO USUÁRIO COM HASH ESPECÍFICO ===");
        System.out.println("Hash procurado: " + TARGET_HASH);
        
        try {
            // Buscar todas as credenciais e verificar o hash
            System.out.println("\nProcurando em todas as credenciais...");
            
            List<UserCredentials> allCredentials = userCredentialsRepository.findAll();
            System.out.println("Total de credenciais encontradas: " + allCredentials.size());
            
            boolean found = false;
            
            for (UserCredentials credentials : allCredentials) {
                System.out.println("\n--- Usuário ID: " + credentials.getUserId() + " ---");
                String hash = credentials.getPasswordHash();
                
                if (hash != null) {
                    // Mostrar apenas os primeiros e últimos caracteres do hash por segurança
                    String maskedHash = hash.length() > 20 ? 
                        hash.substring(0, 10) + "..." + hash.substring(hash.length() - 10) : hash;
                    System.out.println("Hash: " + maskedHash);
                    
                    // Verificar se é o hash que procuramos
                    if (TARGET_HASH.equals(hash)) {
                        System.out.println("🎉 HASH ENCONTRADO!");
                        found = true;
                        
                        // Buscar informações do usuário
                        try {
                            UserDto user = userService.getUserById(credentials.getUserId());
                            if (user != null) {
                                System.out.println("\n📋 INFORMAÇÕES DO USUÁRIO:");
                                System.out.println("  ID: " + user.getId());
                                System.out.println("  Nome: " + user.getName());
                                System.out.println("  Email: " + user.getEmail());
                                System.out.println("  Status: " + user.getStatus());
                                System.out.println("  Ativo: " + !Boolean.TRUE.equals(user.getDeleted()));
                                System.out.println("  Criado em: " + user.getCreatedAt());
                                
                                // Mostrar informações das credenciais
                                System.out.println("\n🔐 INFORMAÇÕES DAS CREDENCIAIS:");
                                System.out.println("  Conta bloqueada: " + credentials.isAccountLocked());
                                System.out.println("  Bloqueio permanente: " + credentials.isPermanentlyLocked());
                                System.out.println("  Tentativas falhadas: " + credentials.getFailedLoginAttempts());
                                System.out.println("  2FA habilitado: " + credentials.getTwoFactorEnabled());
                                System.out.println("  Último login: " + credentials.getLastLoginAt());
                                System.out.println("  Senha alterada em: " + credentials.getPasswordChangedAt());
                                
                                // Verificar possíveis problemas
                                checkUserIssues(user, credentials);
                                
                            } else {
                                System.out.println("❌ Não foi possível buscar informações do usuário");
                            }
                        } catch (Exception e) {
                            System.out.println("❌ Erro ao buscar usuário: " + e.getMessage());
                        }
                        
                        break; // Parar na primeira ocorrência
                    }
                } else {
                    System.out.println("Hash: null");
                }
            }
            
            if (!found) {
                System.out.println("\n❌ Hash não encontrado em nenhuma credencial!");
                System.out.println("💡 Possíveis causas:");
                System.out.println("  - O hash foi alterado recentemente");
                System.out.println("  - O usuário foi removido");
                System.out.println("  - Erro na consulta do banco de dados");
                
                // Mostrar alguns exemplos de hashes existentes
                showExampleHashes(allCredentials);
            }
            
        } catch (Exception e) {
            System.out.println("❌ Erro ao buscar credenciais: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    private void checkUserIssues(UserDto user, UserCredentials credentials) {
        System.out.println("\n🔍 VERIFICANDO POSSÍVEIS PROBLEMAS:");
        
        boolean hasIssues = false;
        
        // 1. Usuário deletado
        if (Boolean.TRUE.equals(user.getDeleted())) {
            System.out.println("  ❌ Usuário está marcado como deletado");
            hasIssues = true;
        }
        
        // 2. Status inativo
        if (!"ACTIVE".equals(user.getStatus())) {
            System.out.println("  ❌ Status do usuário não é ACTIVE: " + user.getStatus());
            hasIssues = true;
        }
        
        // 3. Conta bloqueada
        if (credentials.isAccountLocked()) {
            System.out.println("  ❌ Conta está bloqueada");
            hasIssues = true;
        }
        
        // 4. Bloqueio permanente
        if (credentials.isPermanentlyLocked()) {
            System.out.println("  ❌ Conta está permanentemente bloqueada");
            hasIssues = true;
        }
        
        // 5. Muitas tentativas falhadas
        if (credentials.getFailedLoginAttempts() != null && credentials.getFailedLoginAttempts() > 0) {
            System.out.println("  ⚠️ Tentativas falhadas: " + credentials.getFailedLoginAttempts());
        }
        
        if (!hasIssues) {
            System.out.println("  ✅ Nenhum problema encontrado! O usuário deveria conseguir fazer login.");
            
            System.out.println("\n💡 INSTRUÇÕES PARA LOGIN:");
            System.out.println("  Email: " + user.getEmail());
            System.out.println("  Senha: Leader@2025!Strong#Pass");
            System.out.println("  URL: http://localhost:8000/login (ou a URL da sua aplicação)");
            
        } else {
            System.out.println("\n🔧 SOLUÇÕES:");
            
            if (Boolean.TRUE.equals(user.getDeleted())) {
                System.out.println("  - Reativar o usuário no banco de dados");
            }
            
            if (!"ACTIVE".equals(user.getStatus())) {
                System.out.println("  - Alterar status para ACTIVE");
            }
            
            if (credentials.isAccountLocked() || credentials.isPermanentlyLocked()) {
                System.out.println("  - Desbloquear a conta: userCredentialsService.unlockAccount(" + user.getId() + "L)");
            }
            
            if (credentials.getFailedLoginAttempts() != null && credentials.getFailedLoginAttempts() > 0) {
                System.out.println("  - Resetar tentativas: userCredentialsService.resetFailedAttempts(" + user.getId() + "L)");
            }
        }
    }
    
    private void showExampleHashes(List<UserCredentials> allCredentials) {
        System.out.println("\n📊 EXEMPLOS DE HASHES EXISTENTES:");
        
        int count = 0;
        for (UserCredentials credentials : allCredentials) {
            if (credentials.getPasswordHash() != null && count < 5) {
                String hash = credentials.getPasswordHash();
                String maskedHash = hash.length() > 20 ? 
                    hash.substring(0, 15) + "..." + hash.substring(hash.length() - 10) : hash;
                System.out.println("  Usuário " + credentials.getUserId() + ": " + maskedHash);
                count++;
            }
        }
        
        if (count == 0) {
            System.out.println("  Nenhum hash encontrado!");
        }
    }
    
    @Test
    public void findUserByDirectQuery() {
        System.out.println("=== BUSCA DIRETA NO BANCO ===");
        
        try {
            // Tentar buscar por hash diretamente (se houver um método customizado)
            System.out.println("Procurando credenciais com hash específico...");
            
            // Como não temos um método findByPasswordHash, vamos usar findAll e filtrar
            List<UserCredentials> allCredentials = userCredentialsRepository.findAll();
            
            UserCredentials foundCredentials = allCredentials.stream()
                .filter(c -> TARGET_HASH.equals(c.getPasswordHash()))
                .findFirst()
                .orElse(null);
            
            if (foundCredentials != null) {
                System.out.println("✅ Credenciais encontradas para usuário ID: " + foundCredentials.getUserId());
                
                // Buscar informações do usuário
                try {
                    UserDto user = userService.getUserById(foundCredentials.getUserId());
                    System.out.println("✅ Usuário encontrado: " + user.getEmail());
                    
                    System.out.println("\n🎯 INFORMAÇÕES PARA LOGIN:");
                    System.out.println("  Email: " + user.getEmail());
                    System.out.println("  Senha: Leader@2025!Strong#Pass");
                    System.out.println("  Status: " + user.getStatus());
                    System.out.println("  Ativo: " + !Boolean.TRUE.equals(user.getDeleted()));
                    
                } catch (Exception e) {
                    System.out.println("❌ Erro ao buscar usuário ID " + foundCredentials.getUserId() + ": " + e.getMessage());
                }
                
            } else {
                System.out.println("❌ Nenhuma credencial encontrada com o hash especificado");
            }
            
        } catch (Exception e) {
            System.out.println("❌ Erro na busca: " + e.getMessage());
            e.printStackTrace();
        }
    }
}
