package com.social.media.domain.socialnetwork;

import com.social.media.domain.shared.BaseEntity;
import com.social.media.domain.shared.enums.SocialPlatform;

import java.time.LocalDateTime;
import java.util.UUID;
import java.util.Objects;

/**
 * Social Network aggregate root representing a social media platform configuration.
 * Contains platform-specific features, rate limits, and metadata.
 */
public class SocialNetwork extends BaseEntity {
    
    private SocialPlatform platform;
    private String platformName;
    private String platformVersion;
    private String apiBaseUrl;
    private String authUrl;
    private String tokenUrl;
    private PlatformFeatures features;
    private RateLimits rateLimits;
    private boolean isActive;
    private boolean isMaintenanceMode;
    private String maintenanceMessage;
    private LocalDateTime lastApiCheck;
    private String apiStatus;
    private String iconUrl;
    private String brandColor;
    private String documentationUrl;
    private String supportEmail;
    private Integer priority; // For display ordering
    
    // Default constructor for JPA
    protected SocialNetwork() {
        super();
    }
    
    public SocialNetwork(
            SocialPlatform platform,
            String platformName,
            String platformVersion,
            String apiBaseUrl,
            String authUrl,
            String tokenUrl,
            PlatformFeatures features,
            RateLimits rateLimits,
            String iconUrl,
            String brandColor,
            String documentationUrl,
            String supportEmail,
            Integer priority) {
        
        super();
        this.platform = validatePlatform(platform);
        this.platformName = validatePlatformName(platformName);
        this.platformVersion = validatePlatformVersion(platformVersion);
        this.apiBaseUrl = validateUrl(apiBaseUrl, "apiBaseUrl");
        this.authUrl = validateUrl(authUrl, "authUrl");
        this.tokenUrl = validateUrl(tokenUrl, "tokenUrl");
        this.features = validateFeatures(features);
        this.rateLimits = validateRateLimits(rateLimits);
        this.isActive = true;
        this.isMaintenanceMode = false;
        this.maintenanceMessage = null;
        this.lastApiCheck = LocalDateTime.now();
        this.apiStatus = "UNKNOWN";
        this.iconUrl = iconUrl;
        this.brandColor = brandColor;
        this.documentationUrl = documentationUrl;
        this.supportEmail = supportEmail;
        this.priority = validatePriority(priority);
    }
    
    // Factory methods for common platforms
    public static SocialNetwork createInstagram() {
        return new SocialNetwork(
            SocialPlatform.INSTAGRAM,
            "Instagram",
            "v19.0",
            "https://graph.instagram.com",
            "https://api.instagram.com/oauth/authorize",
            "https://api.instagram.com/oauth/access_token",
            PlatformFeatures.forInstagram(),
            RateLimits.forInstagram(),
            "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/instagram.svg",
            "#E4405F",
            "https://developers.facebook.com/docs/instagram-api",
            "support@instagram.com",
            1
        );
    }
    
    public static SocialNetwork createFacebook() {
        return new SocialNetwork(
            SocialPlatform.FACEBOOK,
            "Facebook",
            "v19.0",
            "https://graph.facebook.com",
            "https://www.facebook.com/v19.0/dialog/oauth",
            "https://graph.facebook.com/v19.0/oauth/access_token",
            PlatformFeatures.forFacebook(),
            RateLimits.forFacebook(),
            "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/facebook.svg",
            "#1877F2",
            "https://developers.facebook.com/docs/",
            "support@facebook.com",
            2
        );
    }
    
    public static SocialNetwork createTwitter() {
        return new SocialNetwork(
            SocialPlatform.TWITTER,
            "X (Twitter)",
            "v2",
            "https://api.twitter.com",
            "https://twitter.com/i/oauth2/authorize",
            "https://api.twitter.com/2/oauth2/token",
            PlatformFeatures.forTwitter(),
            RateLimits.forTwitter(),
            "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/x.svg",
            "#000000",
            "https://developer.twitter.com/en/docs",
            "support@twitter.com",
            3
        );
    }
    
