namespace Managing.Core.Exceptions;

/// <summary>
/// Exception thrown when validation fails (maps to 400 Bad Request)
/// </summary>
public class ValidationException : Exception
{
    public ValidationException(string message) : base(message)
    {
    }

    public ValidationException(string message, Exception innerException) : base(message, innerException)
    {
    }
}

/// <summary>
/// Exception thrown when a resource is not found (maps to 404 Not Found)
/// </summary>
public class NotFoundException : Exception
{
    public NotFoundException(string message) : base(message)
    {
    }

    public NotFoundException(string resourceType, string identifier)
        : base($"{resourceType} with identifier '{identifier}' was not found.")
    {
    }
}

/// <summary>
/// Exception thrown when the user does not have permission (maps to 403 Forbidden)
/// </summary>
public class ForbiddenException : Exception
{
    public ForbiddenException(string message) : base(message)
    {
    }

    public ForbiddenException() : base("You do not have permission to access this resource.")
    {
    }
}

/// <summary>
/// Exception thrown when there is a conflict with the current state (maps to 409 Conflict)
/// </summary>
public class ConflictException : Exception
{
    public ConflictException(string message) : base(message)
    {
    }
}

/// <summary>
/// Exception thrown when a rate limit is exceeded (maps to 429 Too Many Requests)
/// </summary>
public class RateLimitExceededException : Exception
{
    public RateLimitExceededException(string message) : base(message)
    {
    }

    public RateLimitExceededException() : base("Rate limit exceeded. Please try again later.")
    {
    }
}

/// <summary>
/// Exception thrown when an external service is unavailable (maps to 503 Service Unavailable)
/// </summary>
public class ServiceUnavailableException : Exception
{
    public ServiceUnavailableException(string message) : base(message)
    {
    }
}

/// <summary>
/// Exception thrown when there are insufficient funds or allowance for a transaction
/// This typically indicates the user needs to add more ETH for gas or approve token spending
/// </summary>
public class InsufficientFundsException : Exception
{
    /// <summary>
    /// The type of insufficient funds error
    /// </summary>
    public InsufficientFundsType ErrorType { get; }

    /// <summary>
    /// User-friendly message explaining what needs to be done
    /// </summary>
    public string UserMessage { get; }

    public InsufficientFundsException(string errorMessage, InsufficientFundsType errorType) 
        : base(errorMessage)
    {
        ErrorType = errorType;
        UserMessage = GetUserFriendlyMessage(errorType);
    }

    private static string GetUserFriendlyMessage(InsufficientFundsType errorType)
    {
        return errorType switch
        {
            InsufficientFundsType.InsufficientEth => 
                "❌ **Insufficient ETH for Gas Fees**\n" +
                "Your wallet doesn't have enough ETH to pay for transaction gas fees.\n" +
                "Please add ETH to your wallet and try again.",
            
            InsufficientFundsType.InsufficientAllowance => 
                "❌ **Insufficient Token Allowance**\n" +
                "The trading contract doesn't have permission to spend your tokens.\n" +
                "Please approve token spending in your wallet and try again.",
            
            InsufficientFundsType.InsufficientBalance => 
                "❌ **Insufficient Token Balance**\n" +
                "Your wallet doesn't have enough tokens for this trade.\n" +
                "Please add more tokens to your wallet and try again.",
            
            _ => "❌ **Transaction Failed**\n" +
                 "The transaction failed due to insufficient funds.\n" +
                 "Please check your wallet balance and try again."
        };
    }
}

/// <summary>
/// Types of insufficient funds errors
/// </summary>
public enum InsufficientFundsType
{
    /// <summary>
    /// Not enough ETH for gas fees
    /// </summary>
    InsufficientEth,
    
    /// <summary>
    /// Token allowance is insufficient (ERC20: transfer amount exceeds allowance)
    /// </summary>
    InsufficientAllowance,
    
    /// <summary>
    /// Token balance is insufficient
    /// </summary>
    InsufficientBalance,
    
    /// <summary>
    /// General insufficient funds error
    /// </summary>
    General
}