<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\Item;
use App\Models\ItemCategory;
use App\Models\Bom;
use App\Models\BomItem;
use App\Models\WorkOrder;
use App\Models\QualityCheck;
use App\Models\Warehouse;
use App\Models\WarehouseBin;
use App\Models\StockBalance;
use App\Models\StockLedger;
use App\Models\Uom;
use App\Services\InventoryService;

class ManufacturingSeeder extends Seeder
{
    public function run(): void
    {
        $this->command->info('Seeding Manufacturing Demo Data...');

        // Get or create UoMs
        $kgUom = Uom::firstOrCreate(['code' => 'KG'], [
            'name' => 'Kilogram',
            'factor_to_base' => 1.0
        ]);

        $meterUom = Uom::firstOrCreate(['code' => 'METER'], [
            'name' => 'Meter',
            'factor_to_base' => 1.0
        ]);

        // Get or create categories
        $rmCategory = ItemCategory::firstOrCreate(['name' => 'Raw Materials']);
        $fgCategory = ItemCategory::firstOrCreate(['name' => 'Finished Goods']);

        // Create Raw Materials
        $copperRM = Item::firstOrCreate(['name' => 'Copper Wire'], [
            'sku' => 'RM-001',
            'item_category_id' => $rmCategory->id,
            'uom_id' => $kgUom->id,
            'type' => 'RM',
            'unit_of_measure' => 'KG',
            'status' => 'active',
            'is_active' => true
        ]);

        $danaRM = Item::firstOrCreate(['name' => 'Dana (Plastic Insulation)'], [
            'sku' => 'RM-002',
            'item_category_id' => $rmCategory->id,
            'uom_id' => $kgUom->id,
            'type' => 'RM',
            'unit_of_measure' => 'KG',
            'status' => 'active',
            'is_active' => true
        ]);

        // Create Finished Good
        $cableFG = Item::firstOrCreate(['name' => '10km Cable'], [
            'sku' => 'FG-001',
            'item_category_id' => $fgCategory->id,
            'uom_id' => $meterUom->id,
            'type' => 'FG',
            'unit_of_measure' => 'METER',
            'status' => 'active',
            'is_active' => true
        ]);

        // Create BOM for 10km Cable
        $cableBOM = Bom::firstOrCreate(['item_id' => $cableFG->id], [
            'version' => 1,
            'is_active' => true
        ]);

        // Add BOM components
        BomItem::firstOrCreate([
            'bom_id' => $cableBOM->id,
            'component_item_id' => $copperRM->id
        ], [
            'qty_per' => 2.5, // 2.5 KG copper per 10km cable
            'scrap_pct' => 5.0 // 5% scrap
        ]);

        BomItem::firstOrCreate([
            'bom_id' => $cableBOM->id,
            'component_item_id' => $danaRM->id
        ], [
            'qty_per' => 1.8, // 1.8 KG dana per 10km cable
            'scrap_pct' => 3.0 // 3% scrap
        ]);

        // Get MAIN warehouse and GENERAL bin
        $mainWarehouse = Warehouse::where('name', 'Main Warehouse')->first();
        $generalBin = WarehouseBin::where('warehouse_id', $mainWarehouse->id)
            ->where('type', 'general')
            ->first();

        if (!$mainWarehouse || !$generalBin) {
            $this->command->error('MAIN warehouse or GENERAL bin not found. Please run WmsSeeder first.');
            return;
        }

        // Add initial stock for raw materials
        $this->addInitialStock($copperRM, $mainWarehouse, $generalBin, 'LOT-001', 100); // 100 KG
        $this->addInitialStock($danaRM, $mainWarehouse, $generalBin, 'LOT-002', 80); // 80 KG

        // Create a Work Order
        $workOrder = WorkOrder::create([
            'item_id' => $cableFG->id,
            'wo_number' => 'WO-' . date('YmdHis') . '-001',
            'product_id' => $cableFG->id, // Same as item_id for FG
            'bom_id' => $cableBOM->id,
            'qty_planned' => 5, // 5 x 10km cables = 50km total
            'planned_quantity' => 5, // Same as qty_planned
            'warehouse_id' => $mainWarehouse->id,
            'status' => WorkOrder::STATUS_PLANNED,
            'due_date' => now()->addDays(7),
            'batch_no' => 'WO-' . date('YmdHis') . '-001',
            'created_by' => 1
        ]);

        $this->command->info("Created Work Order: {$workOrder->batch_no}");

        // Demonstrate material issues
        $inventoryService = app(InventoryService::class);

        // Issue copper wire
        try {
            $inventoryService->issueToWO(
                $workOrder->id,
                $copperRM->id,
                'LOT-001',
                $generalBin->id,
                12.5 // 5 cables * 2.5 KG per cable
            );
            $this->command->info("Issued 12.5 KG copper wire to WO");

            // Issue dana
            $inventoryService->issueToWO(
                $workOrder->id,
                $danaRM->id,
                'LOT-002',
                $generalBin->id,
                9.0 // 5 cables * 1.8 KG per cable
            );
            $this->command->info("Issued 9.0 KG dana to WO");

        } catch (\Exception $e) {
            $this->command->error("Error issuing materials: " . $e->getMessage());
        }

        // Update WO status to in_progress
        $workOrder->update(['status' => WorkOrder::STATUS_IN_PROGRESS]);

        // Receive finished goods
        try {
            $inventoryService->receiveFromWO(
                $workOrder->id,
                $cableFG->id,
                $workOrder->batch_no,
                $generalBin->id,
                5 // 5 x 10km cables
            );
            $this->command->info("Received 5 x 10km cables from WO");

        } catch (\Exception $e) {
            $this->command->error("Error receiving FG: " . $e->getMessage());
        }

        // Update WO status to completed
        $workOrder->update(['status' => WorkOrder::STATUS_COMPLETED]);

        // Create final quality check
        QualityCheck::create([
            'context' => QualityCheck::CONTEXT_WO_FINAL,
            'context_id' => $workOrder->id,
            'item_id' => $cableFG->id,
            'lot_no' => $workOrder->batch_no,
            'result' => QualityCheck::RESULT_PASS,
            'attributes' => [
                'tensile_strength' => 'Pass',
                'insulation_resistance' => 'Pass',
                'conductor_resistance' => 'Pass',
                'inspector' => 'Quality Team'
            ],
            'checked_by_id' => 1
        ]);

        $this->command->info("Created final quality check (PASS)");

        // Show BOM requirements
        $requirements = $inventoryService->getBOMRequirements($workOrder->id);
        $this->command->info("BOM Requirements for WO {$workOrder->id}:");
        foreach ($requirements as $req) {
            $this->command->info("- {$req['item_name']}: Required {$req['required_qty']}, Available {$req['available_qty']}");
        }

        $this->command->info('Manufacturing demo data seeded successfully!');
    }

    private function addInitialStock($item, $warehouse, $bin, $lotNo, $qty): void
    {
        // Define costs based on item name
        $costs = [
            'Copper Wire' => 1500.00, // PKR per KG
            'Dana (Plastic Insulation)' => 800.00, // PKR per KG
            '10km Cable' => 0.00 // Will be calculated from BOM
        ];

        $unitCost = $costs[$item->name] ?? 0.00;

        // Create stock balance
        StockBalance::firstOrCreate([
            'item_id' => $item->id,
            'warehouse_id' => $warehouse->id,
            'bin_id' => $bin->id,
            'lot_no' => $lotNo
        ], [
            'on_hand_qty' => $qty,
            'reserved_qty' => 0,
            'unit_cost_avg' => $unitCost
        ]);

        // Create ledger entry
        StockLedger::create([
            'txn_type' => 'adjustment',
            'txn_id' => 0,
            'item_id' => $item->id,
            'lot_no' => $lotNo,
            'bin_id' => $bin->id,
            'qty_in' => $qty,
            'qty_out' => 0,
            'uom_id' => $item->uom_id,
            'unit_cost' => $unitCost,
            'ref_no' => 'INITIAL',
            'occurred_at' => now()
        ]);
    }
}
