namespace WalletService.Domain.AggregatesModel.WalletAggregate;

using WalletService.Domain.SeedWork;

/// <summary>
/// EN: Currency type enumeration with exchange rate capabilities.
/// VI: Enumeration loại tiền tệ với khả năng quy đổi tỷ giá.
/// </summary>
/// <remarks>
/// EN: PPoint is treated as a currency type to enable seamless exchange with other currencies.
/// VI: PPoint được coi như một loại tiền tệ để cho phép quy đổi liền mạch với các tiền tệ khác.
/// </remarks>
public class CurrencyType : Enumeration
{
    /// <summary>
    /// EN: Vietnamese Dong - base currency.
    /// VI: Đồng Việt Nam - tiền tệ cơ sở.
    /// </summary>
    public static CurrencyType VND = new(1, nameof(VND), "Vietnamese Dong", 1m);

    /// <summary>
    /// EN: US Dollar.
    /// VI: Đô la Mỹ.
    /// </summary>
    public static CurrencyType USD = new(2, nameof(USD), "US Dollar", 25000m);

    /// <summary>
    /// EN: Loyalty points - exchangeable with currency.
    /// VI: Điểm thưởng - có thể quy đổi với tiền tệ.
    /// </summary>
    public static CurrencyType PPoint = new(3, nameof(PPoint), "Loyalty Points", 1000m);

    /// <summary>
    /// EN: Display name of the currency.
    /// VI: Tên hiển thị của loại tiền tệ.
    /// </summary>
    public string DisplayName { get; private set; }

    /// <summary>
    /// EN: Base exchange rate to VND (1 unit of this currency = X VND).
    /// VI: Tỷ giá cơ sở quy đổi sang VND (1 đơn vị tiền này = X VND).
    /// </summary>
    /// <remarks>
    /// EN: VND = 1, USD = 25000 (1 USD = 25000 VND), PPoint = 1000 (1 PPoint = 1000 VND).
    /// VI: VND = 1, USD = 25000 (1 USD = 25000 VND), PPoint = 1000 (1 PPoint = 1000 VND).
    /// </remarks>
    public decimal BaseExchangeRate { get; private set; }

    protected CurrencyType() : base(0, "Unknown")
    {
        DisplayName = "Unknown";
        BaseExchangeRate = 0;
    }

    public CurrencyType(int id, string name, string displayName, decimal baseExchangeRate) 
        : base(id, name)
    {
        DisplayName = displayName;
        BaseExchangeRate = baseExchangeRate;
    }

    /// <summary>
    /// EN: Calculate exchange rate from this currency to another.
    /// VI: Tính tỷ giá quy đổi từ loại tiền này sang loại khác.
    /// </summary>
    /// <param name="toCurrency">Target currency / Tiền tệ đích</param>
    /// <returns>Exchange rate / Tỷ giá quy đổi</returns>
    public decimal GetExchangeRateTo(CurrencyType toCurrency)
    {
        if (toCurrency.BaseExchangeRate == 0)
            throw new InvalidOperationException("Cannot exchange to currency with zero base rate");

        return BaseExchangeRate / toCurrency.BaseExchangeRate;
    }

    /// <summary>
    /// EN: Convert amount from this currency to another.
    /// VI: Quy đổi số tiền từ loại tiền này sang loại khác.
    /// </summary>
    public decimal ConvertTo(decimal amount, CurrencyType toCurrency)
    {
        var rate = GetExchangeRateTo(toCurrency);
        return amount * rate;
    }

    /// <summary>
    /// EN: Check if this is a points-based currency.
    /// VI: Kiểm tra xem đây có phải là loại tiền dựa trên điểm không.
    /// </summary>
    public bool IsPointsBased => Id == PPoint.Id;

    /// <summary>
    /// EN: Check if this is a fiat currency.
    /// VI: Kiểm tra xem đây có phải là tiền pháp định không.
    /// </summary>
    public bool IsFiatCurrency => Id == VND.Id || Id == USD.Id;
}
