using LiteCharms.Features.MidrandBooks.AuthorBooks; using LiteCharms.Features.MidrandBooks.Authors; using LiteCharms.Features.MidrandBooks.Customers; using LiteCharms.Features.MidrandBooks.Customers.Models; using LiteCharms.Features.MidrandBooks.Orders; using LiteCharms.Features.MidrandBooks.Payments; using LiteCharms.Features.MidrandBooks.Payments.Models; using LiteCharms.Features.MidrandBooks.Products; namespace MidrandBookshop; public sealed class HydrationService(AuthenticationStateProvider authStateProvider, CustomerService customerService, ProductService productService, OrderService orderService, BooksService booksService, AuthorService authorService, CartService cartService) { private Cart ShoppingCart => cartService.ShoppingCart; private AuthenticationState? AuthState { get; set; } private ClaimsPrincipal? User { get; set; } public bool CartHydrated { get; set; } public async Task EnsureCustomerExistsAsync(CancellationToken cancellationToken = default) { if (ShoppingCart.CustomerId > 0) return; AuthState = await authStateProvider.GetAuthenticationStateAsync(); User = AuthState!.User; if (User?.Identity?.IsAuthenticated == false) return; var email = User!.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)!.Value!; var existingCustomer = await customerService.GetCustomerAsync(email, cancellationToken); if (existingCustomer.IsSuccess) ShoppingCart.CustomerId = existingCustomer.Value.Id; if (existingCustomer.IsFailed) { var name = User!.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)!.Value!; var lastname = User!.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Surname)!.Value!; var mobile = User!.Claims.FirstOrDefault(c => c.Type == ClaimTypes.MobilePhone)!.Value!; var customerCreate = await customerService.CreateCustomerAsync(new CreateCustomer { Email = email }, cancellationToken); if (customerCreate.IsSuccess) { ShoppingCart.CustomerId = customerCreate.Value; if (!string.IsNullOrWhiteSpace(name)) await customerService.CreateCustomerContactAsync((long)ShoppingCart.CustomerId, new CreateCustomerContact { Email = email, Name = name, LastName = lastname, Phone = mobile, Type = LiteCharms.Features.ContactTypes.Personal }, cancellationToken); } } } public async Task RehydrateCartFromPendingOrderAsync(CancellationToken cancellationToken = default) { if (User?.Identity?.IsAuthenticated == false) return; if (ShoppingCart.OrderId > 0 && ShoppingCart.CustomerId > 0) { cartService.CalculateTotalPrice(); CartHydrated = true; return; } var orderResult = await orderService.GetPendingOrderAsync((long)ShoppingCart.CustomerId!, cancellationToken); if (orderResult.IsFailed) return; if(orderResult.Value.Id == ShoppingCart.OrderId) { cartService.CalculateTotalPrice(); CartHydrated = true; return; } var orderItemsResult = await orderService.GetOrderItemsAsync((long)orderResult.Value.Id!, cancellationToken); ShoppingCart.OrderId = orderResult.Value.Id; if(orderItemsResult.IsFailed) return; foreach (var item in orderItemsResult.Value) { var priceFetchResult = await productService.GetProductPriceAsync(item.ProductPriceId, cancellationToken); if (priceFetchResult.IsFailed) continue; var bookFetchResult = await booksService.GetBookByProductIdAsync(priceFetchResult.Value.ProductId, cancellationToken); if (bookFetchResult.IsFailed) continue; var authorFetchResult = await authorService.GetAuthorAsync(bookFetchResult.Value.AuthorId, cancellationToken); if (authorFetchResult.IsFailed) continue; if(!ShoppingCart.Items.Any(i => i.Price!.Id == item.ProductPriceId)) cartService.AddItem(priceFetchResult.Value, bookFetchResult.Value.Product!, authorFetchResult.Value); } CartHydrated = true; await cartService.SaveCartToStorageAsync(); } }