using Grand.Business.Core.Utilities.Checkout;
using Grand.Domain.Common;
using Grand.Domain.Customers;
using Grand.Domain.Orders;
using Grand.Domain.Stores;

namespace Grand.Business.Core.Interfaces.Checkout.Shipping
{
    /// <summary>
    /// Shipping service interface
    /// </summary>
    public interface IShippingService
    {
        /// <summary>
        /// Load active Shipping rate  providers
        /// </summary>
        /// <param name="customer">Customer</param>
        /// <param name="storeId">Store ident</param>
        /// <param name="cart">Cart</param>
        /// <returns>Shipping rate  methods</returns>
        Task<IList<IShippingRateCalculationProvider>> LoadActiveShippingRateCalculationProviders(Customer customer = null, string storeId = "", IList<ShoppingCartItem> cart = null);

        /// <summary>
        /// Load Shipping rate  provider by system name
        /// </summary>
        /// <param name="systemName">System name</param>
        /// <returns>Found Shipping rate  provider</returns>
        IShippingRateCalculationProvider LoadShippingRateCalculationProviderBySystemName(string systemName);

        /// <summary>
        /// Load all Shipping rate  providers
        /// </summary>
        /// <param name="customer">Customer</param>
        /// <param name="storeId">Store ident</param>
        /// <returns>Shipping rate  providers</returns>
        IList<IShippingRateCalculationProvider> LoadAllShippingRateCalculationProviders(Customer customer = null, string storeId = "");

        /// <summary>
        /// Create shipment packages (requests) from shopping cart
        /// </summary>
        /// <param name="customer">Customer</param>
        /// <param name="cart">Shopping cart</param>
        /// <param name="shippingAddress">Shipping address</param>
        /// <param name="store">Store</param>
        /// <returns>Shipment packages</returns>
        Task<GetShippingOptionRequest> CreateShippingOptionRequests(Customer customer,
            IList<ShoppingCartItem> cart, Address shippingAddress, Store store);

        /// <summary>
        ///  Gets available shipping options
        /// </summary>
        /// <param name="customer"></param>
        /// <param name="cart">Shopping cart</param>
        /// <param name="shippingAddress">Shipping address</param>
        /// <param name="allowedShippingRateMethodSystemName">Filter by Shipping rate  method identifier; null to load shipping options of all Shipping rate  methods</param>
        /// <param name="store">Load records allowed only in a specified store; pass "" to load all records</param>
        /// <returns>Shipping options</returns>
        Task<GetShippingOptionResponse> GetShippingOptions(Customer customer, IList<ShoppingCartItem> cart, Address shippingAddress,
            string allowedShippingRateMethodSystemName = "", Store store = null);
    }
}
