namespace CMSMicroservice.Application.Common.Interfaces;

/// <summary>
/// Interface برای یکپارچه‌سازی با درگاه‌های پرداخت
/// </summary>
public interface IPaymentGatewayService
{
    /// <summary>
    /// شروع تراکنش پرداخت (ارسال به درگاه)
    /// </summary>
    /// <param name="request">اطلاعات تراکنش</param>
    /// <param name="cancellationToken"></param>
    /// <returns>URL درگاه برای هدایت کاربر + RefId تراکنش</returns>
    Task<PaymentInitiateResult> InitiatePaymentAsync(
        PaymentRequest request, 
        CancellationToken cancellationToken = default);
    
    /// <summary>
    /// تأیید پرداخت (بعد از بازگشت از درگاه)
    /// </summary>
    /// <param name="refId">شماره مرجع تراکنش</param>
    /// <param name="verificationToken">توکن تأیید از درگاه</param>
    /// <param name="cancellationToken"></param>
    /// <returns>وضعیت نهایی تراکنش</returns>
    Task<PaymentVerificationResult> VerifyPaymentAsync(
        string refId, 
        string verificationToken, 
        CancellationToken cancellationToken = default);
    
    /// <summary>
    /// تأیید پرداخت با مبلغ — برای درگاه‌هایی مثل زرین‌پال که مبلغ را در Verify نیاز دارند
    /// </summary>
    /// <param name="refId">شماره مرجع تراکنش (Authority در زرین‌پال)</param>
    /// <param name="verificationToken">توکن تأیید از درگاه (Status در زرین‌پال)</param>
    /// <param name="amountInToman">مبلغ تراکنش به تومان</param>
    /// <param name="cancellationToken"></param>
    /// <returns>وضعیت نهایی تراکنش</returns>
    Task<PaymentVerificationResult> VerifyPaymentAsync(
        string refId, 
        string verificationToken,
        decimal amountInToman,
        CancellationToken cancellationToken = default)
    {
        // ⚠️ هشدار: این پیاده‌سازی پیش‌فرض مبلغ را نادیده می‌گیرد.
        // درگاه‌هایی مثل زرین‌پال باید حتماً این متد را override کنند.
        throw new NotImplementedException(
            "درگاه پرداخت باید متد VerifyPaymentAsync با مبلغ را پیاده‌سازی کند");
    }
    
    /// <summary>
    /// فهرست Authority‌هایی که کاربر پرداخت کرده ولی سیستم هنوز Verify نکرده
    /// این متد برای Reconciliation در background job استفاده می‌شود.
    /// پیاده‌سازی پیش‌فرض لیست خالی برمی‌گرداند (درگاه‌هایی که این API را ندارند).
    /// </summary>
    Task<IReadOnlyList<string>> GetUnverifiedAuthoritiesAsync(
        CancellationToken cancellationToken = default)
    {
        return Task.FromResult<IReadOnlyList<string>>(Array.Empty<string>());
    }

    /// <summary>
    /// واریز مبلغ به حساب کاربر (برداشت از کیف پول)
    /// </summary>
    /// <param name="request">اطلاعات واریز</param>
    /// <param name="cancellationToken"></param>
    /// <returns>وضعیت واریز</returns>
    Task<PayoutResult> ProcessPayoutAsync(
        PayoutRequest request, 
        CancellationToken cancellationToken = default);
}

/// <summary>
/// درخواست شروع تراکنش پرداخت
/// </summary>
public class PaymentRequest
{
    /// <summary>
    /// مبلغ (تومان)
    /// </summary>
    public decimal Amount { get; set; }
    
    /// <summary>
    /// شناسه کاربر
    /// </summary>
    public long UserId { get; set; }
    
    /// <summary>
    /// شماره موبایل
    /// </summary>
    public string Mobile { get; set; } = string.Empty;
    
    /// <summary>
    /// شرح تراکنش
    /// </summary>
    public string Description { get; set; } = string.Empty;
    
    /// <summary>
    /// URL بازگشت بعد از پرداخت
    /// </summary>
    public string CallbackUrl { get; set; } = string.Empty;
}

/// <summary>
/// نتیجه شروع تراکنش
/// </summary>
public class PaymentInitiateResult
{
    /// <summary>
    /// موفق بودن درخواست
    /// </summary>
    public bool IsSuccess { get; set; }
    
    /// <summary>
    /// شماره مرجع تراکنش (RefId)
    /// </summary>
    public string? RefId { get; set; }
    
    /// <summary>
    /// URL درگاه برای هدایت کاربر
    /// </summary>
    public string? GatewayUrl { get; set; }
    
    /// <summary>
    /// پیام خطا (در صورت ناموفق بودن)
    /// </summary>
    public string? ErrorMessage { get; set; }
}

/// <summary>
/// نتیجه تأیید تراکنش
/// </summary>
public class PaymentVerificationResult
{
    /// <summary>
    /// موفق بودن تراکنش
    /// </summary>
    public bool IsSuccess { get; set; }
    
    /// <summary>
    /// شماره مرجع تراکنش
    /// </summary>
    public string RefId { get; set; } = string.Empty;
    
    /// <summary>
    /// کد پیگیری بانک
    /// </summary>
    public string? TrackingCode { get; set; }
    
    /// <summary>
    /// مبلغ تراکنش
    /// </summary>
    public decimal Amount { get; set; }
    
    /// <summary>
    /// پیام
    /// </summary>
    public string? Message { get; set; }
    
    /// <summary>
    /// شماره کارت ماسک‌شده (مثلاً 6037-****-****-1234)
    /// </summary>
    public string? CardPan { get; set; }
    
    /// <summary>
    /// هش کارت بانکی
    /// </summary>
    public string? CardHash { get; set; }
    
    /// <summary>
    /// کد وضعیت verify از درگاه (100=موفق، 101=تکراری)
    /// </summary>
    public int? VerificationCode { get; set; }
}

/// <summary>
/// درخواست واریز
/// </summary>
public class PayoutRequest
{
    /// <summary>
    /// مبلغ (تومان)
    /// </summary>
    public decimal Amount { get; set; }
    
    /// <summary>
    /// شناسه کاربر
    /// </summary>
    public long UserId { get; set; }
    
    /// <summary>
    /// شماره شبا
    /// </summary>
    public string Iban { get; set; } = string.Empty;
    
    /// <summary>
    /// نام صاحب حساب
    /// </summary>
    public string AccountHolderName { get; set; } = string.Empty;
    
    /// <summary>
    /// شرح واریز
    /// </summary>
    public string Description { get; set; } = string.Empty;
    
    /// <summary>
    /// شماره مرجع داخلی
    /// </summary>
    public string InternalRefId { get; set; } = string.Empty;
}

/// <summary>
/// نتیجه واریز
/// </summary>
public class PayoutResult
{
    /// <summary>
    /// موفق بودن واریز
    /// </summary>
    public bool IsSuccess { get; set; }
    
    /// <summary>
    /// شماره مرجع تراکنش بانکی
    /// </summary>
    public string? BankRefId { get; set; }
    
    /// <summary>
    /// کد پیگیری
    /// </summary>
    public string? TrackingCode { get; set; }
    
    /// <summary>
    /// پیام
    /// </summary>
    public string? Message { get; set; }
    
    /// <summary>
    /// زمان پردازش
    /// </summary>
    public DateTime ProcessedAt { get; set; }
}
