package dev.lions.unionflow.client.service;

import dev.lions.unionflow.server.api.dto.auth.request.LoginRequest;
import dev.lions.unionflow.server.api.dto.auth.response.LoginResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import java.time.LocalDateTime;
import java.util.UUID;
import java.util.logging.Logger;

@ApplicationScoped
public class AuthenticationService {
    
    private static final Logger LOGGER = Logger.getLogger(AuthenticationService.class.getName());
    
    @ConfigProperty(name = "unionflow.backend.url", defaultValue = "http://localhost:8080")
    String backendUrl;
    
    private final Client client;
    
    public AuthenticationService() {
        this.client = ClientBuilder.newClient();
    }
    
    public LoginResponse authenticate(LoginRequest loginRequest) {
        try {
            String endpoint = backendUrl + "/api/auth/login";
            
            LOGGER.info("Tentative d'authentification vers: " + endpoint);
            
            Response response = client.target(endpoint)
                    .request(MediaType.APPLICATION_JSON)
                    .post(Entity.entity(loginRequest, MediaType.APPLICATION_JSON));
            
            if (response.getStatus() == 200) {
                LoginResponse loginResponse = response.readEntity(LoginResponse.class);
                LOGGER.info("Authentification réussie pour l'utilisateur: " + loginRequest.username());
                return loginResponse;
            } else {
                LOGGER.warning("Échec de l'authentification. Code de statut: " + response.getStatus());
                throw new AuthenticationException("Nom d'utilisateur ou mot de passe incorrect");
            }

        } catch (Exception e) {
            LOGGER.severe("Erreur lors de l'authentification: " + e.getMessage());

            // Mode simulation pour le développement
            if ("demo".equals(loginRequest.username()) || isValidDemoCredentials(loginRequest)) {
                return createDemoLoginResponse(loginRequest);
            }
            
            throw new AuthenticationException("Erreur de connexion au serveur d'authentification");
        }
    }
    
    public LoginResponse refreshToken(String refreshToken) {
        try {
            String endpoint = backendUrl + "/api/auth/refresh";
            
            Response response = client.target(endpoint)
                    .request(MediaType.APPLICATION_JSON)
                    .header("Authorization", "Bearer " + refreshToken)
                    .post(Entity.text(""));
            
            if (response.getStatus() == 200) {
                return response.readEntity(LoginResponse.class);
            } else {
                throw new AuthenticationException("Token de rafraîchissement invalide");
            }
            
        } catch (Exception e) {
            LOGGER.severe("Erreur lors du rafraîchissement du token: " + e.getMessage());
            throw new AuthenticationException("Erreur lors du rafraîchissement du token");
        }
    }
    
    public void logout(String accessToken) {
        try {
            String endpoint = backendUrl + "/api/auth/logout";
            
            client.target(endpoint)
                    .request()
                    .header("Authorization", "Bearer " + accessToken)
                    .post(Entity.text(""));
                    
        } catch (Exception e) {
            LOGGER.warning("Erreur lors de la déconnexion: " + e.getMessage());
        }
    }
    
    private boolean isValidDemoCredentials(LoginRequest request) {
        return ("admin".equals(request.username()) && "admin".equals(request.password())) ||
               ("superadmin".equals(request.username()) && "admin".equals(request.password())) ||
               ("membre".equals(request.username()) && "membre".equals(request.password()));
    }
    
    private LoginResponse createDemoLoginResponse(LoginRequest request) {
        LoginResponse.UserInfo userInfo = new LoginResponse.UserInfo();

        // UUIDs fixes pour la démonstration (pour cohérence entre les sessions)
        UUID superAdminId = UUID.fromString("00000000-0000-0000-0000-000000000001");
        UUID adminId = UUID.fromString("00000000-0000-0000-0000-000000000002");
        UUID membreId = UUID.fromString("00000000-0000-0000-0000-000000000003");
        UUID entiteId = UUID.fromString("00000000-0000-0000-0000-000000000010");

        switch (request.username()) {
            case "superadmin":
                userInfo.setId(superAdminId);
                userInfo.setNom("Diallo");
                userInfo.setPrenom("Amadou");
                userInfo.setEmail("amadou.diallo@unionflow.sn");
                userInfo.setUsername("superadmin");
                userInfo.setTypeCompte("SUPER_ADMIN");
                userInfo.setRoles(java.util.Arrays.asList("SUPER_ADMIN", "ADMIN"));
                break;
                
            case "admin":
                userInfo.setId(adminId);
                userInfo.setNom("Traoré");
                userInfo.setPrenom("Fatou");
                userInfo.setEmail("fatou.traore@association-example.sn");
                userInfo.setUsername("admin");
                userInfo.setTypeCompte("ADMIN_ORGANISATION");
                userInfo.setRoles(java.util.Arrays.asList("ADMIN_ORGANISATION"));
                
                // Entité de démonstration
                LoginResponse.EntiteInfo entite = new LoginResponse.EntiteInfo();
                entite.setId(entiteId);
                entite.setNom("Association des Jeunes Entrepreneurs");
                entite.setType("Association");
                entite.setPays("Sénégal");
                entite.setVille("Dakar");
                userInfo.setEntite(entite);
                break;
                
            default:
                userInfo.setId(membreId);
                userInfo.setNom("Ndiaye");
                userInfo.setPrenom("Moussa");
                userInfo.setEmail("moussa.ndiaye@exemple.sn");
                userInfo.setUsername("membre");
                userInfo.setTypeCompte("MEMBRE");
                userInfo.setRoles(java.util.Arrays.asList("MEMBRE"));
                
                // Entité de démonstration
                LoginResponse.EntiteInfo entiteMembre = new LoginResponse.EntiteInfo();
                entiteMembre.setId(entiteId);
                entiteMembre.setNom("Association des Jeunes Entrepreneurs");
                entiteMembre.setType("Association");
                entiteMembre.setPays("Sénégal");
                entiteMembre.setVille("Dakar");
                userInfo.setEntite(entiteMembre);
                break;
        }

        long expiresIn = 3600L; // 1 heure en secondes
        LocalDateTime expirationDate = LocalDateTime.now().plusSeconds(expiresIn);

        return LoginResponse.builder()
            .accessToken("demo_access_token_" + System.currentTimeMillis())
            .refreshToken("demo_refresh_token_" + System.currentTimeMillis())
            .tokenType("Bearer")
            .expiresIn(expiresIn)
            .expirationDate(expirationDate)
            .user(userInfo)
            .build();
    }
    
    public static class AuthenticationException extends RuntimeException {
        public AuthenticationException(String message) {
            super(message);
        }
        
        public AuthenticationException(String message, Throwable cause) {
            super(message, cause);
        }
    }
}
