<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use App\Models\Store;
use App\Models\RawMaterial;
use App\Models\ItemConversion;
use App\Models\CurrentStock;
use App\Models\User;

class ItemConversionAndStockSeeder extends Seeder
{
    /**
     * Run the database seeder for Item Conversions and Current Stocks.
     * This seeder creates realistic test data for SO (Stock Opname) testing.
     */
    public function run(): void
    {
        DB::beginTransaction();
        
        try {
            $this->command->info('Starting Item Conversion and Stock Data Seeder...');

            // Get first user as creator
            $userId = User::first()->id ?? 1;

            // Get all active stores and raw materials
            $stores = Store::where('delete_flag', 0)->get();
            $rawMaterials = RawMaterial::where('delete_flag', 0)->get();

            if ($stores->isEmpty()) {
                $this->command->warn('No stores found. Please run master data seeders first.');
                DB::rollback();
                return;
            }

            if ($rawMaterials->isEmpty()) {
                $this->command->warn('No raw materials found. Please run master data seeders first.');
                DB::rollback();
                return;
            }

            // 1. Create Item Conversions
            $this->command->info('Creating Item Conversions...');
            $conversionCount = 0;

            // Define common UOM conversions
            $commonConversions = [
                // Dry goods (Kering)
                ['uom_utuh' => 'DS', 'uom_pakai' => 'KG', 'factor' => 25.0, 'notes' => '1 Dus = 25 Kg'],
                ['uom_utuh' => 'BX', 'uom_pakai' => 'KG', 'factor' => 10.0, 'notes' => '1 Box = 10 Kg'],
                ['uom_utuh' => 'SK', 'uom_pakai' => 'KG', 'factor' => 50.0, 'notes' => '1 Sak = 50 Kg'],
                ['uom_utuh' => 'PK', 'uom_pakai' => 'KG', 'factor' => 5.0, 'notes' => '1 Pack = 5 Kg'],
                ['uom_utuh' => 'KT', 'uom_pakai' => 'KG', 'factor' => 20.0, 'notes' => '1 Karton = 20 Kg'],
                
                // Liquids (Basah)
                ['uom_utuh' => 'JR', 'uom_pakai' => 'LT', 'factor' => 20.0, 'notes' => '1 Jerigen = 20 Liter'],
                ['uom_utuh' => 'GL', 'uom_pakai' => 'LT', 'factor' => 5.0, 'notes' => '1 Galon = 5 Liter'],
                ['uom_utuh' => 'BT', 'uom_pakai' => 'LT', 'factor' => 1.0, 'notes' => '1 Botol = 1 Liter'],
                ['uom_utuh' => 'DR', 'uom_pakai' => 'LT', 'factor' => 200.0, 'notes' => '1 Drum = 200 Liter'],
                
                // Small items
                ['uom_utuh' => 'BX', 'uom_pakai' => 'PC', 'factor' => 100.0, 'notes' => '1 Box = 100 Pieces'],
                ['uom_utuh' => 'PK', 'uom_pakai' => 'PC', 'factor' => 12.0, 'notes' => '1 Pack = 12 Pieces'],
            ];

            foreach ($rawMaterials as $rm) {
                // Check if conversion already exists
                $existingConversion = ItemConversion::where('raw_material_id', $rm->id)
                    ->where('delete_flag', 0)
                    ->first();

                if ($existingConversion) {
                    $this->command->info("  - Skipping {$rm->code}: conversion already exists");
                    continue;
                }

                // Select conversion based on material type
                $conversion = null;
                
                if ($rm->tipe_barang === 'Basah') {
                    // Wet type - use liquid conversions
                    $liquidConversions = array_filter($commonConversions, function($c) {
                        return $c['uom_pakai'] === 'LT';
                    });
                    $conversion = $liquidConversions[array_rand($liquidConversions)];
                } else {
                    // Dry type - use dry goods conversions
                    $dryConversions = array_filter($commonConversions, function($c) {
                        return in_array($c['uom_pakai'], ['KG', 'PC']);
                    });
                    $conversion = $dryConversions[array_rand($dryConversions)];
                }

                // Create item conversion
                ItemConversion::create([
                    'raw_material_id' => $rm->id,
                    'uom_utuh' => $conversion['uom_utuh'],
                    'uom_pakai' => $conversion['uom_pakai'],
                    'conversion_factor' => $conversion['factor'],
                    'notes' => $conversion['notes'],
                    'is_active' => true,
                    'delete_flag' => false,
                    'created_by' => $userId,
                    'updated_by' => $userId,
                ]);

                $conversionCount++;
                $this->command->info("  - Created conversion for {$rm->code}: {$conversion['notes']}");
            }

            // 2. Create Current Stocks (Last Stock)
            $this->command->info('Creating Current Stocks...');
            $stockCount = 0;

            foreach ($stores as $store) {
                $this->command->info("  Processing store: {$store->name}");
                
                foreach ($rawMaterials as $rm) {
                    // Get the conversion for this raw material
                    $conversion = ItemConversion::where('raw_material_id', $rm->id)
                        ->where('is_active', true)
                        ->where('delete_flag', false)
                        ->first();

                    if (!$conversion) {
                        $this->command->warn("    - No conversion found for {$rm->code}, skipping stock creation");
                        continue;
                    }

                    // Generate realistic stock levels
                    // 70% chance of having stock, 30% chance of zero stock
                    $hasStock = rand(1, 100) <= 70;
                    
                    if ($hasStock) {
                        // Generate random stock levels
                        $qtyUtuh = rand(0, 20); // 0-20 whole units
                        $qtyPakai = round(rand(0, 1000) / 10, 2); // 0-100.0 usage units
                        
                        // Calculate total converted
                        $qtyTotalConverted = ($qtyUtuh * $conversion->conversion_factor) + $qtyPakai;
                    } else {
                        $qtyUtuh = 0;
                        $qtyPakai = 0;
                        $qtyTotalConverted = 0;
                    }

                    // Create or update current stock
                    CurrentStock::updateOrCreate(
                        [
                            'store_id' => $store->id,
                            'raw_material_id' => $rm->id
                        ],
                        [
                            'qty_utuh' => $qtyUtuh,
                            'qty_pakai' => $qtyPakai,
                            'qty_total_converted' => $qtyTotalConverted,
                            'uom_utuh' => $conversion->uom_utuh,
                            'uom_pakai' => $conversion->uom_pakai,
                            'conversion_factor' => $conversion->conversion_factor,
                            'last_updated_date' => Carbon::now()->subDays(rand(0, 7)),
                            'last_movement_time' => Carbon::now()->subHours(rand(1, 168)),
                            'last_updated_by' => $userId,
                            'delete_flag' => false
                        ]
                    );

                    $stockCount++;
                }
            }

            DB::commit();
            
            $this->command->info('');
            $this->command->info('✓ Item Conversion and Stock Data created successfully!');
            $this->command->info('');
            $this->command->info('Summary:');
            $this->command->info("  - Stores: {$stores->count()}");
            $this->command->info("  - Raw Materials: {$rawMaterials->count()}");
            $this->command->info("  - Item Conversions Created: {$conversionCount}");
            $this->command->info("  - Current Stock Records: {$stockCount}");
            $this->command->info('');
            $this->command->info('You can now test Stock Opname (SO) with realistic data!');
            
        } catch (\Exception $e) {
            DB::rollback();
            $this->command->error('Error creating test data: ' . $e->getMessage());
            $this->command->error('Stack trace: ' . $e->getTraceAsString());
        }
    }
}