    public static SocialNetwork createLinkedIn() {
        return new SocialNetwork(
            SocialPlatform.LINKEDIN,
            "LinkedIn",
            "v2",
            "https://api.linkedin.com",
            "https://www.linkedin.com/oauth/v2/authorization",
            "https://www.linkedin.com/oauth/v2/accessToken",
            PlatformFeatures.forLinkedIn(),
            RateLimits.forLinkedIn(),
            "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/linkedin.svg",
            "#0A66C2",
            "https://docs.microsoft.com/en-us/linkedin/",
            "support@linkedin.com",
            4
        );
    }
    
    // Validation methods
    private SocialPlatform validatePlatform(SocialPlatform platform) {
        if (platform == null) {
            throw new IllegalArgumentException("Platform cannot be null");
        }
        return platform;
    }
    
    private String validatePlatformName(String platformName) {
        if (platformName == null || platformName.trim().isEmpty()) {
            throw new IllegalArgumentException("Platform name cannot be null or empty");
        }
        if (platformName.length() > 100) {
            throw new IllegalArgumentException("Platform name cannot exceed 100 characters");
        }
        return platformName.trim();
    }
    
    private String validatePlatformVersion(String platformVersion) {
        if (platformVersion == null || platformVersion.trim().isEmpty()) {
            throw new IllegalArgumentException("Platform version cannot be null or empty");
        }
        if (platformVersion.length() > 20) {
            throw new IllegalArgumentException("Platform version cannot exceed 20 characters");
        }
        return platformVersion.trim();
    }
    
    private String validateUrl(String url, String fieldName) {
        if (url == null || url.trim().isEmpty()) {
            throw new IllegalArgumentException(fieldName + " cannot be null or empty");
        }
        if (!url.startsWith("http://") && !url.startsWith("https://")) {
            throw new IllegalArgumentException(fieldName + " must be a valid URL");
        }
        if (url.length() > 500) {
            throw new IllegalArgumentException(fieldName + " cannot exceed 500 characters");
        }
        return url.trim();
    }
    
    private PlatformFeatures validateFeatures(PlatformFeatures features) {
        if (features == null) {
            throw new IllegalArgumentException("Platform features cannot be null");
        }
        return features;
    }
    
    private RateLimits validateRateLimits(RateLimits rateLimits) {
        if (rateLimits == null) {
            throw new IllegalArgumentException("Rate limits cannot be null");
        }
        return rateLimits;
    }
    
    private Integer validatePriority(Integer priority) {
        if (priority != null && (priority < 1 || priority > 100)) {
            throw new IllegalArgumentException("Priority must be between 1 and 100");
        }
        return priority;
    }
    
    // Business methods
    
    /**
     * Activates the social network platform.
     */
    public void activate() {
        if (!isActive) {
            this.isActive = true;
            this.markAsModified();
        }
    }
    
    /**
     * Deactivates the social network platform.
     */
    public void deactivate() {
        if (isActive) {
            this.isActive = false;
            this.markAsModified();
        }
    }
    
    /**
     * Puts the platform into maintenance mode.
     */
    public void enableMaintenanceMode(String message) {
        this.isMaintenanceMode = true;
        this.maintenanceMessage = message;
        this.markAsModified();
    }
    
    /**
     * Takes the platform out of maintenance mode.
     */
    public void disableMaintenanceMode() {
        this.isMaintenanceMode = false;
        this.maintenanceMessage = null;
        this.markAsModified();
    }
    
    /**
     * Updates the platform version.
     */
    public void updateVersion(String newVersion) {
        String validatedVersion = validatePlatformVersion(newVersion);
        if (!this.platformVersion.equals(validatedVersion)) {
            this.platformVersion = validatedVersion;
            this.markAsModified();
        }
    }
    
    /**
     * Updates the API URLs.
     */
    public void updateApiUrls(String apiBaseUrl, String authUrl, String tokenUrl) {
        String validatedApiBaseUrl = validateUrl(apiBaseUrl, "apiBaseUrl");
        String validatedAuthUrl = validateUrl(authUrl, "authUrl");
        String validatedTokenUrl = validateUrl(tokenUrl, "tokenUrl");
        
        boolean changed = false;
        if (!this.apiBaseUrl.equals(validatedApiBaseUrl)) {
            this.apiBaseUrl = validatedApiBaseUrl;
            changed = true;
        }
        if (!this.authUrl.equals(validatedAuthUrl)) {
            this.authUrl = validatedAuthUrl;
            changed = true;
        }
        if (!this.tokenUrl.equals(validatedTokenUrl)) {
            this.tokenUrl = validatedTokenUrl;
            changed = true;
        }
        
        if (changed) {
            this.markAsModified();
        }
    }
    
