package com.social.media.domain.shared.enums;

import java.math.BigDecimal;

/**
 * Enumeration of company subscription plans.
 * 
 * This enum defines the different subscription tiers available in the Social Media Manager
 * platform, each with different limits and capabilities.
 * 
 * @author Social Media Manager Team
 * @version 2.0
 * @since 2025-01-01
 */
public enum CompanyPlan {
    
    /**
     * Basic plan for small businesses and individuals.
     * Limited features suitable for simple social media management.
     */
    BASIC("Basic", "Basic plan for small businesses", 
          new BigDecimal("29.90"), 
          5,    // social accounts
          100,  // monthly posts
          5,    // users
          1),   // bots
    
    /**
     * Professional plan for growing businesses.
     * Enhanced features and higher limits for serious social media management.
     */
    PROFESSIONAL("Professional", "Professional plan for growing businesses", 
                 new BigDecimal("79.90"), 
                 15,   // social accounts
                 500,  // monthly posts
                 15,   // users
                 5),   // bots
    
    /**
     * Enterprise plan for large organizations.
     * Advanced features and high limits for enterprise-level social media management.
     */
    ENTERPRISE("Enterprise", "Enterprise plan for large organizations", 
               new BigDecimal("199.90"), 
               50,   // social accounts
               2000, // monthly posts
               50,   // users
               20),  // bots
    
    /**
     * Custom plan with negotiated limits and pricing.
     * Tailored for organizations with specific requirements.
     */
    CUSTOM("Custom", "Custom plan with negotiated terms", 
           BigDecimal.ZERO, // Price negotiated separately
           Integer.MAX_VALUE, // Unlimited or custom limits
           Integer.MAX_VALUE,
           Integer.MAX_VALUE,
           Integer.MAX_VALUE);
    
    private final String displayName;
    private final String description;
    private final BigDecimal monthlyPrice;
    private final int socialAccountsLimit;
    private final int monthlyPostsLimit;
    private final int usersLimit;
    private final int botsLimit;
    
    CompanyPlan(String displayName, String description, BigDecimal monthlyPrice,
                int socialAccountsLimit, int monthlyPostsLimit, int usersLimit, int botsLimit) {
        this.displayName = displayName;
        this.description = description;
        this.monthlyPrice = monthlyPrice;
        this.socialAccountsLimit = socialAccountsLimit;
        this.monthlyPostsLimit = monthlyPostsLimit;
        this.usersLimit = usersLimit;
        this.botsLimit = botsLimit;
    }
    
    /**
     * Gets the human-readable display name of the plan.
     * 
     * @return the display name
     */
    public String getDisplayName() {
        return displayName;
    }
    
    /**
     * Gets the description of the plan.
     * 
     * @return the description
     */
    public String getDescription() {
        return description;
    }
    
    /**
     * Gets the monthly price of the plan.
     * 
     * @return the monthly price
     */
    public BigDecimal getMonthlyPrice() {
        return monthlyPrice;
    }
    
    /**
     * Gets the limit of social accounts for this plan.
     * 
     * @return the social accounts limit
     */
    public int getSocialAccountsLimit() {
        return socialAccountsLimit;
    }
    
    /**
     * Gets the limit of monthly posts for this plan.
     * 
     * @return the monthly posts limit
     */
    public int getMonthlyPostsLimit() {
        return monthlyPostsLimit;
    }
    
    /**
     * Gets the limit of users for this plan.
     * 
     * @return the users limit
     */
    public int getUsersLimit() {
        return usersLimit;
    }
    
    /**
     * Gets the limit of bots for this plan.
     * 
     * @return the bots limit
     */
    public int getBotsLimit() {
        return botsLimit;
    }
    
    /**
     * Checks if this plan supports advanced analytics.
     * 
     * @return true if advanced analytics are supported
     */
    public boolean supportsAdvancedAnalytics() {
        return switch (this) {
            case PROFESSIONAL, ENTERPRISE, CUSTOM -> true;
            case BASIC -> false;
        };
    }
    
    /**
     * Checks if this plan supports automation features.
     * 
     * @return true if automation is supported
     */
    public boolean supportsAutomation() {
        return botsLimit > 0;
    }
    
    /**
     * Checks if this plan supports API access.
     * 
     * @return true if API access is supported
     */
    public boolean supportsApiAccess() {
        return switch (this) {
            case ENTERPRISE, CUSTOM -> true;
            case BASIC, PROFESSIONAL -> false;
        };
    }
    
    /**
     * Checks if this plan supports white-label features.
     * 
     * @return true if white-label is supported
     */
    public boolean supportsWhiteLabel() {
        return this == CUSTOM;
    }
    
    /**
     * Checks if this plan supports priority support.
     * 
     * @return true if priority support is included
     */
    public boolean supportsPrioritySupport() {
        return switch (this) {
            case ENTERPRISE, CUSTOM -> true;
            case BASIC, PROFESSIONAL -> false;
        };
    }
    
    /**
     * Gets the available upgrade paths from this plan.
     * 
     * @return array of plans that can be upgraded to
     */
    public CompanyPlan[] getUpgradePaths() {
        return switch (this) {
            case BASIC -> new CompanyPlan[]{PROFESSIONAL, ENTERPRISE, CUSTOM};
            case PROFESSIONAL -> new CompanyPlan[]{ENTERPRISE, CUSTOM};
            case ENTERPRISE -> new CompanyPlan[]{CUSTOM};
            case CUSTOM -> new CompanyPlan[]{}; // Already at the top
        };
    }
    
    /**
     * Checks if this plan can be upgraded to the target plan.
     * 
     * @param targetPlan the plan to upgrade to
     * @return true if the upgrade is possible
     */
    public boolean canUpgradeTo(CompanyPlan targetPlan) {
        if (targetPlan == null || targetPlan == this) {
            return false;
        }
        
        CompanyPlan[] upgradePaths = getUpgradePaths();
        for (CompanyPlan upgradePath : upgradePaths) {
            if (upgradePath == targetPlan) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Calculates the annual price with discount.
     * 
     * @param annualDiscountPercent the discount percentage for annual payment
     * @return the annual price with discount applied
     */
    public BigDecimal getAnnualPrice(int annualDiscountPercent) {
        if (this == CUSTOM) {
            return BigDecimal.ZERO; // Custom pricing
        }
        
        BigDecimal annualPrice = monthlyPrice.multiply(BigDecimal.valueOf(12));
        BigDecimal discount = annualPrice.multiply(BigDecimal.valueOf(annualDiscountPercent))
                                        .divide(BigDecimal.valueOf(100));
        
        return annualPrice.subtract(discount);
    }
}
