using CMSMicroservice.Protobuf.Protos.Package;

namespace FrontOffice.Main.Utilities;

/// <summary>
/// Package data transfer object for UI display
/// </summary>
public record PackageDto(
    long Id,
    string Title,
    string Description,
    string ImageUrl,
    long Price,
    long ActivationFee = 0,
    double DiscountMultiplier = 0,
    double MagicWalletMultiplier = 0,
    long MagicWalletMaxDeposit = 0,
    long MagicWalletMaxCredit = 0,
    bool IsBasePackage = false,
    bool SupportsDayaPurchase = false,
    bool SupportsDirectPurchase = false)
{
    /// <summary>قیمت فرمت‌شده به تومان</summary>
    public string FormattedPrice => string.Format("{0:N0} تومان", Price);
}

/// <summary>
/// User's package purchase status
/// </summary>
public record UserPackageStatusDto(
    bool HasPurchasedPackage,
    string? PackageTitle,
    string? PurchaseMethod, // DayaLoan, DirectPurchase, or null
    bool IsClubMemberActive,
    long WalletBalance,
    bool CanActivateClubMembership,
    DateTime? PurchaseDate);

/// <summary>
/// Service for managing packages in FrontOffice
/// </summary>
public class PackageService
{
    private readonly CMSMicroservice.Protobuf.Protos.Package.PackageContract.PackageContractClient _client;

    public PackageService(CMSMicroservice.Protobuf.Protos.Package.PackageContract.PackageContractClient client)
    {
        _client = client;
    }

    /// <summary>
    /// Get all available packages
    /// </summary>
    public async Task<List<PackageDto>> GetAllPackagesAsync(CancellationToken ct = default)
    {
        try
        {
            var request = new GetCustomerPackagesRequest();

            var response = await _client.GetCustomerPackagesAsync(request, cancellationToken: ct);

            return response.Models
                .Select(m => new PackageDto(
                    m.Id,
                    m.Title,
                    m.Description,
                    m.ImagePath,
                    m.Price,
                    m.ActivationFee,
                    m.DiscountMultiplier,
                    m.MagicWalletMultiplier,
                    m.MagicWalletMaxDeposit,
                    m.MagicWalletMaxCredit,
                    m.IsBasePackage,
                    m.SupportsDayaPurchase,
                    m.SupportsDirectPurchase))
                .ToList();
        }
        catch (Exception ex)
        {
#if DEBUG
            Console.WriteLine($"Error fetching packages: {ex.Message}");
#endif
            return new List<PackageDto>();
        }
    }

    /// <summary>
    /// Get a single package by ID
    /// </summary>
    public async Task<PackageDto?> GetPackageByIdAsync(long id, CancellationToken ct = default)
    {
        try
        {
            var response = await _client.GetCustomerPackageDetailsAsync(
                new GetCustomerPackageDetailsRequest { PackageId = id },
                cancellationToken: ct);

            if (response == null) return null;

            return new PackageDto(
                response.Id,
                response.Title,
                response.Description,
                response.ImagePath,
                response.Price);
        }
        catch (Exception ex)
        {
#if DEBUG
            Console.WriteLine($"Error fetching package {id}: {ex.Message}");
#endif
            return null;
        }
    }

    /// <summary>
    /// Get user's package purchase status
    /// </summary>
    public async Task<UserPackageStatusDto> GetUserPackageStatusAsync(CancellationToken ct = default)
    {
        try
        {
            var response = await _client.GetUserPackageStatusAsync(
                new GetUserPackageStatusRequest(), cancellationToken: ct);

            return new UserPackageStatusDto(
                HasPurchasedPackage: response.HasPurchasedPackage,
                PackageTitle: null,
                PurchaseMethod: response.PackagePurchaseMethod,
                IsClubMemberActive: response.IsClubMemberActive,
                WalletBalance: response.WalletBalance,
                CanActivateClubMembership: response.CanActivateClubMembership,
                PurchaseDate: response.LastPurchaseDate?.ToDateTime());
        }
        catch
        {
            return new UserPackageStatusDto(
                HasPurchasedPackage: false,
                PackageTitle: null,
                PurchaseMethod: null,
                IsClubMemberActive: false,
                WalletBalance: 0,
                CanActivateClubMembership: false,
                PurchaseDate: null);
        }
    }
}
