using System.Text.Json.Serialization;
using Managing.Domain.Accounts;

namespace Managing.Infrastructure.Evm.Models.Proxy
{
    /// <summary>
    /// Base response structure from the Web3Proxy API
    /// </summary>
    public class Web3ProxyResponse
    {
        /// <summary>
        /// Whether the operation was successful
        /// </summary>
        [JsonPropertyName("success")]
        public bool Success { get; set; }
        
        /// <summary>
        /// Error message if not successful
        /// </summary>
        [JsonPropertyName("error")]
        public string Error { get; set; }
    }

    /// <summary>
    /// Generic response with data payload
    /// </summary>
    /// <typeparam name="T">Type of data in the response</typeparam>
    public class Web3ProxyDataResponse<T> : Web3ProxyResponse
    {
        /// <summary>
        /// The response data if successful
        /// </summary>
        [JsonPropertyName("data")]
        public T Data { get; set; }
    }

    /// <summary>
    /// Base error response from Web3Proxy API
    /// </summary>
    public class Web3ProxyError
    {
        /// <summary>
        /// Error type
        /// </summary>
        [JsonPropertyName("type")]
        public string Type { get; set; }
        
        /// <summary>
        /// Error message
        /// </summary>
        [JsonPropertyName("message")]
        public string Message { get; set; }
        
        /// <summary>
        /// Error stack trace
        /// </summary>
        [JsonPropertyName("stack")]
        public string Stack { get; set; }
        
        /// <summary>
        /// HTTP status code (added by service)
        /// </summary>
        [JsonIgnore]
        public int StatusCode { get; set; }
        
        /// <summary>
        /// Returns a formatted error message with type and message
        /// </summary>
        public string FormattedMessage => $"{Type}: {Message}";
    }

    /// <summary>
    /// API response containing error details
    /// </summary>
    public class Web3ProxyErrorResponse : Web3ProxyResponse
    {
        /// <summary>
        /// Error details (for structured errors)
        /// </summary>
        [JsonPropertyName("err")]
        public Web3ProxyError ErrorDetails { get; set; }
    }

    /// <summary>
    /// Represents a Web3Proxy API exception with error details
    /// </summary>
    public class Web3ProxyException : Exception
    {
        /// <summary>
        /// The error details from the API
        /// </summary>
        public Web3ProxyError Error { get; }
        
        /// <summary>
        /// Simple error message from API
        /// </summary>
        public string ApiErrorMessage { get; }

        /// <summary>
        /// Creates a new Web3ProxyException from a structured error
        /// </summary>
        /// <param name="error">The error details</param>
        public Web3ProxyException(Web3ProxyError error) 
            : base(error?.Message ?? "An error occurred in the Web3Proxy API")
        {
            Error = error;
        }
        
        /// <summary>
        /// Creates a new Web3ProxyException from a simple error message
        /// </summary>
        /// <param name="errorMessage">The error message</param>
        public Web3ProxyException(string errorMessage)
            : base(errorMessage)
        {
            ApiErrorMessage = errorMessage;
        }

        /// <summary>
        /// Creates a new Web3ProxyException with a custom message
        /// </summary>
        /// <param name="message">Custom error message</param>
        /// <param name="error">The error details</param>
        public Web3ProxyException(string message, Web3ProxyError error) 
            : base(message)
        {
            Error = error;
        }
    }

    /// <summary>
    /// Response for token sending operations
    /// </summary>
    public class Web3ProxyTokenSendResponse : Web3ProxyResponse
    {
        /// <summary>
        /// Transaction hash if successful
        /// </summary>
        [JsonPropertyName("hash")]
        public string Hash { get; set; }
    }

    /// <summary>
    /// Response for wallet balance operations
    /// </summary>
    public class Web3ProxyBalanceResponse : Web3ProxyResponse
    {
        /// <summary>
        /// List of wallet balances if successful
        /// </summary>
        [JsonPropertyName("balances")]
        public List<Balance> Balances { get; set; }
    }
} 