using Microsoft.AspNetCore.Mvc;
using Nop.Core;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Orders;
using Nop.Plugin.Misc.AuctionPlugin.Domains;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Dtos;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums;
using Nop.Services.Orders;

namespace Nop.Plugin.Misc.AuctionPlugin.Services;

/// <summary>
/// Store pickup point service interface
/// </summary>
public interface IAuctionService
{
    //decimal GetStepAmount(decimal currentPrice);
    Task<ResponseType> UpdateProductToAuctionStatusIfValidAsync(AuctionStatus newProductToAuctionStatus, Auction auction, ProductToAuctionMapping productToAuction, Customer customer, bool updateInDatabase = true);
    Task<(Auction auction, ProductToAuctionMapping productToAuction, ResponseType responseType)> GetAndUpdateProductToAuctionStatusIfValidAsync(int productToAuctionId, AuctionStatus newProductToAuctionStatus, Customer customer);
    Task ResetProductToAuction(ProductToAuctionMapping productToAuction, int? categoryId = null);
    Task UpdateProductCategoryIsFeaturedAsync(int productId, int? categoryId, bool isFeatured);
    bool IsValidRequestAuctionStatus(AuctionStatus newStatus, AuctionStatus oldStatus);

    /// <summary>
    /// Gets all bids
    /// </summary>
    /// <param name="customerId">The store identifier; pass 0 to load all records</param>
    /// <param name="pageIndex">Page index</param>
    /// <param name="pageSize">Page size</param>
    /// <returns>
    /// A task that represents the asynchronous operation
    /// The task result contains the bids
    /// </returns>
    Task<IPagedList<AuctionBid>> GetAllBidsAsync(int customerId = 0, int pageIndex = 0, int pageSize = int.MaxValue);

    Task<int> GetBidsCountByProductToAuctionIdAsync(int productToAuctionId);
    Task<List<AuctionBid>> GetAllLastBidByAuctionIdAsync(int auctionId);
    Task<Dictionary<int, AuctionBid>> GetAllLastBidDictionaryByAuctionIdAsync(int auctionId);
    Task<bool> HasBidByProductToAuctionIdAsync(int productToAuctionId);
    Task<AuctionBid> GetBidByIdAsync(int bidId);
   
    Task InsertBidAsync(AuctionBid auctionBid);
   
    Task UpdateBidAsync(AuctionBid auctionBid);
  
    Task DeleteBidAsync(AuctionBid pickupPoint);

    Task InsertAuctionAsync(Auction auction);
    Task UpdateAuctionAsync(Auction auction);

    Task<List<Auction>> GetAllAuctionsAsync();
    Task<List<Auction>> GetAllCurrentAutoOpenAndClosedAuctionsAsync();

    Task<AuctionDto> GetAuctionDtoWithAuctionBids(int auctionId, bool activeProductOnly, int maxBidsCount);
    Task<List<ProductToAuctionMapping>> GetProductToAuctionsByAuctionIdAsync(int auctionId, bool onlyActiveItems);
    Task<ProductToAuctionMapping> GetNextProductToAuctionByAuctionIdAsync(int auctionId);
    Task<List<ProductToAuctionMapping>> GetNotClosedProductToAuctionsByAuctionId(int auctionId);

    Task<Auction> GetAuctionByIdAsync(int auctionId);
    Task<AuctionDto> GetAuctionDtoByIdAsync(int auctionId, bool widthProducts, bool activeProductOnly);
    Task<List<ProductToAuctionDto>> GetProductToAuctionDtosByAuctionId(int auctionId, bool activeProductOnly);
    Task<List<ProductToAuctionDto>> GetProductToAuctionDtosByProductIdAsync(int productId);

    Task<AuctionDto> GetAuctionDtoWithProductByIdAsync(int auctionId, int productId, bool activeProductOnly);

    Task<ProductToAuctionDto> GetProductToAuctionDtoByIdAsync(int productToAuctionId);

    Task<AuctionBidDto> GetAuctionBidDtoByIdAsync(int auctionBidId);

    Task<ProductToAuctionMapping> AssignProductToAuctionAsync(int productId, decimal startingPrice, decimal bidPrice, int auctionId, int sortIndex);
    
    Task<List<ProductToAuctionMapping>> GetProductToAuctionsByProductIdAsync(int productId);

    Task<List<ProductToAuctionMapping>> GetProductToAuctionByAuctionIdAndProductIdAsync(int auctionId, int productId, bool activeProductOnly);
    Task<ProductToAuctionMapping> GetProductToAuctionMappingByIdAsync(int productToAuctionMappingId);
    Task UpdateProductToAuctionAsync(ProductToAuctionMapping productToAuctionMapping);
    Task UpdateProductToAuctionAsync(IList<ProductToAuctionMapping> productToAuctionMappings);

    Task<Order> CreateOrderForWinnerAsync(ProductToAuctionMapping productToAuctionMapping);
}