using Grand.Business.Core.Enums.Checkout;
using Grand.Business.Core.Utilities.Checkout;
using Grand.Domain.Customers;
using Grand.Domain.Orders;
using Grand.Domain.Payments;

namespace Grand.Business.Core.Interfaces.Checkout.Payments;

/// <summary>
///     Payment service interface
/// </summary>
public interface IPaymentService
{
    /// <summary>
    ///     Load active payment methods
    /// </summary>
    /// <param name="customer">Customer</param>
    /// <param name="storeId">Store ident</param>
    /// <param name="filterByCountryId">Specified country</param>
    /// <returns>Payment methods</returns>
    Task<IList<IPaymentProvider>> LoadActivePaymentMethods(Customer customer = null, string storeId = "",
        string filterByCountryId = "");

    /// <summary>
    ///     Load payment provider by system name
    /// </summary>
    /// <param name="systemName">System name</param>
    /// <returns>Found payment provider</returns>
    IPaymentProvider LoadPaymentMethodBySystemName(string systemName);

    /// <summary>
    ///     Load all payment providers
    /// </summary>
    /// <param name="storeId">Store ident</param>
    /// <param name="customer">Customer</param>
    /// <param name="filterByCountryId">Specified country</param>
    /// <returns>Payment providers</returns>
    IList<IPaymentProvider> LoadAllPaymentMethods(Customer customer = null, string storeId = "",
        string filterByCountryId = "");

    /// <summary>
    ///     Gets a list of country identifiers in which a certain payment method is now allowed
    /// </summary>
    /// <param name="paymentMethod">Payment method</param>
    /// <returns>A list of country identifiers</returns>
    IList<string> GetRestrictedCountryIds(IPaymentProvider paymentMethod);

    /// <summary>
    ///     Gets a list of shipping identifiers in which a certain payment method is now allowed
    /// </summary>
    /// <param name="paymentMethod">Payment method</param>
    /// <returns>A list of role identifiers</returns>
    IList<string> GetRestrictedShippingIds(IPaymentProvider paymentMethod);

    /// <summary>
    ///     Saves a list of country identifiers in which a certain payment method is now allowed
    /// </summary>
    /// <param name="paymentMethod">Payment method</param>
    /// <param name="countryIds">A list of country identifiers</param>
    Task SaveRestrictedCountryIds(IPaymentProvider paymentMethod, List<string> countryIds);

    /// <summary>
    ///     Saves a list of shipping identifiers in which a certain payment method is now allowed
    /// </summary>
    /// <param name="paymentMethod">Payment method</param>
    /// <param name="shippingIds">A list of shipping identifiers</param>
    Task SaveRestrictedShippingIds(IPaymentProvider paymentMethod, List<string> shippingIds);

    /// <summary>
    ///     Process a payment
    /// </summary>
    /// <param name="paymentTransaction">Payment transaction</param>
    /// <returns>Process payment result</returns>
    Task<ProcessPaymentResult> ProcessPayment(PaymentTransaction paymentTransaction);

    /// <summary>
    ///     Post process payment
    /// </summary>
    /// <param name="paymentTransaction">Payment transaction</param>
    Task PostProcessPayment(PaymentTransaction paymentTransaction);

    /// <summary>
    ///     Post redirect payment (used by payment gateways that redirecting to a another URL)
    /// </summary>
    /// <param name="paymentTransaction">Payment transaction</param>
    Task PostRedirectPayment(PaymentTransaction paymentTransaction);

    /// <summary>
    ///     Gets a value indicating whether customers can complete a payment after order is placed but not completed (for
    ///     redirection payment methods)
    /// </summary>
    /// <param name="paymentTransaction">Payment transaction</param>
    /// <returns>Result</returns>
    Task<bool> CanRePostRedirectPayment(PaymentTransaction paymentTransaction);

    /// <summary>
    ///     Gets an additional handling fee of a payment method
    /// </summary>
    /// <param name="cart">Shopping cart</param>
    /// <param name="paymentMethodSystemName">Payment method system name</param>
    /// <returns>Additional handling fee</returns>
    Task<double> GetAdditionalHandlingFee(IList<ShoppingCartItem> cart, string paymentMethodSystemName);

    /// <summary>
    ///     Gets a value indicating whether capture is supported by payment method
    /// </summary>
    /// <param name="paymentMethodSystemName">Payment method system name</param>
    /// <returns>A value indicating whether capture is supported</returns>
    Task<bool> SupportCapture(string paymentMethodSystemName);

    /// <summary>
    ///     Captures payment
    /// </summary>
    /// <param name="paymentTransaction">Payment transaction</param>
    /// <returns>Capture payment result</returns>
    Task<CapturePaymentResult> Capture(PaymentTransaction paymentTransaction);

    /// <summary>
    ///     Gets a value indicating whether partial refund is supported by payment method
    /// </summary>
    /// <param name="paymentMethodSystemName">Payment method system name</param>
    /// <returns>A value indicating whether partial refund is supported</returns>
    Task<bool> SupportPartiallyRefund(string paymentMethodSystemName);

    /// <summary>
    ///     Gets a value indicating whether refund is supported by payment method
    /// </summary>
    /// <param name="paymentMethodSystemName">Payment method system name</param>
    /// <returns>A value indicating whether refund is supported</returns>
    Task<bool> SupportRefund(string paymentMethodSystemName);

    /// <summary>
    ///     Refunds a payment
    /// </summary>
    /// <param name="refundPaymentRequest">Request</param>
    /// <returns>Result</returns>
    Task<RefundPaymentResult> Refund(RefundPaymentRequest refundPaymentRequest);

    /// <summary>
    ///     Gets a value indicating whether void is supported by payment method
    /// </summary>
    /// <param name="paymentMethodSystemName">Payment method system name</param>
    /// <returns>A value indicating whether void is supported</returns>
    Task<bool> SupportVoid(string paymentMethodSystemName);

    /// <summary>
    ///     Voids a payment
    /// </summary>
    /// <param name="paymentTransaction">Payment transaction</param>
    /// <returns>Result</returns>
    Task<VoidPaymentResult> Void(PaymentTransaction paymentTransaction);

    /// <summary>
    ///     Cancel payment
    /// </summary>
    /// <param name="paymentTransaction"></param>
    /// <returns></returns>
    Task CancelPayment(PaymentTransaction paymentTransaction);

    /// <summary>
    ///     Gets a payment method type
    /// </summary>
    /// <param name="paymentMethodSystemName">Payment method system name</param>
    /// <returns>A payment method type</returns>
    PaymentMethodType GetPaymentMethodType(string paymentMethodSystemName);
}