using Microsoft.EntityFrameworkCore; using LittleShop.Data; using LittleShop.Models; using LittleShop.Enums; namespace LittleShop.Services; public interface IDataSeederService { Task SeedSampleDataAsync(); } public class DataSeederService : IDataSeederService { private readonly LittleShopContext _context; private readonly ILogger _logger; public DataSeederService(LittleShopContext context, ILogger logger) { _context = context; _logger = logger; } public async Task SeedSampleDataAsync() { await SeedProductionDataAsync(); } private async Task SeedProductionDataAsync() { _logger.LogInformation("Setting up production-ready catalog..."); // Clean up existing test products first (excluding valid products that just need stock update) var testProducts = await _context.Products .Where(p => p.Name.Contains("JAMES") || p.Name.Contains("dsasada") || p.Name.Contains("asdsads")) .ToListAsync(); if (testProducts.Any()) { _context.Products.RemoveRange(testProducts); await _context.SaveChangesAsync(); _logger.LogInformation("Removed {Count} test products", testProducts.Count); } // Check if we need to create production catalog or update stock var hasProductionProducts = await _context.Products .AnyAsync(p => p.Name.Contains("Wireless Noise-Cancelling Headphones")); if (hasProductionProducts) { // Update stock for existing production products await UpdateProductionStockAsync(); return; } _logger.LogInformation("Seeding sample data..."); // Create Categories var categories = new List { new Category { Id = Guid.NewGuid(), Name = "Electronics", Description = "Electronic devices and accessories", IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, new Category { Id = Guid.NewGuid(), Name = "Clothing", Description = "Apparel and fashion items", IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, new Category { Id = Guid.NewGuid(), Name = "Books", Description = "Physical and digital books", IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow } }; _context.Categories.AddRange(categories); await _context.SaveChangesAsync(); _logger.LogInformation("Created {Count} categories", categories.Count); // Ensure we have categories before creating products var electronicsCategory = await _context.Categories.FirstOrDefaultAsync(c => c.Name == "Electronics"); var clothingCategory = await _context.Categories.FirstOrDefaultAsync(c => c.Name == "Clothing"); var booksCategory = await _context.Categories.FirstOrDefaultAsync(c => c.Name == "Books"); if (electronicsCategory == null || clothingCategory == null || booksCategory == null) { _logger.LogWarning("Categories not found, creating them first"); // Categories would be created by the original seeder logic above } // Create Production-Ready Products with proper stock var products = new List { // ELECTRONICS - High-margin, popular items new Product { Id = Guid.NewGuid(), Name = "Wireless Noise-Cancelling Headphones", Description = "Premium Bluetooth 5.0 headphones with active noise cancellation, 30-hour battery life, and crystal-clear audio. Perfect for music, calls, and travel. Includes carrying case and charging cable.", Price = 149.99m, Weight = 280, WeightUnit = ProductWeightUnit.Grams, StockQuantity = 25, CategoryId = electronicsCategory?.Id ?? categories[0].Id, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, new Product { Id = Guid.NewGuid(), Name = "Fast Wireless Charging Stand", Description = "15W fast wireless charger compatible with iPhone, Samsung, and Qi-enabled devices. Anti-slip base, LED indicator, includes AC adapter. Charge through most phone cases up to 5mm thick.", Price = 34.99m, Weight = 180, WeightUnit = ProductWeightUnit.Grams, StockQuantity = 50, CategoryId = electronicsCategory?.Id ?? categories[0].Id, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, new Product { Id = Guid.NewGuid(), Name = "Ultra-Slim Power Bank 20,000mAh", Description = "High-capacity portable charger with dual USB-A and USB-C ports. Fast charging technology, digital display shows remaining power. Charges iPhone 13 up to 4 times, includes USB-C cable.", Price = 59.99m, Weight = 450, WeightUnit = ProductWeightUnit.Grams, StockQuantity = 35, CategoryId = electronicsCategory?.Id ?? categories[0].Id, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, new Product { Id = Guid.NewGuid(), Name = "Premium Phone Case with MagSafe", Description = "Military-grade protection with built-in MagSafe compatibility. Drop-tested to 12 feet, raised camera and screen edges, clear back shows your phone's design. Compatible with iPhone 14/15 series.", Price = 29.99m, Weight = 65, WeightUnit = ProductWeightUnit.Grams, StockQuantity = 75, CategoryId = electronicsCategory?.Id ?? categories[0].Id, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, // CLOTHING - Essential wardrobe items new Product { Id = Guid.NewGuid(), Name = "Premium Cotton T-Shirt", Description = "100% organic cotton, pre-shrunk, tagless design. Soft, breathable fabric in classic fit. Available in multiple colors. Perfect for casual wear or layering. Machine washable, retains shape after washing.", Price = 24.99m, Weight = 180, WeightUnit = ProductWeightUnit.Grams, StockQuantity = 100, CategoryId = clothingCategory?.Id ?? categories[1].Id, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, new Product { Id = Guid.NewGuid(), Name = "Classic Denim Jeans", Description = "Premium denim with perfect stretch for comfort. Classic 5-pocket styling, reinforced stress points, fade-resistant color. Available in multiple washes and sizes. Timeless style that works with everything.", Price = 79.99m, Weight = 650, WeightUnit = ProductWeightUnit.Grams, StockQuantity = 60, CategoryId = clothingCategory?.Id ?? categories[1].Id, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, new Product { Id = Guid.NewGuid(), Name = "Cozy Knit Sweater", Description = "Soft merino wool blend, lightweight yet warm. Crew neck design, ribbed cuffs and hem. Perfect for layering or wearing alone. Hand-washable, pill-resistant fabric maintains shape and softness.", Price = 89.99m, Weight = 320, WeightUnit = ProductWeightUnit.Grams, StockQuantity = 40, CategoryId = clothingCategory?.Id ?? categories[1].Id, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, // BOOKS - Knowledge and entertainment new Product { Id = Guid.NewGuid(), Name = "The Complete Guide to Cryptocurrency", Description = "Comprehensive guide to understanding Bitcoin, Ethereum, DeFi, and blockchain technology. Written for beginners and enthusiasts. 400+ pages with real-world examples, investment strategies, and security tips.", Price = 39.99m, Weight = 580, WeightUnit = ProductWeightUnit.Grams, StockQuantity = 30, CategoryId = booksCategory?.Id ?? categories[2].Id, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, new Product { Id = Guid.NewGuid(), Name = "Modern Web Development Handbook", Description = "Learn React, Node.js, and modern JavaScript. Hands-on projects, best practices, and deployment strategies. Includes access to online code repository and video tutorials. Perfect for career advancement.", Price = 49.99m, Weight = 720, WeightUnit = ProductWeightUnit.Grams, StockQuantity = 25, CategoryId = booksCategory?.Id ?? categories[2].Id, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, new Product { Id = Guid.NewGuid(), Name = "Mindfulness and Productivity Journal", Description = "Daily planner with mindfulness exercises and productivity techniques. 6-month undated format, premium paper, goal-setting frameworks. Improve focus, reduce stress, achieve work-life balance.", Price = 27.99m, Weight = 380, WeightUnit = ProductWeightUnit.Grams, StockQuantity = 45, CategoryId = booksCategory?.Id ?? categories[2].Id, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow } }; _context.Products.AddRange(products); await _context.SaveChangesAsync(); _logger.LogInformation("Created {Count} products", products.Count); // Create Shipping Rates var shippingRates = new List { new ShippingRate { Id = Guid.NewGuid(), Name = "Royal Mail First Class", Description = "Next working day delivery", Country = "United Kingdom", MinWeight = 0, MaxWeight = 100, Price = 2.99m, MinDeliveryDays = 1, MaxDeliveryDays = 2, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, new ShippingRate { Id = Guid.NewGuid(), Name = "Royal Mail Second Class", Description = "2-3 working days delivery", Country = "United Kingdom", MinWeight = 0, MaxWeight = 100, Price = 1.99m, MinDeliveryDays = 2, MaxDeliveryDays = 3, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, new ShippingRate { Id = Guid.NewGuid(), Name = "Royal Mail Small Parcel", Description = "For items up to 2kg", Country = "United Kingdom", MinWeight = 100, MaxWeight = 2000, Price = 4.99m, MinDeliveryDays = 1, MaxDeliveryDays = 3, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, new ShippingRate { Id = Guid.NewGuid(), Name = "Royal Mail Medium Parcel", Description = "For items 2kg to 10kg", Country = "United Kingdom", MinWeight = 2000, MaxWeight = 10000, Price = 8.99m, MinDeliveryDays = 1, MaxDeliveryDays = 3, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }, new ShippingRate { Id = Guid.NewGuid(), Name = "Express Delivery", Description = "Guaranteed next day delivery", Country = "United Kingdom", MinWeight = 0, MaxWeight = 30000, Price = 14.99m, MinDeliveryDays = 1, MaxDeliveryDays = 1, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow } }; _context.ShippingRates.AddRange(shippingRates); await _context.SaveChangesAsync(); _logger.LogInformation("Created {Count} shipping rates", shippingRates.Count); // Create Sample Orders with different statuses var orders = new List { // Order 1: Pending Payment new Order { Id = Guid.NewGuid(), IdentityReference = "CUST001", Status = OrderStatus.PendingPayment, TotalAmount = 109.98m, Currency = "GBP", ShippingName = "John Smith", ShippingAddress = "123 High Street", ShippingCity = "London", ShippingPostCode = "SW1A 1AA", ShippingCountry = "United Kingdom", Notes = "Please leave with neighbor if not home", CreatedAt = DateTime.UtcNow.AddDays(-5), UpdatedAt = DateTime.UtcNow.AddDays(-5) }, // Order 2: Payment Received new Order { Id = Guid.NewGuid(), IdentityReference = "CUST002", Status = OrderStatus.PaymentReceived, TotalAmount = 44.98m, Currency = "GBP", ShippingName = "Sarah Johnson", ShippingAddress = "456 Oak Avenue", ShippingCity = "Manchester", ShippingPostCode = "M1 2AB", ShippingCountry = "United Kingdom", Notes = null, CreatedAt = DateTime.UtcNow.AddDays(-3), UpdatedAt = DateTime.UtcNow.AddDays(-2), PaidAt = DateTime.UtcNow.AddDays(-2) }, // Order 3: Processing new Order { Id = Guid.NewGuid(), IdentityReference = "CUST003", Status = OrderStatus.Processing, TotalAmount = 84.98m, Currency = "GBP", ShippingName = "Michael Brown", ShippingAddress = "789 Park Lane", ShippingCity = "Birmingham", ShippingPostCode = "B1 1AA", ShippingCountry = "United Kingdom", Notes = "Gift wrapping requested", CreatedAt = DateTime.UtcNow.AddDays(-4), UpdatedAt = DateTime.UtcNow.AddDays(-1), PaidAt = DateTime.UtcNow.AddDays(-3) }, // Order 4: Shipped new Order { Id = Guid.NewGuid(), IdentityReference = "CUST004", Status = OrderStatus.Shipped, TotalAmount = 79.98m, Currency = "GBP", ShippingName = "Emma Wilson", ShippingAddress = "321 Queen Street", ShippingCity = "Liverpool", ShippingPostCode = "L1 1AA", ShippingCountry = "United Kingdom", Notes = "Express delivery", TrackingNumber = "RM123456789GB", CreatedAt = DateTime.UtcNow.AddDays(-7), UpdatedAt = DateTime.UtcNow.AddHours(-12), PaidAt = DateTime.UtcNow.AddDays(-6), ShippedAt = DateTime.UtcNow.AddHours(-12) }, // Order 5: Delivered new Order { Id = Guid.NewGuid(), IdentityReference = "CUST005", Status = OrderStatus.Delivered, TotalAmount = 34.99m, Currency = "GBP", ShippingName = "David Taylor", ShippingAddress = "555 Castle Road", ShippingCity = "Edinburgh", ShippingPostCode = "EH1 1AA", ShippingCountry = "United Kingdom", Notes = null, TrackingNumber = "RM987654321GB", CreatedAt = DateTime.UtcNow.AddDays(-10), UpdatedAt = DateTime.UtcNow.AddDays(-2), PaidAt = DateTime.UtcNow.AddDays(-9), ShippedAt = DateTime.UtcNow.AddDays(-7) } }; _context.Orders.AddRange(orders); await _context.SaveChangesAsync(); _logger.LogInformation("Created {Count} orders", orders.Count); // Create Order Items var orderItems = new List { // Order 1 items new OrderItem { Id = Guid.NewGuid(), OrderId = orders[0].Id, ProductId = products[0].Id, // Wireless Headphones Quantity = 1, UnitPrice = 89.99m, TotalPrice = 89.99m }, new OrderItem { Id = Guid.NewGuid(), OrderId = orders[0].Id, ProductId = products[1].Id, // Smartphone Case Quantity = 1, UnitPrice = 19.99m, TotalPrice = 19.99m }, // Order 2 items new OrderItem { Id = Guid.NewGuid(), OrderId = orders[1].Id, ProductId = products[2].Id, // T-Shirt Quantity = 1, UnitPrice = 24.99m, TotalPrice = 24.99m }, new OrderItem { Id = Guid.NewGuid(), OrderId = orders[1].Id, ProductId = products[1].Id, // Smartphone Case Quantity = 1, UnitPrice = 19.99m, TotalPrice = 19.99m }, // Order 3 items new OrderItem { Id = Guid.NewGuid(), OrderId = orders[2].Id, ProductId = products[2].Id, // T-Shirt Quantity = 2, UnitPrice = 24.99m, TotalPrice = 49.98m }, new OrderItem { Id = Guid.NewGuid(), OrderId = orders[2].Id, ProductId = products[4].Id, // Programming Book Quantity = 1, UnitPrice = 34.99m, TotalPrice = 34.99m }, // Order 4 items new OrderItem { Id = Guid.NewGuid(), OrderId = orders[3].Id, ProductId = products[3].Id, // Jeans Quantity = 1, UnitPrice = 59.99m, TotalPrice = 59.99m }, new OrderItem { Id = Guid.NewGuid(), OrderId = orders[3].Id, ProductId = products[1].Id, // Smartphone Case Quantity = 1, UnitPrice = 19.99m, TotalPrice = 19.99m }, // Order 5 items new OrderItem { Id = Guid.NewGuid(), OrderId = orders[4].Id, ProductId = products[4].Id, // Programming Book Quantity = 1, UnitPrice = 34.99m, TotalPrice = 34.99m } }; _context.OrderItems.AddRange(orderItems); await _context.SaveChangesAsync(); _logger.LogInformation("Created {Count} order items", orderItems.Count); // Create sample crypto payments for some orders var payments = new List { // Payment for Order 2 (Paid) new CryptoPayment { Id = Guid.NewGuid(), OrderId = orders[1].Id, Currency = CryptoCurrency.BTC, WalletAddress = "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh", RequiredAmount = 0.00089m, PaidAmount = 0.00089m, Status = PaymentStatus.Paid, BTCPayInvoiceId = "INV001", TransactionHash = "3a1b9e330afbe003e0f8c7d0e3c3f7e3a1b9e330afbe003e0", CreatedAt = DateTime.UtcNow.AddDays(-2).AddHours(-1), PaidAt = DateTime.UtcNow.AddDays(-2), ExpiresAt = DateTime.UtcNow.AddDays(-1) }, // Payment for Order 3 (Paid) new CryptoPayment { Id = Guid.NewGuid(), OrderId = orders[2].Id, Currency = CryptoCurrency.XMR, WalletAddress = "4AdUndXHHZ6cfufTMvppY6JwXNb9b1LoaGain57XbP", RequiredAmount = 0.45m, PaidAmount = 0.45m, Status = PaymentStatus.Paid, BTCPayInvoiceId = "INV002", TransactionHash = "7c4b5e440bfce113f1f9c8d1f4e4f8e7c4b5e440bfce113f1", CreatedAt = DateTime.UtcNow.AddDays(-3).AddHours(-2), PaidAt = DateTime.UtcNow.AddDays(-3), ExpiresAt = DateTime.UtcNow.AddDays(-2) }, // Payment for Order 4 (Paid) new CryptoPayment { Id = Guid.NewGuid(), OrderId = orders[3].Id, Currency = CryptoCurrency.USDT, WalletAddress = "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7", RequiredAmount = 79.98m, PaidAmount = 79.98m, Status = PaymentStatus.Paid, BTCPayInvoiceId = "INV003", TransactionHash = "0x9f2e5b550afe223c5e1f9c9d2f5e5f9f2e5b550afe223c5e1", CreatedAt = DateTime.UtcNow.AddDays(-6).AddHours(-1), PaidAt = DateTime.UtcNow.AddDays(-6), ExpiresAt = DateTime.UtcNow.AddDays(-5) } }; _context.CryptoPayments.AddRange(payments); await _context.SaveChangesAsync(); _logger.LogInformation("Created {Count} crypto payments", payments.Count); _logger.LogInformation("Sample data seeding completed successfully!"); } private async Task UpdateProductionStockAsync() { _logger.LogInformation("Updating production product stock levels..."); var productStockUpdates = new Dictionary { ["Wireless Noise-Cancelling Headphones"] = 25, ["Fast Wireless Charging Stand"] = 50, ["Ultra-Slim Power Bank 20,000mAh"] = 35, ["Premium Phone Case with MagSafe"] = 75, ["Premium Cotton T-Shirt"] = 100, ["Classic Denim Jeans"] = 60, ["Cozy Knit Sweater"] = 40, ["The Complete Guide to Cryptocurrency"] = 30, ["Modern Web Development Handbook"] = 25, ["Mindfulness and Productivity Journal"] = 45 }; foreach (var update in productStockUpdates) { var product = await _context.Products .FirstOrDefaultAsync(p => p.Name == update.Key); if (product != null) { var oldStock = product.StockQuantity; product.StockQuantity = update.Value; product.UpdatedAt = DateTime.UtcNow; _logger.LogInformation("Updated stock for {Product} from {OldStock} to {NewStock}", product.Name, oldStock, update.Value); } else { _logger.LogWarning("Product not found: {ProductName}", update.Key); } } await _context.SaveChangesAsync(); _logger.LogInformation("Production stock update completed!"); } }