namespace Hims.Domain.Services
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;

    using Hims.Shared.UserModels;
    using Hims.Shared.UserModels.Inventory;

    using Shared.EntityModels;
    using Shared.UserModels.Filters;

    /// <summary>
    /// The InventoryService interface.
    /// </summary>
    public interface IInventoryService
    {
        /// <summary>
        /// The create unit async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CreateUnitAsync(LookupValueModel model);

        /// <summary>
        /// The create category async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CreateCategoryAsync(LookupValueModel model);

        /// <summary>
        /// The create rack async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CreateRackAsync(LookupValueModel model);

        /// <summary>
        /// The create gst async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CreateGstAsync(LookupValueModel model);

        /// <summary>
        /// The update lookup value async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> UpdateLookupValueAsync(LookupValueModel model);

        /// <summary>
        /// The delete lookup value async.
        /// </summary>
        /// <param name="lookupValueId">
        /// The lookup value id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> DeleteLookupValueAsync(int lookupValueId);

        /// <summary>
        /// The fetch lookup values.
        /// </summary>
        /// <param name="model">
        /// The lookup name.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<LookupValueModel>> FetchLookupValues(LookupValueModel model);

        /// <summary>
        /// The create inventory product.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CreateInventoryProduct(ProductModel model);

        /// <summary>
        /// The update inventory product.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> UpdateInventoryProduct(ProductModel model);

        /// <summary>
        /// The delete inventory product.
        /// </summary>
        /// <param name="inventoryProductId">
        /// The inventory product id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> DeleteInventoryProduct(int inventoryProductId);

        /// <summary>
        /// The fetch inventory product.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<ProductModel>> FetchInventoryProduct(ProductModel model);

        /// <summary>
        /// The add purchase bill async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> AddPurchaseBillAsync(InventoryPurchaseBillModel model);

        /// <summary>
        /// The fetch added purchase bill async.
        /// </summary>
        /// <param name="inventoryPurchaseHeaderId">
        /// The inventory purchase header id.
        /// </param>
        /// <param name="billNumber">
        /// The bill number.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<PurchaseBillModel>> FetchAddedPurchaseBillAsync(int? inventoryPurchaseHeaderId, string billNumber);

        /// <summary>
        /// The fetch inventory stocks.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<InventoryStockModel>> FetchInventoryStocks(InventoryStockModel model);

        /// <summary>
        /// The update inventory stocks.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> UpdateInventoryStocks(InventoryStockModel model);

        /// <summary>
        /// The fetch bill number.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<string> FetchBillNumber();

        /// <summary>
        /// The add return purchase bill async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> AddReturnPurchaseBillAsync(InventoryPurchaseReturnModel model);

        /// <summary>
        /// The fetch added return purchase bill async.
        /// </summary>
        /// <param name="inventoryPurchaseReturnHeaderId">
        /// The inventory purchase return header id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<InventoryPurchaseBillReturnModel>> FetchAddedReturnPurchaseBillAsync(int inventoryPurchaseReturnHeaderId);

        /// <summary>
        /// The fetch dashboard reorder level.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<InventoryDashboardModel>> FetchDashboardReorderLevel();

        /// <summary>
        /// The fetch dashboard expiry item.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<InventoryDashboardModel>> FetchDashboardExpiryItem();

        /// <summary>
        /// The fetch dashboard next month expiry item.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<InventoryDashboardModel>> FetchDashboardNextMonthExpiryItem();

        /// <summary>
        /// The fetch dashboard current month expire item.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<InventoryDashboardModel>> FetchDashboardCurrentMonthExpireItem();

        /// <summary>
        /// The fetch inventory product.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<ProductModel>> FetchInventoryProducts();

        /// <summary>
        /// The fetch phaemacy purchase bill.
        /// </summary>
        /// <param name="billNumber">
        /// The purchase header id.
        /// </param>
        /// <param name="type">
        /// The purchase type.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<PurchaseBillModel>> FetchInventoryReturnBill(string billNumber);

        /// <summary>
        /// Checks the product already already exists.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        Task<int> CheckProductAlreadyAlreadyExists(string name);

        /// <summary>
        /// Fetches the purchase bill.
        /// </summary>
        /// <param name="supplierId">The supplier identifier.</param>
        /// <param name="purchaseHeaderId">The purchase header identifier.</param>
        /// <param name="billNumber">The bill number.</param>
        /// <param name="locationId">The location identifier.</param>
        /// <returns></returns>
        Task<InventoryBillHeaderModel> FetchPurchaseBill(int? supplierId, int? purchaseHeaderId, string billNumber, int? locationId);

        /// <summary>
        /// Adds the inventory purchase bill asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        Task<int> AddInventoryPurchaseBillAsync(InventoryBillHeaderModel model);

        /// <summary>
        /// Fetches the existing batch numbers.
        /// </summary>
        /// <param name="inventoryProductId">The inventory product identifier.</param>
        /// <param name="locationId">The location identifier.</param>
        /// <returns></returns>
        Task<IEnumerable<string>> FetchExistingBatchNumbers(int inventoryProductId, int? locationId);

        /// <summary>
        /// Deletes the purchase bill item asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        Task<int> DeletePurchaseBillItemAsync(InventoryBillHeaderModel model);
    }
}
