<?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\ArmadaType;
use App\Models\ShipmentDelivery;
use App\Models\TargetSisaMalam;
use App\Models\Forecast;
use App\Models\StockOpname;
use App\Models\StockOpnameDetail;
use App\Models\ItemRequest;
use App\Models\ItemRequestDetail;
use App\Models\StoreRawMaterial;

class LSMTestDataSeeder extends Seeder
{
    public function run()
    {
        DB::beginTransaction();
        
        try {
            // 1. Create Stores
            $stores = [
                ['name' => 'Store Jakarta Pusat', 'address' => 'Jl. Sudirman No. 1, Jakarta Pusat', 'store_type' => 'Retail', 'document_type' => 'Invoice'],
                ['name' => 'Store Bandung', 'address' => 'Jl. Asia Afrika No. 10, Bandung', 'store_type' => 'Retail', 'document_type' => 'Invoice'],
                ['name' => 'Store Surabaya', 'address' => 'Jl. Pemuda No. 5, Surabaya', 'store_type' => 'Retail', 'document_type' => 'Invoice'],
            ];

            foreach ($stores as $store) {
                Store::create(array_merge($store, [
                    'status' => 'Active',
                    'delete_flag' => 0,
                    'created_by' => 1,
                ]));
            }

            // 2. Create Raw Materials
            $rawMaterials = [
                ['name' => 'Tepung Terigu Premium', 'uom' => 'KG', 'category' => 'Flour'],
                ['name' => 'Gula Pasir', 'uom' => 'KG', 'category' => 'Sugar'],
                ['name' => 'Mentega', 'uom' => 'KG', 'category' => 'Dairy'],
                ['name' => 'Telur Ayam', 'uom' => 'KG', 'category' => 'Protein'],
                ['name' => 'Susu Bubuk', 'uom' => 'KG', 'category' => 'Dairy'],
                ['name' => 'Coklat Bubuk', 'uom' => 'KG', 'category' => 'Flavoring'],
                ['name' => 'Vanilla Extract', 'uom' => 'LTR', 'category' => 'Flavoring'],
                ['name' => 'Baking Powder', 'uom' => 'KG', 'category' => 'Leavening'],
            ];

            foreach ($rawMaterials as $rm) {
                RawMaterial::create(array_merge($rm, [
                    'delete_flag' => 0,
                    'created_by' => 1,
                ]));
            }

            // 3. Create Armada Types
            $armadaTypes = [
                ['name' => 'Truck Kecil', 'description' => 'Truck untuk pengiriman lokal'],
                ['name' => 'Truck Sedang', 'description' => 'Truck untuk pengiriman regional'],
                ['name' => 'Truck Besar', 'description' => 'Truck untuk pengiriman antar kota'],
            ];

            foreach ($armadaTypes as $armada) {
                ArmadaType::create(array_merge($armada, [
                    'delete_flag' => 0,
                    'created_by' => 1,
                ]));
            }

            // 4. Create Shipment Schedules
            $storeIds = Store::pluck('id')->toArray();
            $armadaIds = ArmadaType::pluck('id')->toArray();
            
            $schedules = [
                ['store_id' => $storeIds[0], 'armada_type_id' => $armadaIds[0], 'day_name' => 'Monday', 'departure_time' => '08:00', 'arrival_time' => '07:00'],
                ['store_id' => $storeIds[0], 'armada_type_id' => $armadaIds[1], 'day_name' => 'Wednesday', 'departure_time' => '09:00', 'arrival_time' => '08:00'],
                ['store_id' => $storeIds[1], 'armada_type_id' => $armadaIds[0], 'day_name' => 'Tuesday', 'departure_time' => '08:30', 'arrival_time' => '07:30'],
                ['store_id' => $storeIds[1], 'armada_type_id' => $armadaIds[2], 'day_name' => 'Friday', 'departure_time' => '07:00', 'arrival_time' => '06:00'],
                ['store_id' => $storeIds[2], 'armada_type_id' => $armadaIds[1], 'day_name' => 'Thursday', 'departure_time' => '08:00', 'arrival_time' => '07:00'],
            ];

            foreach ($schedules as $schedule) {
                ShipmentDelivery::create(array_merge($schedule, [
                    'status' => 'Active',
                    'delete_flag' => 0,
                    'created_by' => 1,
                ]));
            }

            // 5. Create Target Sisa Malam for each store and raw material
            $stores = Store::all();
            $rawMaterials = RawMaterial::all();

            foreach ($stores as $store) {
                foreach ($rawMaterials as $rm) {
                    $targetQty = rand(50, 200); // Random target between 50-200
                    
                    TargetSisaMalam::create([
                        'store_id' => $store->id,
                        'raw_material_id' => $rm->id,
                        'target_qty' => $targetQty,
                        'status' => 'Active',
                        'delete_flag' => 0,
                        'created_by' => 1,
                    ]);
                }
            }

            // 6. Create Forecasts for current month
            $currentMonth = date('n');
            $currentYear = date('Y');

            foreach ($stores as $store) {
                foreach ($rawMaterials as $rm) {
                    $forecastQty = rand(100, 500); // Random forecast between 100-500
                    
                    Forecast::create([
                        'store_id' => $store->id,
                        'raw_material_id' => $rm->id,
                        'year' => $currentYear,
                        'month' => $currentMonth,
                        'forecast_date' => Carbon::now()->startOfMonth(),
                        'forecast_qty' => $forecastQty,
                        'status' => 'Active',
                        'delete_flag' => 0,
                        'created_by' => 1,
                    ]);
                }
            }

            // 7. Create Stock Opnames (LSM)
            $stores = Store::all();
            $soData = [
                [
                    'store_id' => $stores[0]->id,
                    'so_date' => Carbon::now()->subDays(2),
                    'status' => 'Submitted',
                    'notes' => 'Stock opname rutin mingguan'
                ],
                [
                    'store_id' => $stores[1]->id,
                    'so_date' => Carbon::now()->subDays(1),
                    'status' => 'Submitted',
                    'notes' => 'Stock opname setelah delivery besar'
                ],
                [
                    'store_id' => $stores[2]->id,
                    'so_date' => Carbon::now(),
                    'status' => 'Draft',
                    'notes' => 'Stock opname hari ini'
                ]
            ];

            foreach ($soData as $so) {
                $stockOpname = StockOpname::create(array_merge($so, [
                    'delete_flag' => 0,
                    'created_by' => 1,
                ]));

                // Create SO Details for each raw material
                foreach ($rawMaterials as $rm) {
                    $qtyUtuh = rand(5, 30);
                    $qtyPakai = rand(10, 50);
                    
                    StockOpnameDetail::create([
                        'so_id' => $stockOpname->id,
                        'raw_material_id' => $rm->id,
                        'qty_utuh' => $qtyUtuh,
                        'qty_pakai' => $qtyPakai,
                        'qty_converted' => 0, // Will be calculated automatically
                        'qty_total' => 0, // Will be calculated automatically
                        'notes' => 'Stock opname detail for ' . $rm->name,
                    ]);
                }
            }

            // 8. Create Item Requests (SPB) from Stock Opnames
            $submittedSOs = StockOpname::where('status', 'Submitted')->get();
            
            foreach ($submittedSOs as $so) {
                $spb = ItemRequest::create([
                    'store_id' => $so->store_id,
                    'stock_opname_id' => $so->id,
                    'request_type' => 'Regular',
                    'request_date' => $so->so_date->addDay(),
                    'delivery_date' => $so->so_date->addDays(2),
                    'shipment_schedule_id' => ShipmentDelivery::where('store_id', $so->store_id)->first()->id,
                    'status' => 'Submitted',
                    'notes' => 'SPB generated from SO #' . $so->so_number,
                    'delete_flag' => 0,
                    'created_by' => 1,
                ]);

                // Create SPB Details based on SO and TSM
                $targets = TargetSisaMalam::where('store_id', $so->store_id)->get()->keyBy('raw_material_id');
                $forecasts = Forecast::where('store_id', $so->store_id)
                    ->where('month', $currentMonth)
                    ->where('year', $currentYear)
                    ->get()->keyBy('raw_material_id');

                foreach ($so->details as $soDetail) {
                    $target = $targets->get($soDetail->raw_material_id);
                    $forecast = $forecasts->get($soDetail->raw_material_id);
                    
                    $targetQty = $target ? $target->target_qty : 100;
                    $forecastQty = $forecast ? $forecast->forecast_qty : 0;
                    $suggestedQty = max(0, $targetQty - $soDetail->qty_total);
                    
                    if ($suggestedQty > 0) {
                        $adjustedQty = $suggestedQty + rand(-10, 20); // Some manual adjustment
                        $adjustedQty = max(0, $adjustedQty);
                        
                        ItemRequestDetail::create([
                            'item_request_id' => $spb->id,
                            'raw_material_id' => $soDetail->raw_material_id,
                            'forecast_qty' => $forecastQty,
                            'so_qty' => $soDetail->qty_total,
                            'tsm_qty' => $targetQty,
                            'suggested_qty' => $suggestedQty,
                            'adjusted_qty' => $adjustedQty,
                            'notes' => $adjustedQty != $suggestedQty ? 'Adjusted based on urgent needs' : null,
                        ]);
                    }
                }
            }

            // 9. Create Delivery Orders from approved SPBs
            $approvedSPBs = ItemRequest::where('status', 'Submitted')->get();
            
            // Approve some SPBs (no DO generation - will use CSV export instead)
            foreach ($approvedSPBs as $spb) {
                $spb->update(['status' => 'Approved']);
            }

            DB::commit();
            
            $this->command->info('LSM Test Data created successfully!');
            $this->command->info('Created:');
            $this->command->info('- ' . Store::count() . ' Stores');
            $this->command->info('- ' . RawMaterial::count() . ' Raw Materials');
            $this->command->info('- ' . ArmadaType::count() . ' Armada Types');
            $this->command->info('- ' . ShipmentDelivery::count() . ' Shipment Schedules');
            $this->command->info('- ' . TargetSisaMalam::count() . ' Target Sisa Malam records');
            $this->command->info('- ' . Forecast::count() . ' Forecast records');
            $this->command->info('- ' . StockOpname::count() . ' Stock Opnames');
            $this->command->info('- ' . ItemRequest::count() . ' Item Requests (SPB)');
            
        } catch (\Exception $e) {
            DB::rollback();
            $this->command->error('Error creating test data: ' . $e->getMessage());
        }
    }
}