package com.social.media.domain.socialnetwork.aggregate;

import com.social.media.domain.socialnetwork.valueobject.*;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * Social Network Aggregate Root
 * Represents a social media platform configuration
 */
public class SocialNetwork {
    
    private SocialNetworkId id;
    private PlatformType platformType;
    private String displayName;
    private String baseUrl;
    private String logoUrl;
    private String primaryColor;
    private PlatformCapabilities capabilities;
    private ApiConfiguration apiConfiguration;
    private boolean active;
    private LocalDateTime registrationDate;
    private boolean deleted;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
    
    // Private constructor for builder pattern
    private SocialNetwork() {}
    
    /**
     * Creates a new social network (factory method)
     */
    public static SocialNetwork create(PlatformType platformType, String displayName, 
                                     String baseUrl, PlatformCapabilities capabilities) {
        SocialNetwork socialNetwork = new SocialNetwork();
        socialNetwork.platformType = Objects.requireNonNull(platformType, "Platform type cannot be null");
        socialNetwork.displayName = validateDisplayName(displayName);
        socialNetwork.baseUrl = baseUrl;
        socialNetwork.capabilities = Objects.requireNonNull(capabilities, "Capabilities cannot be null");
        socialNetwork.active = true;
        socialNetwork.registrationDate = LocalDateTime.now();
        socialNetwork.deleted = false;
        socialNetwork.createdAt = LocalDateTime.now();
        socialNetwork.updatedAt = LocalDateTime.now();
        
        return socialNetwork;
    }
    
    /**
     * Reconstructs social network from persistence (for repository)
     */
    public static SocialNetwork reconstruct(SocialNetworkId id, PlatformType platformType, 
                                          String displayName, String baseUrl, String logoUrl,
                                          String primaryColor, PlatformCapabilities capabilities,
                                          ApiConfiguration apiConfiguration, boolean active,
                                          LocalDateTime registrationDate, boolean deleted,
                                          LocalDateTime createdAt, LocalDateTime updatedAt) {
        SocialNetwork socialNetwork = new SocialNetwork();
        socialNetwork.id = id;
        socialNetwork.platformType = platformType;
        socialNetwork.displayName = displayName;
        socialNetwork.baseUrl = baseUrl;
        socialNetwork.logoUrl = logoUrl;
        socialNetwork.primaryColor = primaryColor;
        socialNetwork.capabilities = capabilities;
        socialNetwork.apiConfiguration = apiConfiguration;
        socialNetwork.active = active;
        socialNetwork.registrationDate = registrationDate;
        socialNetwork.deleted = deleted;
        socialNetwork.createdAt = createdAt;
        socialNetwork.updatedAt = updatedAt;
        
        return socialNetwork;
    }
    
    // Business Methods
    
    public void activate() {
        if (deleted) {
            throw new SocialNetworkDomainException("Cannot activate deleted social network");
        }
        this.active = true;
        this.updatedAt = LocalDateTime.now();
    }
    
    public void deactivate() {
        this.active = false;
        this.updatedAt = LocalDateTime.now();
    }
    
    public void updateConfiguration(ApiConfiguration apiConfiguration) {
        this.apiConfiguration = apiConfiguration;
        this.updatedAt = LocalDateTime.now();
    }
    
    public void updateCapabilities(PlatformCapabilities capabilities) {
        this.capabilities = Objects.requireNonNull(capabilities, "Capabilities cannot be null");
        this.updatedAt = LocalDateTime.now();
    }
    
    public void updateBranding(String logoUrl, String primaryColor) {
        this.logoUrl = logoUrl;
        this.primaryColor = primaryColor;
        this.updatedAt = LocalDateTime.now();
    }
    
    public void softDelete() {
        this.deleted = true;
        this.active = false;
        this.updatedAt = LocalDateTime.now();
    }
    
    public boolean canPublishPost() {
        return active && !deleted && capabilities.supportsPosts();
    }
    
    public boolean canPublishStory() {
        return active && !deleted && capabilities.supportsStories();
    }
    
    public boolean canPublishVideo() {
        return active && !deleted && capabilities.supportsVideos();
    }
    
    public boolean canPublishReel() {
        return active && !deleted && capabilities.supportsReels();
    }
    
    public boolean canSendDirectMessage() {
        return active && !deleted && capabilities.supportsDirectMessages();
    }
    
    public boolean supportsMediaFormat(String format) {
        return capabilities.supportsMediaFormat(format);
    }
    
    public boolean isContentWithinLimit(String content) {
        return capabilities.isWithinPostLimit(content);
    }
    
    // Validation methods
    
    private static String validateDisplayName(String displayName) {
        if (displayName == null || displayName.trim().isEmpty()) {
            throw new SocialNetworkDomainException("Display name cannot be null or empty");
        }
        if (displayName.trim().length() < 2) {
            throw new SocialNetworkDomainException("Display name must have at least 2 characters");
        }
        return displayName.trim();
    }
    
    // Getters
    
    public SocialNetworkId getId() { return id; }
    public PlatformType getPlatformType() { return platformType; }
    public String getDisplayName() { return displayName; }
    public String getBaseUrl() { return baseUrl; }
    public String getLogoUrl() { return logoUrl; }
    public String getPrimaryColor() { return primaryColor; }
    public PlatformCapabilities getCapabilities() { return capabilities; }
    public ApiConfiguration getApiConfiguration() { return apiConfiguration; }
    public boolean isActive() { return active; }
    public LocalDateTime getRegistrationDate() { return registrationDate; }
    public boolean isDeleted() { return deleted; }
    public LocalDateTime getCreatedAt() { return createdAt; }
    public LocalDateTime getUpdatedAt() { return updatedAt; }
    
    // Setters for reconstruction only
    void setId(SocialNetworkId id) { this.id = id; }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SocialNetwork socialNetwork = (SocialNetwork) o;
        return Objects.equals(id, socialNetwork.id);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
    
    @Override
    public String toString() {
        return "SocialNetwork{" +
                "id=" + id +
                ", platformType=" + platformType +
                ", displayName='" + displayName + '\'' +
                ", active=" + active +
                '}';
    }
    
    /**
     * Domain exception specific to SocialNetwork aggregate
     */
    public static class SocialNetworkDomainException extends RuntimeException {
        public SocialNetworkDomainException(String message) {
            super(message);
        }
    }
}
