package com.social.media.application.shared.security;

import com.social.media.domain.user.UserId;
import com.social.media.domain.company.valueobject.CompanyId;
import com.social.media.domain.shared.enums.UserType;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;

import java.util.Collection;

/**
 * Service for extracting authentication information from security context
 */
@Component
public class AuthenticationService {
    
    /**
     * Extract authenticated user information from security context
     * 
     * TODO: Implement based on your authentication setup (JWT, Session, etc.)
     * This is a placeholder implementation that needs to be customized
     */
    public AuthenticatedUserInfo getAuthenticatedUserInfo() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        
        if (authentication == null || !authentication.isAuthenticated()) {
            throw new RuntimeException("User not authenticated");
        }
        
        // TODO: Replace with actual implementation based on your security setup
        
        // Example for JWT token (you need to implement JWT parsing):
        /*
        if (authentication.getPrincipal() instanceof JwtAuthenticationToken jwtToken) {
            String userIdStr = jwtToken.getToken().getClaimAsString("userId");
            String companyIdStr = jwtToken.getToken().getClaimAsString("companyId");
            String userTypeStr = jwtToken.getToken().getClaimAsString("userType");
            String username = jwtToken.getToken().getClaimAsString("username");
            
            return new AuthenticatedUserInfo(
                new UserId(Long.parseLong(userIdStr)),
                new CompanyId(Long.parseLong(companyIdStr)),
                UserType.valueOf(userTypeStr),
                username,
                true
            );
        }
        */
        
        // Example for UserDetails (if using Spring Security UserDetails):
        /*
        if (authentication.getPrincipal() instanceof CustomUserDetails userDetails) {
            return new AuthenticatedUserInfo(
                new UserId(userDetails.getUserId()),
                new CompanyId(userDetails.getCompanyId()),
                userDetails.getUserType(),
                userDetails.getUsername(),
                userDetails.isEnabled()
            );
        }
        */
        
        // Example for custom principal:
        /*
        if (authentication.getPrincipal() instanceof CustomUser customUser) {
            return new AuthenticatedUserInfo(
                new UserId(customUser.getId()),
                new CompanyId(customUser.getCompanyId()),
                customUser.getUserType(),
                customUser.getUsername(),
                customUser.isActive()
            );
        }
        */
        
        // TEMPORARY PLACEHOLDER - REPLACE WITH ACTUAL IMPLEMENTATION
        // This extracts user information from authentication name or attributes
        String principal = authentication.getName();
        
        // Parse from principal if it contains encoded information
        // Format: "userId:companyId:userType:username"
        if (principal.contains(":")) {
            String[] parts = principal.split(":");
            if (parts.length >= 4) {
                return new AuthenticatedUserInfo(
                    UserId.of(java.util.UUID.fromString(parts[0])),
                    com.social.media.domain.company.valueobject.CompanyId.of(Long.parseLong(parts[1])),
                    UserType.valueOf(parts[2]),
                    parts[3],
                    true
                );
            }
        }
        
        // Extract from authorities if roles contain information
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        UserType userType = authorities.stream()
            .map(GrantedAuthority::getAuthority)
            .filter(authority -> authority.startsWith("ROLE_"))
            .map(authority -> authority.substring(5)) // Remove "ROLE_" prefix
            .filter(role -> role.equals("SUPER_ADMIN") || role.equals("ADMIN") || role.equals("MANAGER") || role.equals("USER") || role.equals("CLIENT"))
            .map(UserType::valueOf)
            .findFirst()
            .orElse(UserType.USER);
        
        // Default fallback (SHOULD BE REPLACED)
        return new AuthenticatedUserInfo(
            UserId.of(java.util.UUID.randomUUID()), // TODO: Extract from JWT/Session
            com.social.media.domain.company.valueobject.CompanyId.of(1L), // TODO: Extract from JWT/Session
            UserType.USER,
            authentication.getName(),
            true
        );
    }
    
    /**
     * Check if current user is authenticated
     */
    public boolean isAuthenticated() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return authentication != null && authentication.isAuthenticated();
    }
    
    /**
     * Check if current user has admin privileges
     */
    public boolean isCurrentUserAdmin() {
        try {
            return getAuthenticatedUserInfo().isAdmin();
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * Check if current user is super admin
     */
    public boolean isCurrentUserSuperAdmin() {
        try {
            return getAuthenticatedUserInfo().isSuperAdmin();
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * Get current user's company ID
     */
    public Long getCurrentUserCompanyId() {
        return getAuthenticatedUserInfo().companyIdAsLong();
    }
    
    /**
     * Get current user ID
     */
    public java.util.UUID getCurrentUserId() {
        return getAuthenticatedUserInfo().getUserUUID();
    }
}
