package com.social.media;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.password.PasswordEncoder;

import static org.junit.jupiter.api.Assertions.*;

/**
 * Teste específico para verificar o hash da senha do banco de dados
 */
@SpringBootTest
public class PasswordVerificationTest {
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    // Hash encontrado no banco de dados
    private static final String HASH_FROM_DATABASE = "$2a$10$CQVd5R6UaFV2xRSIt3BhJO2KklkaWGKCYDhR1D1S/jl3xtsWyMYSu";
    
    // Senha que está sendo digitada
    private static final String ENTERED_PASSWORD = "Leader@2025!Strong#Pass";
    
    @Test
    public void testPasswordVerificationFromDatabase() {
        System.out.println("=== VERIFICAÇÃO DA SENHA DO BANCO DE DADOS ===");
        System.out.println("Hash no banco: " + HASH_FROM_DATABASE);
        System.out.println("Senha digitada: " + ENTERED_PASSWORD);
        
        // Verificar se a senha digitada corresponde ao hash do banco
        boolean matches = passwordEncoder.matches(ENTERED_PASSWORD, HASH_FROM_DATABASE);
        
        System.out.println("A senha corresponde ao hash: " + matches);
        
        if (matches) {
            System.out.println("✅ SUCESSO: A senha está correta!");
        } else {
            System.out.println("❌ FALHA: A senha NÃO corresponde ao hash do banco!");
            
            // Vamos testar algumas variações possíveis
            testPasswordVariations();
        }
        
        // Para fins de debugging, vamos mostrar como seria o hash da senha digitada
        String newHash = passwordEncoder.encode(ENTERED_PASSWORD);
        System.out.println("Novo hash para a senha digitada: " + newHash);
        
        boolean newHashMatches = passwordEncoder.matches(ENTERED_PASSWORD, newHash);
        System.out.println("Novo hash verifica corretamente: " + newHashMatches);
    }
    
    private void testPasswordVariations() {
        System.out.println("\n=== TESTANDO VARIAÇÕES DA SENHA ===");
        
        String[] variations = {
            "Leader@2025!Strong#Pass",  // Original
            "leader@2025!strong#pass",  // Tudo minúsculo
            "LEADER@2025!STRONG#PASS",  // Tudo maiúsculo
            "Leader@2025!Strong#Pass ", // Com espaço no final
            " Leader@2025!Strong#Pass", // Com espaço no início
            "Leader@2025!Strong#Pass\n", // Com quebra de linha
            "Leader@2025!Strong#Pass\r", // Com carriage return
            "Leader@2025!Strong#Pass\t", // Com tab
            "Leader@2025Strong#Pass",   // Sem exclamação
            "Leader@2025!Strong Pass",  // Sem hashtag
            "Leader2025!Strong#Pass",   // Sem @
        };
        
        for (String variation : variations) {
            boolean matches = passwordEncoder.matches(variation, HASH_FROM_DATABASE);
            String displayVariation = variation.replace("\n", "\\n")
                                             .replace("\r", "\\r")
                                             .replace("\t", "\\t");
            System.out.println("Variação '" + displayVariation + "': " + (matches ? "✅" : "❌"));
            
            if (matches) {
                System.out.println("🎉 ENCONTRADA A SENHA CORRETA: '" + displayVariation + "'");
                return;
            }
        }
        
        System.out.println("❌ Nenhuma variação funcionou. O hash pode ter sido gerado com uma senha diferente.");
    }
    
    @Test
    public void investigateHashGeneration() {
        System.out.println("\n=== INVESTIGANDO A GERAÇÃO DO HASH ===");
        
        // Vamos tentar descobrir com que senha esse hash foi gerado
        // Testando senhas comuns que poderiam ter gerado esse hash
        
        String[] possiblePasswords = {
            "admin",
            "password",
            "123456",
            "admin123",
            "password123",
            "Leader@2025",
            "Strong#Pass",
            "Leader@2025!",
            "2025!Strong#Pass",
            "Leader@Strong#Pass",
            "Leader@2025!Strong",
            "Leader2025StrongPass",
            "test",
            "test123",
            "demo",
            "demo123",
            "user",
            "user123"
        };
        
        System.out.println("Testando senhas comuns...");
        
        for (String testPassword : possiblePasswords) {
            boolean matches = passwordEncoder.matches(testPassword, HASH_FROM_DATABASE);
            if (matches) {
                System.out.println("🎉 SENHA ENCONTRADA: '" + testPassword + "'");
                return;
            }
        }
        
        System.out.println("❌ Nenhuma senha comum corresponde ao hash.");
        System.out.println("💡 Sugestão: Verifique se o hash está correto ou se a senha foi alterada.");
    }
    
    @Test
    public void testDirectBCryptValidation() {
        System.out.println("\n=== VALIDAÇÃO DIRETA DO BCRYPT ===");
        
        // Verificar se o hash está no formato BCrypt correto
        System.out.println("Hash: " + HASH_FROM_DATABASE);
        System.out.println("Comprimento: " + HASH_FROM_DATABASE.length());
        System.out.println("Inicia com $2a$: " + HASH_FROM_DATABASE.startsWith("$2a$"));
        System.out.println("Formato BCrypt válido: " + isValidBCryptHash(HASH_FROM_DATABASE));
        
        // Testar a senha fornecida
        boolean result = passwordEncoder.matches(ENTERED_PASSWORD, HASH_FROM_DATABASE);
        System.out.println("Resultado da verificação: " + result);
        
        // Mostrar informações sobre o algoritmo BCrypt
        System.out.println("\nInformações do hash:");
        if (HASH_FROM_DATABASE.startsWith("$2a$")) {
            String[] parts = HASH_FROM_DATABASE.split("\\$");
            if (parts.length >= 4) {
                System.out.println("Algoritmo: " + parts[1]);
                System.out.println("Custo: " + parts[2]);
                System.out.println("Salt + Hash: " + parts[3]);
            }
        }
    }
    
    private boolean isValidBCryptHash(String hash) {
        // BCrypt hashes têm o formato $2a$rounds$salt+hash
        // O comprimento total deve ser 60 caracteres
        return hash != null && 
               hash.length() == 60 && 
               (hash.startsWith("$2a$") || hash.startsWith("$2b$") || hash.startsWith("$2y$"));
    }
}
