<?php

namespace Database\Seeders;

use App\Models\PackSize;
use App\Models\Product;
use App\Models\StockIn;
use App\Models\StockOut;
use App\Models\Order;
use App\Models\OrderDetail;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
use Carbon\Carbon;

class TestDataSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        // Clear existing test data (optional - comment out if you want to keep existing data)
        // OrderDetail::truncate();
        // Order::truncate();
        // StockOut::truncate();
        // StockIn::truncate();
        // Product::truncate();
        // PackSize::truncate();

        // 1. Create Pack Sizes
        $packSizes = [
            ['name' => 'Small Pack', 'quantity' => 12, 'description' => '12 bottles per pack'],
            ['name' => 'Medium Pack', 'quantity' => 24, 'description' => '24 bottles per pack'],
            ['name' => 'Large Pack', 'quantity' => 48, 'description' => '48 bottles per pack'],
            ['name' => 'Family Pack', 'quantity' => 72, 'description' => '72 bottles per pack'],
        ];

        $createdPackSizes = [];
        foreach ($packSizes as $packSizeData) {
            $packSize = PackSize::create($packSizeData);
            $createdPackSizes[] = $packSize;
        }

        // 2. Create Products
        $products = [
            ['name' => 'Natural Spring Water', 'pack_size_id' => $createdPackSizes[0]->id, 'status' => 1],
            ['name' => 'Mineral Water', 'pack_size_id' => $createdPackSizes[1]->id, 'status' => 1],
            ['name' => 'Purified Water', 'pack_size_id' => $createdPackSizes[0]->id, 'status' => 1],
            ['name' => 'Sparkling Water', 'pack_size_id' => $createdPackSizes[2]->id, 'status' => 1],
            ['name' => 'Alkaline Water', 'pack_size_id' => $createdPackSizes[1]->id, 'status' => 1],
            ['name' => 'Distilled Water', 'pack_size_id' => $createdPackSizes[0]->id, 'status' => 1],
            ['name' => 'Premium Spring Water', 'pack_size_id' => $createdPackSizes[3]->id, 'status' => 1],
            ['name' => 'Flavored Water - Lemon', 'pack_size_id' => $createdPackSizes[1]->id, 'status' => 1],
        ];

        $createdProducts = [];
        foreach ($products as $productData) {
            $product = Product::create($productData);
            $createdProducts[] = $product;
        }

        // 3. Create Stock In records (purchases over the past 3 months)
        $stockInDates = [];
        $now = Carbon::now();
        
        // Generate stock in dates over past 3 months
        for ($i = 0; $i < 90; $i++) {
            $date = $now->copy()->subDays($i);
            if ($date->dayOfWeek == Carbon::MONDAY || $date->dayOfWeek == Carbon::WEDNESDAY || $date->dayOfWeek == Carbon::FRIDAY) {
                $stockInDates[] = $date;
            }
        }

        foreach ($createdProducts as $product) {
            $packSize = $product->packSize;
            $bottlesPerPack = $packSize->quantity;
            
            // Base unit price (cost per bottle)
            $baseUnitPrice = rand(50, 150) / 100; // £0.50 to £1.50 per bottle
            
            // Create stock in records
            $stockInCount = rand(5, 15); // 5-15 stock in records per product
            $selectedDates = collect($stockInDates)->random($stockInCount)->sort();
            
            foreach ($selectedDates as $date) {
                $quantity = rand(20, 100); // 20-100 packs
                $unitPrice = $baseUnitPrice + (rand(-10, 10) / 100); // Slight variation
                $totalPrice = $quantity * $bottlesPerPack * $unitPrice;
                
                StockIn::create([
                    'product_id' => $product->id,
                    'quantity' => $quantity * $bottlesPerPack, // Store as bottles
                    'total_price' => round($totalPrice, 2),
                    'unit_price' => round($unitPrice, 2),
                    'created_at' => $date->copy()->setTime(rand(9, 17), rand(0, 59)),
                    'created_by' => 1, // Added
                ]);
            }
        }

        // 4. Create Stock Out records (move stock to available inventory)
        foreach ($createdProducts as $product) {
            $totalStockIn = StockIn::where('product_id', $product->id)->sum('quantity');
            // Move 70-90% of stock in to stock out (available for sale)
            $stockOutQuantity = (int)($totalStockIn * (rand(70, 90) / 100));
            
            if ($stockOutQuantity > 0) {
                // Create stock out in batches
                $batches = rand(3, 8);
                $perBatch = (int)($stockOutQuantity / $batches);
                
                for ($i = 0; $i < $batches; $i++) {
                    $date = $now->copy()->subDays(rand(60, 90));
                    StockOut::create([
                        'product_id' => $product->id,
                        'quantity' => $i === $batches - 1 ? $stockOutQuantity - ($perBatch * ($batches - 1)) : $perBatch,
                        'stock_out_date' => $date->format('Y-m-d'),
                        'created_at' => $date,
                        'created_by' => 1, // Added
                    ]);
                }
            }
        }

        // 5. Create Orders and OrderDetails (sales over past 2 months)
        $orderDates = [];
        for ($i = 0; $i < 60; $i++) {
            $date = $now->copy()->subDays($i);
            // Create orders on most days, but more on weekdays
            if (rand(1, 10) <= 8) {
                $orderDates[] = $date;
            }
        }

        foreach ($orderDates as $orderDate) {
            // Number of orders per day (1-5)
            $ordersPerDay = rand(1, 5);
            
            for ($o = 0; $o < $ordersPerDay; $o++) {
                // Select random products for this order (1-4 products)
                $orderProducts = collect($createdProducts)->random(rand(1, 4));
                
                $orderItems = [];
                $subTotal = 0;
                
                foreach ($orderProducts as $product) {
                    $packSize = $product->packSize;
                    $bottlesPerPack = $packSize->quantity;
                    
                    // Get recent stock in price for this product
                    $recentStockIn = StockIn::where('product_id', $product->id)
                        ->where('created_at', '<=', $orderDate)
                        ->latest('created_at')
                        ->first();
                    
                    $costPerBottle = $recentStockIn ? $recentStockIn->unit_price : 1.00;
                    $sellingPricePerPack = ($costPerBottle * $bottlesPerPack) * (1.3 + (rand(0, 20) / 100)); // 30-50% markup
                    
                    $quantity = rand(1, 10); // 1-10 packs
                    $itemTotal = $quantity * $sellingPricePerPack;
                    $subTotal += $itemTotal;
                    
                    $orderItems[] = [
                        'sku' => $product->id,
                        'name' => $product->name,
                        'pack_count' => $quantity,
                        'quantity' => $quantity,
                        'unit_price' => round($sellingPricePerPack, 2),
                        'price' => round($sellingPricePerPack, 2),
                        'total_price' => round($itemTotal, 2),
                        'pack_size' => [
                            'id' => $packSize->id,
                            'name' => $packSize->name,
                            'bottle_quantity' => $bottlesPerPack,
                        ],
                        'bottle_quantity' => $quantity * $bottlesPerPack,
                    ];
                }
                
                // Add charges (sometimes)
                $fuelCharges = rand(1, 10) <= 3 ? round(rand(5, 25), 2) : 0; // 30% chance
                $otherCharges = rand(1, 10) <= 2 ? round(rand(10, 50), 2) : 0; // 20% chance
                $total = $subTotal + $fuelCharges + $otherCharges;
                
                $order = Order::create([
                    'id' => Str::uuid(),
                    'sale_date' => $orderDate->format('Y-m-d'),
                    'order_snap' => $orderItems,
                    'fuel_charges' => $fuelCharges,
                    'other_charges' => $otherCharges,
                    'sub_total' => round($subTotal, 2),
                    'total' => round($total, 2),
                    'created_at' => $orderDate->copy()->setTime(rand(8, 20), rand(0, 59)),
                ]);
                
                // Create OrderDetails
                foreach ($orderItems as $item) {
                    $product = Product::find($item['sku']);
                    if ($product) {
                        $packSize = $product->packSize;
                        $bottleQuantity = $item['pack_count'] * $packSize->quantity;
                        
                        OrderDetail::create([
                            'id' => Str::uuid(),
                            'order_id' => $order->id,
                            'product_id' => $product->id,
                            'unit_price' => $item['unit_price'],
                            'total_price' => $item['total_price'],
                            'qty' => $bottleQuantity, // Store as bottles
                            'created_at' => $order->created_at,
                        ]);
                    }
                }
            }
        }

        $this->command->info('Test data seeded successfully!');
        $this->command->info('Created:');
        $this->command->info('- ' . count($createdPackSizes) . ' Pack Sizes');
        $this->command->info('- ' . count($createdProducts) . ' Products');
        $this->command->info('- ' . StockIn::count() . ' Stock In records');
        $this->command->info('- ' . StockOut::count() . ' Stock Out records');
        $this->command->info('- ' . Order::count() . ' Orders');
        $this->command->info('- ' . OrderDetail::count() . ' Order Details');
    }
}

