using Grand.Domain;
using Grand.Domain.Orders;
using Grand.Domain.Payments;
using Grand.Domain.Shipping;

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

/// <summary>
///     Order service interface
/// </summary>
public interface IOrderService
{
    #region Orders items

    /// <summary>
    ///     Gets an order item
    /// </summary>
    /// <param name="orderItemGuid">Order item identifier</param>
    /// <returns>Order item</returns>
    Task<OrderItem> GetOrderItemByGuid(Guid orderItemGuid);

    #endregion

    #region Orders

    /// <summary>
    ///     Gets an order
    /// </summary>
    /// <param name="orderId">The order identifier</param>
    /// <returns>Order</returns>
    Task<Order> GetOrderById(string orderId);

    /// <summary>
    ///     Gets an order
    /// </summary>
    /// <param name="orderItemId">The order item identifier</param>
    /// <returns>Order</returns>
    Task<Order> GetOrderByOrderItemId(string orderItemId);

    /// <summary>
    ///     Gets an order
    /// </summary>
    /// <param name="orderNumber">The order number</param>
    /// <returns>Order</returns>
    Task<Order> GetOrderByNumber(int orderNumber);

    /// <summary>
    ///     Gets orders by code
    /// </summary>
    /// <param name="code">The order code</param>
    /// <returns>Order</returns>
    Task<IList<Order>> GetOrdersByCode(string code);

    /// <summary>
    ///     Get orders by identifiers
    /// </summary>
    /// <param name="orderIds">Order identifiers</param>
    /// <returns>Order</returns>
    Task<IList<Order>> GetOrdersByIds(string[] orderIds);

    /// <summary>
    ///     Gets an order
    /// </summary>
    /// <param name="orderGuid">The order identifier</param>
    /// <returns>Order</returns>
    Task<Order> GetOrderByGuid(Guid orderGuid);

    /// <summary>
    ///     Search orders
    /// </summary>
    /// <param name="storeId">Store identifier; null to load all orders</param>
    /// <param name="vendorId">Vendor identifier; null to load all orders</param>
    /// <param name="customerId">Customer identifier; null to load all orders</param>
    /// <param name="productId">Product identifier which was purchased in an order; 0 to load all orders</param>
    /// <param name="affiliateId">Affiliate identifier; 0 to load all orders</param>
    /// <param name="warehouseId">
    ///     Warehouse identifier, only orders with products from a specified warehouse will be loaded; 0
    ///     to load all orders
    /// </param>
    /// <param name="billingCountryId">Billing country identifier; 0 to load all orders</param>
    /// <param name="ownerId">Owner identifier</param>
    /// <param name="salesEmployeeId">Sales ident</param>
    /// <param name="paymentMethodSystemName">Payment method system name; null to load all records</param>
    /// <param name="createdFromUtc">Created date from (UTC); null to load all records</param>
    /// <param name="createdToUtc">Created date to (UTC); null to load all records</param>
    /// <param name="os">Order status; null to load all orders</param>
    /// <param name="ps">Order payment status; null to load all orders</param>
    /// <param name="ss">Order shipment status; null to load all orders</param>
    /// <param name="billingEmail">Billing email. Leave empty to load all records.</param>
    /// <param name="billingLastName"></param>
    /// <param name="orderGuid">
    ///     Search by order GUID (Global unique identifier) or part of GUID. Leave empty to load all
    ///     records.
    /// </param>
    /// <param name="orderCode">Search by order code.</param>
    /// <param name="pageIndex">Page index</param>
    /// <param name="pageSize">Page size</param>
    /// <param name="orderTagId">Order tag identifier</param>
    /// <returns>Orders</returns>
    Task<IPagedList<Order>> SearchOrders(string storeId = "",
        string vendorId = "", string customerId = "",
        string productId = "", string affiliateId = "", string warehouseId = "",
        string billingCountryId = "", string ownerId = "", string salesEmployeeId = "",
        string paymentMethodSystemName = null,
        DateTime? createdFromUtc = null, DateTime? createdToUtc = null,
        int? os = null, PaymentStatus? ps = null, ShippingStatus? ss = null,
        string billingEmail = null, string billingLastName = "", string orderGuid = null,
        string orderCode = null, int pageIndex = 0, int pageSize = int.MaxValue, string orderTagId = "");

    /// <summary>
    ///     Inserts an order
    /// </summary>
    /// <param name="order">Order</param>
    Task InsertOrder(Order order);

    /// <summary>
    ///     Updates the order
    /// </summary>
    /// <param name="order">The order</param>
    Task UpdateOrder(Order order);

    #endregion

    #region Order notes

    /// <summary>
    ///     Deletes an order note
    /// </summary>
    /// <param name="orderNote">The order note</param>
    Task DeleteOrderNote(OrderNote orderNote);

    /// <summary>
    ///     Insert an order note
    /// </summary>
    /// <param name="orderNote">The order note</param>
    Task InsertOrderNote(OrderNote orderNote);


    /// <summary>
    ///     Get order notes for order
    /// </summary>
    /// <param name="orderId">Order identifier</param>
    /// <returns>OrderNote</returns>
    Task<IList<OrderNote>> GetOrderNotes(string orderId);

    /// <summary>
    ///     Get order note by id
    /// </summary>
    /// <param name="orderNoteId">Order note identifier</param>
    /// <returns>OrderNote</returns>
    Task<OrderNote> GetOrderNote(string orderNoteId);


    /// <summary>
    ///     Cancel Expired UnPaid Orders
    /// </summary>
    /// <param name="expirationDateUtc">Date at which all unPaid  orders and has pending status Would be Canceled</param>
    Task CancelExpiredOrders(DateTime expirationDateUtc);

    #endregion
}