using Grand.Business.Core.Utilities.System;
using Grand.Domain;
using Grand.Domain.Catalog;
using Grand.Domain.Payments;
using Grand.Domain.Shipping;

namespace Grand.Business.Core.Interfaces.System.Reports;

/// <summary>
///     Order report service interface
/// </summary>
public interface IOrderReportService
{
    /// <summary>
    ///     Get "order by country" report
    /// </summary>
    /// <param name="storeId">Store identifier; "" to load all records</param>
    /// <param name="vendorId">Vendor identifier; "" to load all records</param>
    /// <param name="os">Order status</param>
    /// <param name="ps">Payment status</param>
    /// <param name="ss">Shipping status</param>
    /// <param name="startTimeUtc">Start date</param>
    /// <param name="endTimeUtc">End date</param>
    /// <returns>Result</returns>
    Task<IList<OrderByCountryReportLine>> GetCountryReport(string storeId = "",
        string vendorId = "", int? os = null,
        PaymentStatus? ps = null, ShippingStatus? ss = null,
        DateTime? startTimeUtc = null, DateTime? endTimeUtc = null);


    /// <summary>
    ///     Get "order by time" report
    /// </summary>
    /// <param name="storeId">Store identifier; "" to load all records</param>
    /// <param name="startTimeUtc">Start date</param>
    /// <param name="endTimeUtc">End date</param>
    /// <returns>Result</returns>
    Task<IList<OrderByTimeReportLine>> GetOrderByTimeReport(string storeId = "", DateTime? startTimeUtc = null,
        DateTime? endTimeUtc = null);

    /// <summary>
    ///     Get order average report
    /// </summary>
    /// <param name="storeId">Store identifier</param>
    /// <param name="customerId">Customer identifier</param>
    /// <param name="vendorId">Vendor identifier</param>
    /// <param name="salesEmployeeId">Sales employee identifier</param>
    /// <param name="billingCountryId">Billing country identifier</param>
    /// <param name="orderId">Order identifier</param>
    /// <param name="paymentMethodSystemName">Payment method system name; null to load all records</param>
    /// <param name="os">Order status</param>
    /// <param name="ps">Payment status</param>
    /// <param name="ss">Shipping status</param>
    /// <param name="startTimeUtc">Start date</param>
    /// <param name="endTimeUtc">End date</param>
    /// <param name="billingEmail">Billing email. Leave empty to load all records.</param>
    /// <param name="billingLastName">Billing last name. Leave empty to load all records.</param>
    /// <param name="ignoreCancelledOrders">A value indicating whether to ignore cancelled orders</param>
    /// <param name="tagId">Tag ident</param>
    /// <returns>Result</returns>
    Task<OrderAverageReportLine> GetOrderAverageReportLine(string storeId = "",
        string customerId = "", string vendorId = "", string salesEmployeeId = "",
        string billingCountryId = "", string orderId = "", string paymentMethodSystemName = null,
        int? os = null, PaymentStatus? ps = null, ShippingStatus? ss = null,
        DateTime? startTimeUtc = null, DateTime? endTimeUtc = null,
        string billingEmail = null, string billingLastName = "",
        bool ignoreCancelledOrders = false,
        string tagId = null);


    /// <summary>
    ///     Get order average report
    /// </summary>
    /// <param name="storeId">Store identifier</param>
    /// <param name="os">Order status</param>
    /// <returns>Result</returns>
    Task<OrderAverageReportLineSummary> OrderAverageReport(string storeId, int os);

    /// <summary>
    ///     Get best sellers report
    /// </summary>
    /// <param name="storeId">Store identifier; "" to load all records</param>
    /// <param name="vendorId">Vendor identifier; "" to load all records</param>
    /// <param name="createdFromUtc">Order created date from (UTC); null to load all records</param>
    /// <param name="createdToUtc">Order created date to (UTC); null to load all records</param>
    /// <param name="os">Order status; null to load all records</param>
    /// <param name="ps">Order payment status; null to load all records</param>
    /// <param name="ss">Shipping status; null to load all records</param>
    /// <param name="billingCountryId">Billing country identifier; "" to load all records</param>
    /// <param name="orderBy">1 - order by quantity, 2 - order by total amount</param>
    /// <param name="pageIndex">Page index</param>
    /// <param name="pageSize">Page size</param>
    /// <param name="showHidden">A value indicating whether to show hidden records</param>
    /// <returns>Result</returns>
    Task<IPagedList<BestsellersReportLine>> BestSellersReport(
        string storeId = "", string vendorId = "",
        DateTime? createdFromUtc = null, DateTime? createdToUtc = null,
        int? os = null, PaymentStatus? ps = null, ShippingStatus? ss = null,
        string billingCountryId = "",
        int orderBy = 1,
        int pageIndex = 0, int pageSize = int.MaxValue,
        bool showHidden = false);


    /// <summary>
    ///     Gets a report of orders in the last days
    /// </summary>
    /// <param name="days">Orders in the last days</param>
    /// <param name="storeId">Store ident</param>
    /// <param name="salesEmployeeId">Sales employee ident</param>
    /// <returns>ReportPeriodOrder</returns>
    Task<ReportPeriodOrder> GetOrderPeriodReport(int days, string storeId = "", string salesEmployeeId = "");

    /// <summary>
    ///     Gets a list of products (identifiers) purchased by other customers who purchased a specified product
    /// </summary>
    /// <param name="storeId">Store identifier</param>
    /// <param name="productId">Product identifier</param>
    /// <param name="recordsToReturn">Records to return</param>
    /// <param name="showHidden">A value indicating whether to show hidden records</param>
    /// <returns>Products</returns>
    Task<string[]> GetAlsoPurchasedProductsIds(string storeId, string productId,
        int recordsToReturn = 5, bool showHidden = false);

    /// <summary>
    ///     Gets a list of products that were never sold
    /// </summary>
    /// <param name="storeId">Store identifier</param>
    /// <param name="vendorId">Vendor identifier</param>
    /// <param name="createdFromUtc">Order created date from (UTC); null to load all records</param>
    /// <param name="createdToUtc">Order created date to (UTC); null to load all records</param>
    /// <param name="pageIndex">Page index</param>
    /// <param name="pageSize">Page size</param>
    /// <param name="showHidden">A value indicating whether to show hidden records</param>
    /// <returns>Products</returns>
    Task<IPagedList<Product>> ProductsNeverSold(string storeId = "", string vendorId = "",
        DateTime? createdFromUtc = null, DateTime? createdToUtc = null,
        int pageIndex = 0, int pageSize = int.MaxValue, bool showHidden = false);
}