<?php

namespace Database\Seeders;

use App\Models\Branch;
use App\Models\BranchProduct;
use App\Models\Category;
use App\Models\Ingredient;
use App\Models\InnerOptionSet;
use App\Models\InnerOptionItem;
use App\Models\OptionSet;
use App\Models\OptionSetItem;
use App\Models\Product;
use App\Models\Recipe;
use App\Models\RecipeIngredient;
use App\Models\StockLedger;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;

class BananaMilkshakeSeeder extends Seeder
{
    /**
     * Seed a complete Banana Milkshake product with all related data.
     *
     * This creates:
     * - Category: Milkshakes
     * - Ingredients: Banana, Milk, Ice Cream Base, Sugar, Vanilla Extract
     * - Recipe: Banana Milkshake Recipe
     * - Option Set: Milkshake Sizes (Small, Medium, Large)
     * - Inner Option Set: Milkshake Add-ons (Whipped Cream, Chocolate Syrup, Extra Banana)
     * - Product: Banana Milkshake with options
     * - Stock for all ingredients at branch 1
     * - Product availability at branch 1
     */
    public function run(): void
    {
        $this->command->info('Creating Banana Milkshake product with complete flow...');

        // Get the first branch and user
        $branch = Branch::first();
        $user = User::first();

        if (!$branch || !$user) {
            $this->command->error('Please ensure at least one branch and user exist before running this seeder.');
            return;
        }

        // 1. Create Category
        $this->command->info('1. Creating Milkshakes category...');
        $category = Category::firstOrCreate(
            ['slug' => 'milkshakes'],
            [
                'name' => 'Milkshakes',
                'description' => 'Delicious blended milkshakes',
                'is_active' => true,
                'sort_order' => 2,
            ]
        );

        // 2. Create Ingredients
        $this->command->info('2. Creating ingredients...');
        $ingredients = [
            'banana' => Ingredient::firstOrCreate(
                ['sku' => 'ING-BANANA'],
                [
                    'name' => 'Banana',
                    'unit' => 'Piece',
                    'cost_per_unit' => 15.00,
                    'minimum_stock' => 20,
                    'reorder_level' => 50,
                    'is_active' => true,
                ]
            ),
            'milk' => Ingredient::firstOrCreate(
                ['sku' => 'ING-MILK'],
                [
                    'name' => 'Milk',
                    'unit' => 'Liter',
                    'cost_per_unit' => 80.00,
                    'minimum_stock' => 10,
                    'reorder_level' => 20,
                    'is_active' => true,
                ]
            ),
            'ice_cream_base' => Ingredient::firstOrCreate(
                ['sku' => 'ING-ICBASE'],
                [
                    'name' => 'Vanilla Ice Cream Base',
                    'unit' => 'Kg',
                    'cost_per_unit' => 200.00,
                    'minimum_stock' => 5,
                    'reorder_level' => 10,
                    'is_active' => true,
                ]
            ),
            'sugar' => Ingredient::firstOrCreate(
                ['sku' => 'ING-SUGAR'],
                [
                    'name' => 'Sugar',
                    'unit' => 'Kg',
                    'cost_per_unit' => 60.00,
                    'minimum_stock' => 5,
                    'reorder_level' => 10,
                    'is_active' => true,
                ]
            ),
            'vanilla_extract' => Ingredient::firstOrCreate(
                ['sku' => 'ING-VANILLA'],
                [
                    'name' => 'Vanilla Extract',
                    'unit' => 'ml',
                    'cost_per_unit' => 0.50,
                    'minimum_stock' => 100,
                    'reorder_level' => 200,
                    'is_active' => true,
                ]
            ),
            'whipped_cream' => Ingredient::firstOrCreate(
                ['sku' => 'ING-WHIPCREAM'],
                [
                    'name' => 'Whipped Cream',
                    'unit' => 'Liter',
                    'cost_per_unit' => 150.00,
                    'minimum_stock' => 2,
                    'reorder_level' => 5,
                    'is_active' => true,
                ]
            ),
            'chocolate_syrup' => Ingredient::firstOrCreate(
                ['sku' => 'ING-CHOCSYRUP'],
                [
                    'name' => 'Chocolate Syrup',
                    'unit' => 'Liter',
                    'cost_per_unit' => 120.00,
                    'minimum_stock' => 2,
                    'reorder_level' => 5,
                    'is_active' => true,
                ]
            ),
        ];

        // 3. Create Product
        $this->command->info('3. Creating Banana Milkshake product...');
        $product = Product::firstOrCreate(
            ['slug' => 'banana-milkshake'],
            [
                'category_id' => $category->id,
                'name' => 'Banana Milkshake',
                'description' => 'Creamy banana milkshake made with fresh bananas and vanilla ice cream',
                'base_price' => 180.00, // Base selling price
                'scoop_price' => null,  // Not sold by scoop
                'max_scoops' => 0,      // Not applicable for milkshakes
                'is_active' => true,
            ]
        );

        // 4. Create Recipe
        $this->command->info('4. Creating recipe...');
        $recipe = Recipe::firstOrCreate(
            ['product_id' => $product->id],
            [
                'name' => 'Banana Milkshake Recipe',
                'description' => 'Classic banana milkshake - blend all ingredients until smooth',
                'instructions' => "1. Add milk to blender\n2. Add ice cream base\n3. Add banana pieces\n4. Add sugar and vanilla\n5. Blend until smooth\n6. Serve in tall glass",
                'yield_quantity' => 1, // Makes 1 serving
                'is_active' => true,
            ]
        );

        // 5. Create Recipe Ingredients
        $this->command->info('5. Adding recipe ingredients...');
        $recipeIngredients = [
            ['ingredient' => $ingredients['banana'], 'quantity' => 1.5, 'unit' => 'Piece', 'notes' => 'Fresh ripe bananas'],
            ['ingredient' => $ingredients['milk'], 'quantity' => 0.2, 'unit' => 'Liter', 'notes' => '200ml milk'],
            ['ingredient' => $ingredients['ice_cream_base'], 'quantity' => 0.1, 'unit' => 'Kg', 'notes' => '100g ice cream'],
            ['ingredient' => $ingredients['sugar'], 'quantity' => 0.02, 'unit' => 'Kg', 'notes' => '20g sugar'],
            ['ingredient' => $ingredients['vanilla_extract'], 'quantity' => 5, 'unit' => 'ml', 'notes' => 'A few drops'],
        ];

        foreach ($recipeIngredients as $ri) {
            RecipeIngredient::firstOrCreate(
                [
                    'recipe_id' => $recipe->id,
                    'ingredient_id' => $ri['ingredient']->id,
                ],
                [
                    'quantity' => $ri['quantity'],
                    'unit' => $ri['unit'],
                    'notes' => $ri['notes'],
                ]
            );
        }

        // 6. Create Option Set (Sizes)
        $this->command->info('6. Creating Milkshake Sizes option set...');
        $sizeOptionSet = OptionSet::firstOrCreate(
            ['name' => 'Milkshake Size'],
            [
                'type' => 'size',
                'is_required' => true,
                'min_select' => 1,
                'max_select' => 1,
                'is_active' => true,
            ]
        );

        $sizes = [
            ['name' => 'Regular (300ml)', 'price_modifier' => 0.00, 'is_default' => true, 'sort_order' => 1],
            ['name' => 'Medium (450ml)', 'price_modifier' => 40.00, 'is_default' => false, 'sort_order' => 2],
            ['name' => 'Large (600ml)', 'price_modifier' => 80.00, 'is_default' => false, 'sort_order' => 3],
        ];

        foreach ($sizes as $size) {
            OptionSetItem::firstOrCreate(
                [
                    'option_set_id' => $sizeOptionSet->id,
                    'name' => $size['name'],
                ],
                [
                    'price_modifier' => $size['price_modifier'],
                    'is_default' => $size['is_default'],
                    'is_active' => true,
                    'sort_order' => $size['sort_order'],
                ]
            );
        }

        // 7. Create Inner Option Set (Add-ons)
        $this->command->info('7. Creating Milkshake Add-ons inner option set...');
        $addonsOptionSet = InnerOptionSet::firstOrCreate(
            ['name' => 'Milkshake Add-ons'],
            [
                'type' => 'topping', // Using topping type for add-ons
                'is_active' => true,
            ]
        );

        $addons = [
            ['name' => 'Whipped Cream', 'price' => 25.00, 'sort_order' => 1],
            ['name' => 'Chocolate Syrup', 'price' => 20.00, 'sort_order' => 2],
            ['name' => 'Extra Banana', 'price' => 30.00, 'sort_order' => 3],
            ['name' => 'Oreo Crumbs', 'price' => 35.00, 'sort_order' => 4],
            ['name' => 'Caramel Drizzle', 'price' => 25.00, 'sort_order' => 5],
        ];

        foreach ($addons as $addon) {
            InnerOptionItem::firstOrCreate(
                [
                    'inner_option_set_id' => $addonsOptionSet->id,
                    'name' => $addon['name'],
                ],
                [
                    'price' => $addon['price'],
                    'is_active' => true,
                    'sort_order' => $addon['sort_order'],
                ]
            );
        }

        // 8. Attach Option Sets to Product
        $this->command->info('8. Attaching option sets to product...');
        $product->optionSets()->syncWithoutDetaching([$sizeOptionSet->id]);
        $product->innerOptionSets()->syncWithoutDetaching([$addonsOptionSet->id]);

        // 9. Create Stock for Ingredients at Branch
        $this->command->info('9. Creating stock entries at branch...');
        foreach ($ingredients as $key => $ingredient) {
            $stockQuantity = match($key) {
                'banana' => 100,       // 100 pieces
                'milk' => 50,          // 50 liters
                'ice_cream_base' => 20, // 20 kg
                'sugar' => 25,         // 25 kg
                'vanilla_extract' => 500, // 500 ml
                'whipped_cream' => 10, // 10 liters
                'chocolate_syrup' => 10, // 10 liters
                default => 50,
            };

            StockLedger::updateOrCreate(
                [
                    'branch_id' => $branch->id,
                    'ingredient_id' => $ingredient->id,
                ],
                [
                    'quantity' => $stockQuantity,
                    'average_cost' => $ingredient->cost_per_unit,
                ]
            );
        }

        // 10. Make Product Available at Branch
        $this->command->info('10. Making product available at branch...');
        BranchProduct::updateOrCreate(
            [
                'branch_id' => $branch->id,
                'product_id' => $product->id,
            ],
            [
                'is_available' => true,
                'custom_price' => null, // Use base price
            ]
        );

        // Summary
        $this->command->newLine();
        $this->command->info('=== Banana Milkshake Product Created Successfully! ===');
        $this->command->table(
            ['Item', 'Details'],
            [
                ['Category', $category->name],
                ['Product', $product->name],
                ['Base Price', 'Rs ' . number_format($product->base_price, 2)],
                ['Recipe', $recipe->name],
                ['Ingredients', count($recipeIngredients) . ' items'],
                ['Size Options', implode(', ', array_column($sizes, 'name'))],
                ['Add-ons', implode(', ', array_column($addons, 'name'))],
                ['Available at', $branch->name],
            ]
        );

        // Calculate cost per serving
        $costPerServing = 0;
        foreach ($recipeIngredients as $ri) {
            $costPerServing += $ri['quantity'] * $ri['ingredient']->cost_per_unit;
        }
        $profit = $product->base_price - $costPerServing;
        $margin = ($profit / $product->base_price) * 100;

        $this->command->newLine();
        $this->command->info('=== Cost Analysis ===');
        $this->command->table(
            ['Metric', 'Value'],
            [
                ['Cost per Serving', 'Rs ' . number_format($costPerServing, 2)],
                ['Selling Price', 'Rs ' . number_format($product->base_price, 2)],
                ['Profit per Serving', 'Rs ' . number_format($profit, 2)],
                ['Profit Margin', number_format($margin, 1) . '%'],
            ]
        );

        $this->command->newLine();
        $this->command->info('You can now place orders for Banana Milkshake in POS!');
    }
}
