package com.social.media.infrastructure.persistence.socialaccount;

import com.social.media.application.socialaccount.dto.SocialAccountResponseDto;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.HashMap;

/**
 * Mapper for converting between Social Account JPA Entity and DTOs
 */
@Component
public class SocialAccountMapper {

    /**
     * Convert JPA entity to response DTO
     */
    public SocialAccountResponseDto toResponseDto(SocialAccountJpaEntity entity) {
        if (entity == null) {
            return null;
        }

        // Extract metrics with safe defaults
        Map<String, Object> metrics = entity.getMetrics() != null ? entity.getMetrics() : new HashMap<>();
        
        return SocialAccountResponseDto.builder()
                .id(entity.getId().toString())
                .userId(entity.getResponsibleUserId() != null ? entity.getResponsibleUserId().toString() : null)
                .companyId(entity.getCompanyId().toString())
                .socialNetworkId(entity.getSocialNetworkId().toString())
                .platformAccountId(entity.getUsername()) // Using username as platform account ID
                .username(entity.getUsername())
                .displayName(entity.getDisplayName())
                .profileUrl(entity.getProfileUrl())
                .avatarUrl(entity.getProfilePhotoUrl())
                .status(entity.getConnectionStatus().name())
                .verified(entity.getVerified() != null ? entity.getVerified() : false)
                .followersCount(extractIntegerFromMetrics(metrics, "followers", 0))
                .followingCount(extractIntegerFromMetrics(metrics, "following", 0))
                .postsCount(extractIntegerFromMetrics(metrics, "posts", 0))
                .authTokens(entity.getTokens())
                .accountMetrics(metrics)
                .lastSyncDate(entity.getLastSyncDate())
                .connectedAt(entity.getRegistrationDate())
                .createdAt(entity.getCreatedAt())
                .updatedAt(entity.getUpdatedAt())
                .build();
    }

    /**
     * Update JPA entity from update command data
     */
    public void updateEntityFromRequest(SocialAccountJpaEntity entity, 
                                      String displayName,
                                      String bio,
                                      String location,
                                      String website,
                                      String profilePhotoUrl,
                                      String contactPhone,
                                      String contactEmail,
                                      String category,
                                      Map<String, Object> automationConfig,
                                      String responsibleUserId) {
        
        if (displayName != null) {
            entity.setDisplayName(displayName);
        }
        
        if (bio != null) {
            entity.setBio(bio);
        }
        
        if (location != null) {
            entity.setLocation(location);
        }
        
        if (website != null) {
            entity.setWebsite(website);
        }
        
        if (profilePhotoUrl != null) {
            entity.setProfilePhotoUrl(profilePhotoUrl);
        }
        
        if (contactPhone != null) {
            entity.setContactPhone(contactPhone);
        }
        
        if (contactEmail != null) {
            entity.setContactEmail(contactEmail);
        }
        
        if (category != null) {
            entity.setCategory(category);
        }
        
        if (automationConfig != null) {
            entity.setAutomationConfig(automationConfig);
        }
        
        if (responsibleUserId != null && !responsibleUserId.trim().isEmpty()) {
            try {
                entity.setResponsibleUserId(Long.parseLong(responsibleUserId));
            } catch (NumberFormatException e) {
                // Log error or handle invalid user ID
            }
        }
    }

    /**
     * Create new JPA entity from connect command
     */
    public SocialAccountJpaEntity createEntityFromConnectCommand(
            String companyId,
            Long socialNetworkId,
            String username,
            String accessToken,
            String refreshToken,
            String tokenType) {
        
        SocialAccountJpaEntity entity = new SocialAccountJpaEntity();
        entity.setCompanyId(Long.parseLong(companyId));
        entity.setSocialNetworkId(socialNetworkId);
        entity.setUsername(username);
        entity.setDisplayName(username); // Default display name to username
        
        // Create tokens map
        Map<String, Object> tokens = new HashMap<>();
        tokens.put("accessToken", accessToken != null ? accessToken : "");
        tokens.put("refreshToken", refreshToken != null ? refreshToken : "");
        tokens.put("tokenType", tokenType != null ? tokenType : "Bearer");
        tokens.put("isExpired", false);
        tokens.put("needsRefresh", false);
        tokens.put("scope", new String[]{});
        entity.setTokens(tokens);
        
        // Create default metrics
        Map<String, Object> metrics = new HashMap<>();
        metrics.put("followers", 0);
        metrics.put("following", 0);
        metrics.put("posts", 0);
        metrics.put("engagement", 0.0);
        metrics.put("avgLikes", 0.0);
        metrics.put("avgComments", 0.0);
        metrics.put("avgShares", 0.0);
        metrics.put("reachRate", 0.0);
        metrics.put("impressionRate", 0.0);
        entity.setMetrics(metrics);
        
        // Create default automation config
        Map<String, Object> automationConfig = new HashMap<>();
        automationConfig.put("followEnabled", false);
        automationConfig.put("unfollowEnabled", false);
        automationConfig.put("likeEnabled", false);
        automationConfig.put("commentEnabled", false);
        automationConfig.put("dmEnabled", false);
        automationConfig.put("storyViewEnabled", false);
        automationConfig.put("followLimit", 50);
        automationConfig.put("unfollowLimit", 50);
        automationConfig.put("likeLimit", 100);
        automationConfig.put("commentLimit", 20);
        automationConfig.put("dmLimit", 10);
        automationConfig.put("targetHashtags", new String[]{});
        automationConfig.put("targetLocations", new String[]{});
        automationConfig.put("blacklistedUsers", new String[]{});
        entity.setAutomationConfig(automationConfig);
        
        entity.setConnectionStatus(SocialAccountJpaEntity.ConnectionStatusEnum.ACTIVE);
        entity.setActive(true);
        entity.setVerified(false);
        entity.setIsPrivate(false);
        entity.setDeleted(false);
        
        return entity;
    }

    /**
     * Helper method to safely extract integer values from metrics map
     */
    private Integer extractIntegerFromMetrics(Map<String, Object> metrics, String key, Integer defaultValue) {
        if (metrics == null || !metrics.containsKey(key)) {
            return defaultValue;
        }
        
        Object value = metrics.get(key);
        if (value instanceof Integer) {
            return (Integer) value;
        } else if (value instanceof Number) {
            return ((Number) value).intValue();
        } else if (value instanceof String) {
            try {
                return Integer.parseInt((String) value);
            } catch (NumberFormatException e) {
                return defaultValue;
            }
        }
        
        return defaultValue;
    }

    /**
     * Helper method to safely extract double values from metrics map
     */
    private Double extractDoubleFromMetrics(Map<String, Object> metrics, String key, Double defaultValue) {
        if (metrics == null || !metrics.containsKey(key)) {
            return defaultValue;
        }
        
        Object value = metrics.get(key);
        if (value instanceof Double) {
            return (Double) value;
        } else if (value instanceof Number) {
            return ((Number) value).doubleValue();
        } else if (value instanceof String) {
            try {
                return Double.parseDouble((String) value);
            } catch (NumberFormatException e) {
                return defaultValue;
            }
        }
        
        return defaultValue;
    }
}
