using Mango.Nop.Core.Repositories;
using Microsoft.AspNetCore.Http;
using Nop.Core.Caching;
using Nop.Core.Configuration;
using Nop.Core.Domain.Catalog;
using Nop.Core.Events;
using Nop.Data;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums;
using Nop.Plugin.Misc.AuctionPlugin.Hubs;
using Nop.Plugin.Misc.AuctionPlugin.Services;
using Nop.Services.Events;
using Nop.Services.Logging;

namespace Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer;

public class ProductToAuctionDbTable : MgDbTableBase<ProductToAuctionMapping>
{
    public ProductToAuctionDbTable(IEventPublisher eventPublisher, INopDataProvider dataProvider, IShortTermCacheManager shortTermCacheManager, IStaticCacheManager staticCacheManager, AppSettings appSettings, ILogger logger)
        : base(eventPublisher, dataProvider, shortTermCacheManager, staticCacheManager, appSettings, logger)
    {
    }

    private static bool HasActiveAuctionStatus(AuctionStatus auctionStatus)
    {
        //TODO: erre a problémára kitalálni valamit! - J.
        return auctionStatus == AuctionStatus.Active || auctionStatus == AuctionStatus.FirstWarning || auctionStatus == AuctionStatus.SecondWarning || auctionStatus == AuctionStatus.Pause;
        //return auctionStatus.HasFlag(AuctionStatus.Active) || auctionStatus.HasFlag(AuctionStatus.FirstWarning) || auctionStatus.HasFlag(AuctionStatus.SecondWarning);
    }

    public IQueryable<ProductToAuctionMapping> GetByAuctionAndProductId(int auctionId, int productId, bool activeProductOnly = false)
    {
        return GetProductToAuctionsByAuctionId(auctionId, activeProductOnly).Where(x => x.ProductId == productId);
    }

    public IQueryable<ProductToAuctionMapping> GetByProductId(int productId, bool activeProductOnly = false)
    {
        return Table.Where(x => x.ProductId == productId &&
                                (!activeProductOnly || x.AuctionStatus == AuctionStatus.Active || x.AuctionStatus == AuctionStatus.FirstWarning || x.AuctionStatus == AuctionStatus.SecondWarning || x.AuctionStatus == AuctionStatus.Pause /*HasActiveAuctionStatus(x.AuctionStatus)*/));
    }

    public IQueryable<ProductToAuctionMapping> GetProductToAuctionsByAuctionId(int auctionId, bool activeProductOnly = false)
    {
        return Table.Where(x => x.AuctionId == auctionId &&
                                (!activeProductOnly || x.AuctionStatus == AuctionStatus.Active || x.AuctionStatus == AuctionStatus.FirstWarning || x.AuctionStatus == AuctionStatus.SecondWarning || x.AuctionStatus == AuctionStatus.Pause /*HasActiveAuctionStatus(x.AuctionStatus)*/));
    }

    public IQueryable<ProductToAuctionMapping> GetNotClosedItemsByAuctionId(int auctionId)
    {
        return Table.Where(x => x.AuctionId == auctionId && x.AuctionStatus != AuctionStatus.Sold && x.AuctionStatus != AuctionStatus.NotSold);
    }

    public Task<ProductToAuctionMapping> GetNextItemByAuctionIdAsync(int auctionId)
    {
        return GetNotClosedItemsByAuctionId(auctionId).OrderBy(x => x.SortIndex).FirstOrDefaultAsync();
    }

    //public async Task ResetByProductIdAsync(int productId, decimal basePrice) => await ResetAsync(await GetByProductId(productId).FirstOrDefaultAsync(), basePrice);
    public async Task ResetByIdAsync(int productToAuctionId, decimal basePrice) => await ResetAsync(await GetByIdAsync(productToAuctionId), basePrice);
    public async Task ResetAsync(ProductToAuctionMapping productToAuction, decimal basePrice)
    {
        if (productToAuction == null)
        {
            Logger.Error($"ProductToAuctionDbTable.ResetAsync(); productToAuction == null");
            return;
        }

        await Logger.InformationAsync($"ProductToAuctionDbTable.ResetAsync(); productToAuction.Id: {productToAuction.Id}; basePrice: {basePrice}");

        //TODO: ezt kivegyem egyelőre? amíg a Product.Price-t használjuk, addig nem sok értelme
        productToAuction.StartingPrice = basePrice;
        productToAuction.CurrentPrice = basePrice;
        productToAuction.WinnerCustomerId = 0;
        productToAuction.OrderItemId = 0;
        productToAuction.OrderId = 0;
        productToAuction.AuctionStatus = AuctionStatus.None;
        productToAuction.BiddingNumber = null;
        productToAuction.BidsCount = 0;

        await UpdateAsync(productToAuction);
    }
}