using AyCode.Core.Extensions; using AyCode.Utils.Extensions; using Mango.Nop.Services; using Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages; using Nop.Plugin.Misc.AuctionPlugin.Services; using Nop.Services.Catalog; using Nop.Services.Logging; using Microsoft.AspNetCore.SignalR; using Nop.Core; using Nop.Core.Domain.Catalog; using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; using Nop.Core.Domain.Customers; using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities; using Nop.Services.Customers; namespace Nop.Plugin.Misc.AuctionPlugin.Hubs { //- Dollár currency //- Pipa, ha tied a licit //- Pause, Lezárás, Revert, //- ha saját licit a legjobb vagy lezárt, ne lehessen bid-elni //- az előző esetben a kliensen a gombot is tiltani, már a.cshtml-ben ellenőrizni! //- csak a watch-olt item-eknél legyen announcment //- ha bid-elt 1x is, kerüljön a watch-ba //- DbTransaction-t vhogy megcsinánli! //public class SignalRMessageHandler(ILogger logger, IProductService productService, AuctionService auctionService, IHubContext hubContext, IWorkContext workContext, ICustomerService customerService, ICategoryService categoryService) //{ //private readonly Mutex _handleMessageMutex = new(); //public async Task HandleMessage(MessageWrapper messageWrapper, SessionItem sessionItem, string connectionId) //{ // var customer = await workContext.GetCurrentCustomerAsync(); // //var connectionId = sessionItem?.SessionId; // if (messageWrapper?.Data == null) // { // logger.Error($"SignalRMessageHandler.HandleMessage(); message?.Data == null; connectionId: {connectionId}", null, customer); // return; // } // if (sessionItem == null || sessionItem.RequestCount != messageWrapper.RequestCount) // await logger.WarningAsync($"SignalRMessageHandler.HandleMessage(); sessionItem == null || sessionItem.RequestCount != messageWrapper.RequestCount; connectionId: {connectionId}; sessionId: {sessionItem?.SessionId}; sessionRequests: {sessionItem?.RequestCount}; wrapperRequests: {messageWrapper.RequestCount}", null, customer); // if (customer == null || messageWrapper.SenderId <= 0 || messageWrapper.SenderId != customer.Id || await customerService.IsGuestAsync(customer)) // { // logger.Error($"SignalRMessageHandler.HandleMessage(); (customer == null || message.SenderId <= 0 || message.SenderId != customer.Id || IsGuestAsync() == true); connectionId: {connectionId}", null, customer); // return; // } // await logger.InformationAsync($"SignalRMessageHandler.HandleMessage(); Before lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}; jsonData: {messageWrapper.Data}", null, customer); // //TODO: az összes request-et egy base-ből származtatni és beletenni az AuctionRequestMode-ot! - J. // using (_handleMessageMutex.UseWaitOne()) // { // try // { // await logger.InformationAsync($"SignalRMessageHandler.HandleMessage(); Enter lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); // if (messageWrapper.MessageType == "BidRequestMessage") await HandleBidRequest(customer, messageWrapper); // else // { // if (!await customerService.IsAdminAsync(customer)) // { // logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); IsAdminAsync() == false; connectionId: {connectionId}", null, customer); // return; // } // switch (messageWrapper.MessageType) // { // case nameof(AuctionProductStatusRequest): // await HandleProductToAuctionStatusChangedRequest(customer, messageWrapper); // break; // case nameof(RevertAuctionBidRequest): // await HandleRevertAuctionBidRequest(customer, messageWrapper); // break; // default: // // Add other message types here // await logger.ErrorAsync($"SignalRMessageHandler.HandleMessage(); Unknown message type; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); // break; // } // } // await logger.InformationAsync($"SignalRMessageHandler.HandleMessage(); Exit lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); // } // catch (Exception ex) // { // logger.Error($"SignalRMessageHandler.HandleMessage(); switch (message.MessageType); MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}; Exception: {ex.Message}", ex, customer); // } // } //} //public async Task HandleRevertAuctionBidRequest(Customer customer, MessageWrapper messageWrapper) //{ // var revertAuctionBidRequest = messageWrapper.Data.JsonTo(); // if (revertAuctionBidRequest == null) // { // logger.Error($"SignalRMessageHandler.HandleRevertAuctionBidRequest(); auctionProductStatusRequest == null", null, customer); // return ResponseType.Error; // } // try // { // var productToAuction = (await auctionService.GetProductToAuctionMappingByIdAsync(revertAuctionBidRequest.ProductToAuctionId)); // if (productToAuction is not { AuctionStatus: AuctionStatus.Pause }) // { // logger.Warning($"SignalRMessageHandler.HandleRevertAuctionBidRequest(); (productToAuction is not {{ AuctionStatus: AuctionStatus.Pause }}); AuctionStatus: {productToAuction?.AuctionStatus}", null, customer); // return ResponseType.Error; // } // await logger.InformationAsync($"SignalRMessageHandler.HandleRevertAuctionBidRequest(); (productToAuction is not {{ AuctionStatus: AuctionStatus.Pause }}); AuctionStatus: {productToAuction.AuctionStatus}", null, customer); // var product = await auctionService.GetProductById(productToAuction.ProductId); // if (product == null) return ResponseType.Error; // var revertLastBid = await auctionService.RevertAuctionBidByProductToAuctionIdAsync(productToAuction.Id); // if (revertLastBid == null) await ResetProductToAuction(productToAuction); // else // { // productToAuction.BidsCount = await auctionService.GetBidsCountByProductToAuctionIdAsync(productToAuction.Id); // await SetAuctionBidPrice(revertLastBid.BidPrice, productToAuction, product, revertLastBid.CustomerId); // } // await SendAuctionBidMessageAsync(messageWrapper, productToAuction, product, customer.Id, ResponseType.ToAllClients); // return ResponseType.ToAllClients; // } // catch (Exception ex) // { // logger.Error($"SignalRMessageHandler.HandleRevertAuctionBidRequest(); Exception: {ex.Message}", ex, customer); // } // return ResponseType.Error; //} //public async Task HandleProductToAuctionStatusChangedRequest(Customer customer, MessageWrapper messageWrapper) //{ // var auctionProductStatusRequest = messageWrapper.Data.JsonTo(); // if (auctionProductStatusRequest == null) // { // logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); auctionProductStatusRequest == null", null, customer); // return ResponseType.Error; // } // try // { // var responseType = ResponseType.ToAllClients; // await logger.InformationAsync($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); ProductToAuctionMappingId: {auctionProductStatusRequest.ProductToAuctionId}; Status: {auctionProductStatusRequest.AuctionStatus}({(int)auctionProductStatusRequest.AuctionStatus})", null, customer); // var productToAuction = await auctionService.GetProductToAuctionMappingByIdAsync(auctionProductStatusRequest.ProductToAuctionId); // if (productToAuction == null) // { // logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (productToAuction == null)", null, customer); // return ResponseType.Error; // } // var auction = await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId); // if (auction == null || auction.Closed) // { // logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer); // return ResponseType.Error; // } // if (!IsValidRequestAuctionStatus(auctionProductStatusRequest.AuctionStatus, productToAuction.AuctionStatus)) // { // responseType = ResponseType.ToCaller; // logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); RequestAuctionStatusIsValid() == false; newStatus: {auctionProductStatusRequest.AuctionStatus}; oldStatus: {productToAuction.AuctionStatus}", null, customer); // //return ResponseType.Error;; // } // else if (auctionProductStatusRequest.AuctionStatus == AuctionStatus.None) await ResetProductToAuction(productToAuction, auction.CategoryId); // else // { // switch (auctionProductStatusRequest.AuctionStatus) // { // case AuctionStatus.Active: // productToAuction.AuctionStatus = AuctionStatus.Active; // await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, auction.CategoryId, true); // break; // case AuctionStatus.FirstWarning: // case AuctionStatus.SecondWarning: // productToAuction.AuctionStatus = auctionProductStatusRequest.AuctionStatus; // break; // case AuctionStatus.Sold: // var lastAuctionBid = await auctionService.GetLastAuctionBidByProductToAuctionIdAsync(productToAuction.Id); // if (lastAuctionBid == null) productToAuction.AuctionStatus = AuctionStatus.NotSold; // else // { // productToAuction.AuctionStatus = AuctionStatus.Sold; // productToAuction.CurrentPrice = lastAuctionBid.BidPrice; // productToAuction.WinnerCustomerId = lastAuctionBid.CustomerId; // var placeOrderResult = await auctionService.CreateOrderForWinnerAsync(productToAuction); // if (placeOrderResult == null || placeOrderResult.Id == 0) // { // logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (placeOrderResult == null || placeOrderResult.Id == 0)", null, customer); // //return; //TODO: EGYELŐRE HAGYJUK LEZÁRNI AKKOR IS, HA NEM SIKERÜLT AZ ORDERPLACE()! - J. // } // } // await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, auction.CategoryId, false); // break; // case AuctionStatus.Pause: // productToAuction.AuctionStatus = AuctionStatus.Pause; // break; // default: // logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); AuctionStatus not found; (auctionProductStatusRequest.AuctionStatus == {auctionProductStatusRequest.AuctionStatus})", null, customer); // return ResponseType.Error; // } // await auctionService.UpdateProductToAuctionMappingAsync(productToAuction); // } // var bidsCount = productToAuction.BidsCount;//await auctionService.GetBidsCountByProductToAuctionIdAsync(productToAuction.Id); // var productToauctionChangedNotification = new MessageWrapper // { // MessageType = nameof(ProductToAuctionStatusNotification), // SenderId = customer.Id, // ResponseType = responseType, // Data = new ProductToAuctionStatusNotification(await auctionService.GetAuctionDtoByProductToAuctionIdAsync(productToAuction.Id, true), bidsCount, "EMPTY").ToJson() // }; // await SendMessageToClientsAsync(productToauctionChangedNotification, responseType == ResponseType.ToCaller); // //TODO: gond van ha az Admin valamit módosít és újrazár egy régi ProductToAuction-t!!!! AuctionRequestMode.Normal...- J. // if (responseType == ResponseType.ToAllClients && /*AuctionRequestMode.Normal &&*/ auction.AuctionType == AuctionType.AutomaticNext && productToAuction.AuctionStatus is AuctionStatus.Sold or AuctionStatus.NotSold) // await StepNextProductToAuctionAsync(messageWrapper, customer, productToAuction, auctionProductStatusRequest); // return ResponseType.ToAllClients; // } // catch (Exception ex) // { // logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); Exception: {ex.Message}", ex, customer); // } // return ResponseType.Error; //} //private async Task SendMessageToClientsAsync(MessageWrapper messageWrapper, bool sendToCaller = false) //{ // //if (sendToCaller) await hubContext.Clients.Caller.SendAsync("send", bidMessage.ToJson()); // //else // await hubContext.Clients.All.SendAsync("send", messageWrapper.ToJson()); //} //public async Task HandleBidRequestAsync(Customer customer, MessageWrapper messageWrapper) //{ // var bidRequestMessage = messageWrapper.Data.JsonTo(); // if (bidRequestMessage == null) // { // logger.Error($"SignalRMessageHandler.HandleBidRequestAsync(); (bidRequestMessage == null)", null, customer); // return ResponseType.Error; // } // try // { // await logger.InformationAsync($"SignalRMessageHandler.HandleBidRequestAsync(); Bid received; Auction: {bidRequestMessage.AuctionId}; ProductToAuction: {bidRequestMessage.ProductAuctionMappingId}; Product: {bidRequestMessage.ProductId}; Bid: {bidRequestMessage.BidPrice}; Customer: {bidRequestMessage.CustomerId}", null, customer); // var auction = await auctionService.GetAuctionDtoByIdAsync(bidRequestMessage.AuctionId, false, false); // if (auction == null || auction.Closed) // { // logger.Warning($"SignalRMessageHandler.HandleBidRequestAsync(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer); // return ResponseType.Error; // } // var product = await auctionService.GetProductById(bidRequestMessage.ProductId); // if (product == null) return ResponseType.Error; // var activeProductAuction = (await auctionService.GetProductToAuctionByAuctionIdAndProductIdAsync(bidRequestMessage.AuctionId, bidRequestMessage.ProductId, true)).FirstOrDefault(); // if (activeProductAuction is not { IsActiveItem: true } || (activeProductAuction.WinnerCustomerId == customer.Id && !await customerService.IsAdminAsync(customer))) // { // logger.Warning($"SignalRMessageHandler.HandleBidRequestAsync(); (activeProductAuction is not {{ IsActiveItem: true }} || activeProductAuction.WinnerCustomerId == customer.Id && !await customerService.IsAdminAsync(customer)); AuctionStatus: {activeProductAuction?.AuctionStatus}; WinnerCustomerId: {activeProductAuction?.WinnerCustomerId}", null, customer); // await UpdateBidNotificationMessageWrapperAsync(messageWrapper, activeProductAuction, product, customer.Id, ResponseType.ToCaller); // return ResponseType.ToCaller; // } // if (!IsValidBidPrice(activeProductAuction.CurrentPrice, bidRequestMessage.BidPrice, activeProductAuction.BidsCount > 0, customer)) // { // await UpdateBidNotificationMessageWrapperAsync(messageWrapper, activeProductAuction, product, customer.Id, ResponseType.ToCaller); // return ResponseType.ToCaller; // } // var auctionBid = bidRequestMessage.CreateMainEntity(); // auctionBid.ProductAuctionMappingId = activeProductAuction.Id; // await auctionService.InsertBidAsync(auctionBid); // activeProductAuction.BidsCount++; // activeProductAuction.AuctionStatus = AuctionStatus.Active; // if (!await SetAuctionBidPrice(auctionBid.BidPrice, activeProductAuction, product, customer.Id)) return ResponseType.Error; // await UpdateBidNotificationMessageWrapperAsync(messageWrapper, activeProductAuction, product, customer.Id, ResponseType.ToAllClients); // return ResponseType.ToAllClients; // } // catch (Exception ex) // { // logger.Error($"SignalRMessageHandler.HandleBidRequestAsync(); Exception: {ex.Message}", ex, customer); // } // return ResponseType.Error; //} //private async Task SetAuctionBidPrice(decimal bidPrice, ProductToAuctionMapping productToAuction, Product product, int lastBidCustomerId) //{ // try // { // product.Price = bidPrice; // await productService.UpdateProductAsync(product); // //activeProductAuction.StartingPrice = product.OldPrice; //TODO: ez biztosan kezelve van mikor összerendeljük? - J. // productToAuction.CurrentPrice = bidPrice; // productToAuction.WinnerCustomerId = lastBidCustomerId; // await auctionService.UpdateProductToAuctionMappingAsync(productToAuction); // return true; // } // catch (Exception ex) // { // logger.Error($"SignalRMessageHandler.HandleBidRequest(); SetAuctionBidPrice() == false", ex); // } // return false; //} //public async Task UpdateBidNotificationMessageWrapperAsync(MessageWrapper messageWrapper, ProductToAuctionMapping productToAuction, Product product, int customerId, ResponseType responseType) //{ // var bidsCount = productToAuction.BidsCount; //await auctionService.GetBidsCountByProductToAuctionIdAsync(productToAuction.Id); // var stepAmount = GetStepAmount(productToAuction.CurrentPrice); // var nextBidPrice = GetNextBidPrice(productToAuction.CurrentPrice, stepAmount, bidsCount > 0); // messageWrapper.SenderId = customerId; // messageWrapper.ResponseType = responseType; // messageWrapper.MessageType = "bidNotification"; // messageWrapper.Data = new BidNotificationMessage(await auctionService.GetAuctionDtoByProductToAuctionIdAsync(productToAuction.Id, true), bidsCount, "EMPTY") //TODO: NE KÉRJÜK LE DB-BŐL!!! - J. // { // ProductName = product.Name, // CurrentPrice = productToAuction.CurrentPrice, // NextStepAmount = stepAmount, // NextBidPrice = nextBidPrice, // }.ToJson(); //} //public async Task SendAuctionBidMessageAsync(MessageWrapper messageWrapper, ProductToAuctionMapping productToAuction, Product product, int customerId, ResponseType responseType) //{ // await UpdateBidNotificationMessageWrapperAsync(messageWrapper, productToAuction, product, customerId, responseType); // await SendMessageToClientsAsync(messageWrapper, responseType == ResponseType.ToCaller); //} //private async Task StepNextProductToAuctionAsync(MessageWrapper messageWrapper, Customer customer, ProductToAuctionMapping productToAuction, AuctionProductStatusRequest auctionProductStatusRequest) //{ // var nextProductToAuction = await auctionService.GetNextProductToAuctionByAuctionIdAsync(productToAuction.AuctionId); // if (nextProductToAuction == null) return; // await logger.InformationAsync($"SignalRMessageHandler.StepNextProductToAuctionAsync(); NextProductToAuctionId: {nextProductToAuction.Id};", null, customer); // if (nextProductToAuction.AuctionStatus != AuctionStatus.None) // { // await logger.WarningAsync($"SignalRMessageHandler.StepNextProductToAuctionAsync(); (nextProductToAuction.AuctionStatus != AuctionStatus.None); NextProductToAuctionId: {nextProductToAuction.Id}; Status: {nextProductToAuction.AuctionStatus}({(int)nextProductToAuction.AuctionStatus})", null, customer); // return; //TODO: Ilyenkor mi legyen?! - J. // } // auctionProductStatusRequest.AuctionStatus = AuctionStatus.Active; // auctionProductStatusRequest.ProductToAuctionId = nextProductToAuction.Id; // await HandleProductToAuctionStatusChangedRequest(customer, messageWrapper); //} //private async Task ResetProductToAuction(ProductToAuctionMapping productToAuction, int? categoryId = null) //{ // productToAuction.AuctionStatus = AuctionStatus.None; // await auctionService.ResetProductToAuctionAsync(productToAuction, productToAuction.StartingPrice); // categoryId ??= (await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId))?.CategoryId; // await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, categoryId, false); //} //private async Task UpdateProductCategoryIsFeaturedAsync(int productId, int? categoryId, bool isFeatured) //{ // //Leszarjuk ha elszáll, az aukció menjen tovább... - J. // try // { // if (categoryId.GetValueOrDefault(0) == 0) return; // var productCategory = (await categoryService.GetProductCategoriesByProductIdAsync(productId)).FirstOrDefault(x => x.CategoryId == categoryId); // if (productCategory == null) return; // if (productCategory.IsFeaturedProduct == isFeatured) return; // productCategory.IsFeaturedProduct = isFeatured; // await categoryService.UpdateProductCategoryAsync(productCategory); // } // catch (Exception ex) // { // logger.Error($"SignalRMessageHandler.UpdateProductCategoryIsFeaturedAsync(); categoryId: {categoryId}; productId: {productId}; isFeatured: {isFeatured}", ex); // } //} //private bool IsValidBidPrice(decimal productToAuctionCurrentPrice, decimal bidRequestPrice, bool hasAuctionBidInDb, Customer customer = null) //{ // var nextBidPrice = GetNextBidPrice(productToAuctionCurrentPrice, hasAuctionBidInDb); // if (bidRequestPrice != nextBidPrice) // { // logger.Warning($"SignalRMessageHandler.IsValidBidPrice(); (bidRequestPrice != nextBidPrice); productToAuctionCurrentPrice: {productToAuctionCurrentPrice}; bidRequestPrice: {bidRequestPrice}; hasAuctionBidInDb: {hasAuctionBidInDb}", null, customer); // return false; // } // return true; //} //private static decimal GetStepAmount(decimal currentBidPrice) => AuctionService.GetStepAmount(currentBidPrice); //private static decimal GetNextBidPrice(decimal currentBidPrice, bool hasAuctionBidInDb) => GetNextBidPrice(currentBidPrice, GetStepAmount(currentBidPrice), hasAuctionBidInDb); //private static decimal GetNextBidPrice(decimal currentBidPrice, decimal stepAmount, bool hasAuctionBidInDb) => AuctionService.GetNextBidPrice(currentBidPrice, stepAmount, hasAuctionBidInDb); //private static bool IsValidRequestAuctionStatus(AuctionStatus newStatus, AuctionStatus oldStatus) //{ // switch (oldStatus) // { // case AuctionStatus.None: // return newStatus is AuctionStatus.Active or AuctionStatus.Pause; // case AuctionStatus.Active: // return newStatus is AuctionStatus.FirstWarning or AuctionStatus.Pause; // case AuctionStatus.FirstWarning: // return newStatus is AuctionStatus.SecondWarning or AuctionStatus.Pause; // case AuctionStatus.SecondWarning: // return newStatus is AuctionStatus.Sold or AuctionStatus.Pause; // case AuctionStatus.Pause: // return newStatus is AuctionStatus.None or AuctionStatus.Active; // case AuctionStatus.Sold: // case AuctionStatus.NotSold: // default: // return false; // } //} } //}