    /**
     * Updates the platform features.
     */
    public void updateFeatures(PlatformFeatures newFeatures) {
        PlatformFeatures validatedFeatures = validateFeatures(newFeatures);
        if (!this.features.equals(validatedFeatures)) {
            this.features = validatedFeatures;
            this.markAsModified();
        }
    }
    
    /**
     * Updates the rate limits.
     */
    public void updateRateLimits(RateLimits newRateLimits) {
        RateLimits validatedRateLimits = validateRateLimits(newRateLimits);
        if (!this.rateLimits.equals(validatedRateLimits)) {
            this.rateLimits = validatedRateLimits;
            this.markAsModified();
        }
    }
    
    /**
     * Updates the API status after a health check.
     */
    public void updateApiStatus(String status) {
        if (status == null || status.trim().isEmpty()) {
            throw new IllegalArgumentException("API status cannot be null or empty");
        }
        
        String newStatus = status.trim().toUpperCase();
        if (!this.apiStatus.equals(newStatus)) {
            this.apiStatus = newStatus;
            this.lastApiCheck = LocalDateTime.now();
            this.markAsModified();
        }
    }
    
    /**
     * Updates the priority for display ordering.
     */
    public void updatePriority(Integer newPriority) {
        Integer validatedPriority = validatePriority(newPriority);
        if (!Objects.equals(this.priority, validatedPriority)) {
            this.priority = validatedPriority;
            this.markAsModified();
        }
    }
    
    /**
     * Checks if the platform is available for use.
     */
    public boolean isAvailable() {
        return isActive && !isMaintenanceMode;
    }
    
    /**
     * Checks if a specific feature is supported by this platform.
     */
    public boolean supportsFeature(String featureName) {
        return features.supportsFeature(featureName);
    }
    
    /**
     * Checks if an image format is supported by this platform.
     */
    public boolean supportsImageFormat(String format) {
        return features.supportsImageFormat(format);
    }
    
    /**
     * Checks if a video format is supported by this platform.
     */
    public boolean supportsVideoFormat(String format) {
        return features.supportsVideoFormat(format);
    }
    
    /**
     * Checks if a request would exceed the platform's rate limits.
     */
    public boolean wouldExceedRateLimit(String limitType, int currentCount) {
        return rateLimits.wouldExceedLimit(limitType, currentCount);
    }
    
    // Getters
    public SocialPlatform getPlatform() { return platform; }
    public String getPlatformName() { return platformName; }
    public String getPlatformVersion() { return platformVersion; }
    public String getApiBaseUrl() { return apiBaseUrl; }
    public String getAuthUrl() { return authUrl; }
    public String getTokenUrl() { return tokenUrl; }
    public PlatformFeatures getFeatures() { return features; }
    public RateLimits getRateLimits() { return rateLimits; }
    public boolean isActive() { return isActive; }
    public boolean isMaintenanceMode() { return isMaintenanceMode; }
    public String getMaintenanceMessage() { return maintenanceMessage; }
    public LocalDateTime getLastApiCheck() { return lastApiCheck; }
    public String getApiStatus() { return apiStatus; }
    public String getIconUrl() { return iconUrl; }
    public String getBrandColor() { return brandColor; }
    public String getDocumentationUrl() { return documentationUrl; }
    public String getSupportEmail() { return supportEmail; }
    public Integer getPriority() { return priority; }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        if (!super.equals(o)) return false;
        SocialNetwork that = (SocialNetwork) o;
        return platform == that.platform;
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), platform);
    }
    
    @Override
    public String toString() {
        return "SocialNetwork{" +
               "id=" + getId() +
               ", platform=" + platform +
               ", platformName='" + platformName + '\'' +
               ", platformVersion='" + platformVersion + '\'' +
               ", isActive=" + isActive +
               ", isMaintenanceMode=" + isMaintenanceMode +
               ", apiStatus='" + apiStatus + '\'' +
               ", priority=" + priority +
               '}';
    }
}
