<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\Inventory;
use App\Models\Brand;
use App\Models\Category;
use App\Models\Supplier;
use App\Models\User;
use App\Models\Setting;
use App\Models\Purchase;
use App\Models\PurchaseItem;
use App\Models\InventoryItem;
use App\Models\Customer;
use App\Models\Order; // 👈 make sure this exists
use Illuminate\Support\Str;
use Faker\Factory as Faker;

class InventorySeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $faker = Faker::create();

        $brands = Brand::pluck('id')->toArray();
        $categories = Category::pluck('id')->toArray();
        $suppliers = Supplier::pluck('id')->toArray();

        $colors = ['Black', 'White', 'Blue', 'Red', 'Green', 'Gray', 'Gold'];
        $storageOptions = ['32GB', '64GB', '128GB', '256GB', '512GB'];
        $ramOptions = ['2GB', '3GB', '4GB', '6GB', '8GB', '12GB'];
        $conditions = ['new', 'refurbished', 'used'];
        $statuses = ['available', 'out_of_stock', 'discontinued'];
        $processors = ['Snapdragon', 'MediaTek Helio', 'Apple A-Series', 'Exynos'];
        $os = ['Android', 'iOS', 'HarmonyOS'];

        /*
        |--------------------------------------------------------------------------
        | 1) INVENTORY (20 PRODUCTS)
        |--------------------------------------------------------------------------
        */
        for ($i = 1; $i <= 2; $i++) {

            $brand_id = $faker->randomElement($brands);
            $category_id = $faker->randomElement($categories);

            // ----- PRICE LOGIC (ROUND THOUSANDS + PROFIT) -----

            // Base purchase price in thousands (e.g. 20–200 => 20,000–200,000)
            $purchaseThousands = $faker->numberBetween(20, 200);
            $purchase_price = $purchaseThousands * 1000;

            // Profit margin between 5% and 30%
            $marginPercent = $faker->numberBetween(5, 30);
            $rawSelling = $purchase_price * (1 + $marginPercent / 100);

            // Round selling price to nearest thousand
            $selling_price = round($rawSelling / 1000) * 1000;

            // Ensure selling price > purchase price
            if ($selling_price <= $purchase_price) {
                $selling_price = $purchase_price + 1000;
            }

            // Wholesale price between purchase and selling, closer to purchase
            $wholesaleMin = $purchase_price + 1000;
            $wholesaleMax = $selling_price - 1000;

            if ($wholesaleMax <= $wholesaleMin) {
                $wholesale_price = $purchase_price + 1000;
            } else {
                $wholesaleThousands = $faker->numberBetween(
                    (int)($wholesaleMin / 1000),
                    (int)($wholesaleMax / 1000)
                );

                $wholesale_price = $wholesaleThousands * 1000;
            }

            // --------------------------------------------------

            Inventory::create([
                'sku' => strtoupper(Str::random(10)),
                'brand_id' => $brand_id,
                'category_id' => $category_id,
                'model' => $faker->unique()->bothify('Model ###'),
                'color' => $faker->randomElement($colors),
                'storage' => $faker->randomElement($storageOptions),
                'ram' => $faker->randomElement($ramOptions),

                'purchase_price' => $purchase_price,
                'selling_price' => $selling_price,
                'wholesale_price' => $wholesale_price,

                'minimum_stock' => $faker->numberBetween(3, 10),
                'description' => $faker->sentence(12),
                'condition' => $faker->randomElement($conditions),
                'warranty_period' => $faker->randomElement(['6 Months', '1 Year', 'No Warranty']),
                'camera' => $faker->numberBetween(8, 108) . ' MP',
                'battery' => $faker->numberBetween(2500, 6000) . ' mAh',
                'screen_size' => $faker->randomElement(['5.5"', '6.1"', '6.5"', '6.7"']),
                'processor' => $faker->randomElement($processors),
                'operating_system' => $faker->randomElement($os),
                'supplier_id' => $faker->optional()->randomElement($suppliers),
                'status' => $faker->randomElement($statuses),
                'is_active' => true,
                // if you have quantity column, it will be updated during purchases
            ]);
        }

        echo "✅ 20 inventory items added with realistic, profitable pricing!\n";

        /*
        |--------------------------------------------------------------------------
        | 2) PURCHASES, PURCHASE ITEMS & INVENTORY ITEMS (IMEI LEVEL)
        |--------------------------------------------------------------------------
        */

        $inventories = Inventory::all();
        if ($inventories->count() === 0 || empty($suppliers)) {
            echo "⚠️ Skipping purchases: no inventory or suppliers found.\n";
            return;
        }

        // Get admin user for created_by
        $adminId = User::where('role', 'admin')->value('id') ?? User::first()->id;

        // Purchase number prefix from settings (fallback PUR)
        $prefix = Setting::where('key', 'purchase_prefix')->value('value') ?? 'PUR';
        $lastPurchaseId = Purchase::max('id') ?? 0;

        $numberOfPurchases = 500;

        for ($p = 1; $p <= $numberOfPurchases; $p++) {

            $purchaseNumber = $prefix . '-' . str_pad($lastPurchaseId + $p, 4, '0', STR_PAD_LEFT);
            $purchaseDate = now()->subDays($faker->numberBetween(10, 40))->toDateString();
            $supplierId = $faker->randomElement($suppliers);

            // Choose 2–4 random inventory products for this purchase
            // $itemsForPurchase = $inventories->random($faker->numberBetween(2, 4));
            $itemsForPurchase = $inventories->random($faker->numberBetween(1,2));

            // Calculate subtotal from items
            $subtotal = 0;
            $itemsData = [];

            foreach ($itemsForPurchase as $inv) {
                $qty = $faker->numberBetween(1, 5); // quantity per line
                $unitPrice = $inv->purchase_price;
                $lineSubtotal = $qty * $unitPrice;
                $subtotal += $lineSubtotal;

                $itemsData[] = [
                    'inventory'     => $inv,
                    'quantity'      => $qty,
                    'unit_price'    => $unitPrice,
                    'line_subtotal' => $lineSubtotal,
                ];
            }

            $taxAmount = 0;
            $discount = 0;
            $totalAmount = $subtotal + $taxAmount - $discount;

            // Create Purchase
            $purchase = Purchase::create([
                'purchase_number'  => $purchaseNumber,
                'supplier_id'      => $supplierId,
                'created_by'       => $adminId,
                'purchase_date'    => $purchaseDate,
                'subtotal'         => $subtotal,
                'tax_amount'       => $taxAmount,
                'discount'         => $discount,
                'total_amount'     => $totalAmount,
                'paid_amount'      => 0,
                'due_amount'       => $totalAmount,
                'payment_status'   => 'pending',
                'status'           => 'completed',
                'reference_number' => 'REF-' . Str::upper(Str::random(6)),
                'notes'            => $faker->sentence(8),
            ]);

            // Create PurchaseItems & InventoryItems (per-device IMEIs)
            foreach ($itemsData as $item) {
                /** @var \App\Models\Inventory $inventory */
                $inventory = $item['inventory'];
                $qty = $item['quantity'];
                $unitPrice = $item['unit_price'];
                $lineSubtotal = $item['line_subtotal'];

                $purchaseItem = PurchaseItem::create([
                    'purchase_id'  => $purchase->id,
                    'inventory_id' => $inventory->id,
                    'quantity'     => $qty,
                    'unit_price'   => $unitPrice,
                    'subtotal'     => $lineSubtotal,
                    'is_device'    => 1,
                ]);

                // Update aggregate inventory quantity & status
                // if (isset($inventory->quantity)) {
                //     $inventory->quantity = ($inventory->quantity ?? 0) + $qty;

                //     if ($inventory->quantity > 0 && $inventory->status === 'out_of_stock') {
                //         $inventory->status = 'available';
                //     }
                // }

                // Keep purchase_price in sync
                $inventory->purchase_price = $unitPrice;
                $inventory->save();

                // Create per-device InventoryItem rows with fake IMEIs
                for ($iDev = 1; $iDev <= $qty; $iDev++) {
                    $imei1 = $faker->numerify('###############'); // 15 digits
                    $imei2 = $faker->numerify('###############');

                    InventoryItem::create([
                        'inventory_id'         => $inventory->id,
                        'purchase_item_id'     => $purchaseItem->id,
                        'imei_1'               => $imei1,
                        'imei_2'               => $imei2,
                        'serial_number'        => strtoupper(Str::random(12)),

                        'color'                => $inventory->color,
                        'storage'              => $inventory->storage,
                        'ram'                  => $inventory->ram,

                        'purchase_price'       => $unitPrice,
                        'selling_price'        => $inventory->selling_price,

                        'supplier_id'          => $supplierId,
                        'purchase_date'        => $purchaseDate,

                        'condition'            => $inventory->condition ?? 'new',
                        'warranty_months'      => $faker->randomElement([0, 3, 6, 12]),
                        'warranty_expiry_date' => null,

                        'status'               => 'available',
                        'location'             => $faker->randomElement(['Main Store', 'Branch 1', 'Warehouse']),

                        'sold_date'            => null,
                        'customer_id'          => null,

                        'notes'                => $faker->boolean(20) ? $faker->sentence(6) : null,
                        'is_active'            => true,
                    ]);
                }
            }
        }

        echo "✅ {$numberOfPurchases} purchases with items & per-device inventory items created!\n";

        /*
        |--------------------------------------------------------------------------
        | 3) ORDERS (SELLING SOME DEVICES, RESERVING THEM)
        |--------------------------------------------------------------------------
        */

        // $customers = Customer::pluck('id')->toArray();
        // $availableDevices = InventoryItem::where('status', 'available')->get();
        // $totalDevices = $availableDevices->count();

        // if ($totalDevices === 0) {
        //     echo "⚠️ Skipping orders: no available devices found.\n";
        //     return;
        // }

        // $numberOfOrders = 80; // how many orders to create
        // $deviceIndex = 0;

        // $paymentStatuses = [
        //     'unpaid',
        //     'unpaid',
        //     'partial',
        //     'paid',
        //     'paid',
        //     'refunded',
        // ];

        // for ($o = 1; $o <= $numberOfOrders; $o++) {
        //     if ($deviceIndex >= $totalDevices) {
        //         break; // no more devices to sell/reserve
        //     }

        //     // Random how many devices in this order (1–3), but don't exceed remaining devices
        //     $itemsCount = min($faker->numberBetween(1, 3), $totalDevices - $deviceIndex);

        //     $orderDevices = $availableDevices->slice($deviceIndex, $itemsCount);
        //     $deviceIndex += $itemsCount;

        //     $orderDate = now()->subDays($faker->numberBetween(0, 10))->toDateString();
        //     $dueDate = $faker->boolean(60)
        //         ? now()->subDays($faker->numberBetween(-1, -7))->toDateString() // few days after order
        //         : null;

        //     $customerId = !empty($customers)
        //         ? ($faker->boolean(80) ? $faker->randomElement($customers) : null) // some walk-in (null)
        //         : null;

        //     $paymentStatus = $faker->randomElement($paymentStatuses);

        //     $orderNumber = 'SO-' . now()->format('YmdHis') . '-' . Str::upper(Str::random(4));

        //     $order = Order::create([
        //         'order_number'   => $orderNumber,
        //         'customer_id'    => $customerId,
        //         'order_date'     => $orderDate,
        //         'due_date'       => $dueDate,
        //         'status'         => 'confirmed',
        //         'payment_status' => $paymentStatus,
        //         'notes'          => $faker->boolean(40) ? $faker->sentence(8) : null,
        //     ]);

        //     $subTotal = 0;
        //     $discountTotal = 0;
        //     $taxTotal = 0;

        //     foreach ($orderDevices as $device) {
        //         /** @var InventoryItem $device */
        //         $unitPrice = $device->selling_price; // selling price from inventory item
        //         $qty = 1;

        //         // Keep discount and tax realistic (and in round thousands)
        //         $maxDiscountThousands = max(0, (int)floor($unitPrice / 1000) - 5); // don't kill margin
        //         $discountThousands = $maxDiscountThousands > 0
        //             ? $faker->numberBetween(0, min(3, $maxDiscountThousands))
        //             : 0;

        //         $discountAmount = $discountThousands * 1000;

        //         // Simple tax (0 or 1000/2000)
        //         $taxAmount = $faker->randomElement([0, 0, 1000, 2000]);

        //         if ($discountAmount > $unitPrice) {
        //             $discountAmount = 0;
        //         }

        //         $lineTotal = ($unitPrice * $qty) - $discountAmount + $taxAmount;

        //         $description = $device->inventory
        //             ? ($device->inventory->model . ' ' . ($device->storage ?? ''))
        //             : 'Device';

        //         $order->items()->create([
        //             'inventory_id'      => $device->inventory_id,
        //             'inventory_item_id' => $device->id,
        //             'description'       => $description,
        //             'qty'               => $qty,
        //             'unit_price'        => $unitPrice,
        //             'discount_amount'   => $discountAmount,
        //             'tax_amount'        => $taxAmount,
        //             'total'             => $lineTotal,
        //         ]);

        //         // Reserve device (same as controller)
        //         $device->update([
        //             'status'      => 'sold',
        //             'customer_id' => $customerId,
        //             'sold_date'   => now(),
        //         ]);

        //         $subTotal      += ($unitPrice * $qty);
        //         $discountTotal += $discountAmount;
        //         $taxTotal      += $taxAmount;
        //     }

        //     $grandTotal = $subTotal - $discountTotal + $taxTotal;

        //     $order->update([
        //         'sub_total'      => $subTotal,
        //         'discount_total' => $discountTotal,
        //         'tax_total'      => $taxTotal,
        //         'grand_total'    => $grandTotal,
        //     ]);
        // }

        // echo "✅ {$numberOfOrders} orders created using real devices (inventory_items)!\n";
    }
}
