package com.social.media.domain.shared.enums;

/**
 * Enumeration of post statuses throughout their lifecycle.
 * 
 * This enum defines the possible states a post can be in from creation
 * to archival in the Social Media Manager platform.
 * 
 * @author Social Media Manager Team
 * @version 2.0
 * @since 2025-01-01
 */
public enum PostStatus {
    
    /**
     * Post is in draft state.
     * Post is being created or edited and is not ready for publishing.
     */
    DRAFT("Draft", "Post is being created or edited", false, true),
    
    /**
     * Post is scheduled for future publication.
     * Post is ready and will be automatically published at the scheduled time.
     */
    SCHEDULED("Scheduled", "Post is scheduled for future publication", false, true),
    
    /**
     * Post is currently being published.
     * Post is in the process of being published to social media platforms.
     */
    PUBLISHING("Publishing", "Post is currently being published", false, false),
    
    /**
     * Post has been successfully published.
     * Post is live on the target social media platforms.
     */
    PUBLISHED("Published", "Post has been successfully published", true, false),
    
    /**
     * Post publication failed.
     * There was an error during the publishing process.
     */
    FAILED("Failed", "Post publication failed", false, true),
    
    /**
     * Post has been archived.
     * Post is no longer active but preserved for historical purposes.
     */
    ARCHIVED("Archived", "Post has been archived", true, false);
    
    private final String displayName;
    private final String description;
    private final boolean isFinal;
    private final boolean canBeEdited;
    
    PostStatus(String displayName, String description, boolean isFinal, boolean canBeEdited) {
        this.displayName = displayName;
        this.description = description;
        this.isFinal = isFinal;
        this.canBeEdited = canBeEdited;
    }
    
    /**
     * Gets the human-readable display name of the status.
     * 
     * @return the display name
     */
    public String getDisplayName() {
        return displayName;
    }
    
    /**
     * Gets the description of what this status means.
     * 
     * @return the description
     */
    public String getDescription() {
        return description;
    }
    
    /**
     * Checks if this is a final status (cannot transition to other statuses).
     * 
     * @return true if this is a final status
     */
    public boolean isFinal() {
        return isFinal;
    }
    
    /**
     * Checks if the post can be edited in this status.
     * 
     * @return true if the post can be edited
     */
    public boolean canBeEdited() {
        return canBeEdited;
    }
    
    /**
     * Checks if the post can be published from this status.
     * 
     * @return true if the post can be published
     */
    public boolean canBePublished() {
        return switch (this) {
            case DRAFT, FAILED -> true;
            case SCHEDULED, PUBLISHING, PUBLISHED, ARCHIVED -> false;
        };
    }
    
    /**
     * Checks if the post can be scheduled from this status.
     * 
     * @return true if the post can be scheduled
     */
    public boolean canBeScheduled() {
        return switch (this) {
            case DRAFT, FAILED -> true;
            case SCHEDULED, PUBLISHING, PUBLISHED, ARCHIVED -> false;
        };
    }
    
    /**
     * Checks if the post can be deleted from this status.
     * 
     * @return true if the post can be deleted
     */
    public boolean canBeDeleted() {
        return switch (this) {
            case DRAFT, SCHEDULED, FAILED, ARCHIVED -> true;
            case PUBLISHING, PUBLISHED -> false; // Publishing/Published posts should be archived instead
        };
    }
    
    /**
     * Checks if the post can be archived from this status.
     * 
     * @return true if the post can be archived
     */
    public boolean canBeArchived() {
        return switch (this) {
            case PUBLISHED -> true;
            case DRAFT, SCHEDULED, PUBLISHING, FAILED, ARCHIVED -> false;
        };
    }
    
    /**
     * Checks if the post requires attention (failed, etc.).
     * 
     * @return true if the post needs attention
     */
    public boolean needsAttention() {
        return this == FAILED;
    }
    
    /**
     * Gets the possible status transitions from the current status.
     * 
     * @return array of possible next statuses
     */
    public PostStatus[] getPossibleTransitions() {
        return switch (this) {
            case DRAFT -> new PostStatus[]{SCHEDULED, PUBLISHED, FAILED};
            case SCHEDULED -> new PostStatus[]{DRAFT, PUBLISHING, FAILED};
            case PUBLISHING -> new PostStatus[]{PUBLISHED, FAILED};
            case PUBLISHED -> new PostStatus[]{ARCHIVED};
            case FAILED -> new PostStatus[]{DRAFT, SCHEDULED, PUBLISHED};
            case ARCHIVED -> new PostStatus[]{}; // Terminal state
        };
    }
    
    /**
     * Checks if transition to the target status is allowed.
     * 
     * @param targetStatus the status to transition to
     * @return true if the transition is allowed
     */
    public boolean canTransitionTo(PostStatus targetStatus) {
        if (targetStatus == null || targetStatus == this) {
            return false;
        }
        
        PostStatus[] allowedTransitions = getPossibleTransitions();
        for (PostStatus allowed : allowedTransitions) {
            if (allowed == targetStatus) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Gets the color code associated with this status for UI purposes.
     * 
     * @return hex color code
     */
    public String getColorCode() {
        return switch (this) {
            case DRAFT -> "#6B7280"; // Gray
            case SCHEDULED -> "#3B82F6"; // Blue
            case PUBLISHING -> "#F59E0B"; // Amber
            case PUBLISHED -> "#10B981"; // Green
            case FAILED -> "#EF4444"; // Red
            case ARCHIVED -> "#8B5CF6"; // Purple
        };
    }
    
    /**
     * Gets the icon name associated with this status for UI purposes.
     * 
     * @return icon name
     */
    public String getIconName() {
        return switch (this) {
            case DRAFT -> "draft";
            case SCHEDULED -> "schedule";
            case PUBLISHING -> "publish";
            case PUBLISHED -> "published";
            case FAILED -> "error";
            case ARCHIVED -> "archive";
        };
    }
}
