<?php

namespace Tests\Traits;

use Modules\WMSInventoryCore\App\Models\Inventory;
use Modules\WMSInventoryCore\App\Models\Unit;
use Modules\WMSInventoryCore\App\Models\Warehouse;
use Modules\WMSInventoryCore\App\Models\WarehouseZone;

/**
 * Helper trait for creating WMSInventoryCore test entities.
 */
trait CreatesWMSInventoryEntities
{
    protected ?Unit $defaultUnit = null;

    protected function getOrCreateDefaultUnit(): Unit
    {
        if ($this->defaultUnit) {
            return $this->defaultUnit;
        }

        $this->defaultUnit = Unit::firstOrCreate(
            ['code' => 'PCS'],
            [
                'name' => 'Pieces',
                'description' => 'Default unit for testing',
                'status' => 'active',
            ]
        );

        return $this->defaultUnit;
    }
    // ==========================================
    // Warehouse Methods
    // ==========================================

    protected function createWarehouse(array $attributes = []): Warehouse
    {
        return Warehouse::create(array_merge([
            'name' => 'Test Warehouse '.uniqid(),
            'code' => 'WH-'.strtoupper(uniqid()),
            'address' => '123 Warehouse St',
            'city' => 'Test City',
            'state' => 'Test State',
            'country' => 'Test Country',
            'postal_code' => '12345',
            'phone_number' => '+1234567890',
            'email' => 'warehouse'.uniqid().'@example.com',
            'contact_person' => 'John Manager',
            'is_active' => true,
            'is_main' => false,
            'allow_negative_inventory' => false,
            'requires_approval' => false,
            'is_24_hours' => true,
            'status' => 'active',
        ], $attributes));
    }

    protected function createMainWarehouse(array $attributes = []): Warehouse
    {
        // Ensure no other main warehouse exists
        Warehouse::where('is_main', true)->update(['is_main' => false]);

        return $this->createWarehouse(array_merge([
            'name' => 'Main Warehouse',
            'is_main' => true,
        ], $attributes));
    }

    protected function createInactiveWarehouse(array $attributes = []): Warehouse
    {
        return $this->createWarehouse(array_merge([
            'is_active' => false,
            'status' => 'inactive',
        ], $attributes));
    }

    protected function createWarehouseWithApproval(array $attributes = []): Warehouse
    {
        return $this->createWarehouse(array_merge([
            'requires_approval' => true,
        ], $attributes));
    }

    // ==========================================
    // Warehouse Zone Methods
    // ==========================================

    protected function createWarehouseZone(Warehouse $warehouse, array $attributes = []): WarehouseZone
    {
        return WarehouseZone::create(array_merge([
            'warehouse_id' => $warehouse->id,
            'name' => 'Zone '.uniqid(),
            'code' => 'Z-'.strtoupper(uniqid()),
            'description' => 'Test zone',
            'is_active' => true,
        ], $attributes));
    }

    // ==========================================
    // Inventory Methods
    // ==========================================

    protected function createInventory(array $attributes = []): Inventory
    {
        // Remove created_by_id if passed - inventories table doesn't have this column
        unset($attributes['created_by_id']);
        unset($attributes['updated_by_id']);

        // Ensure unit_id is set
        if (! isset($attributes['unit_id'])) {
            $attributes['unit_id'] = $this->getOrCreateDefaultUnit()->id;
        }

        return Inventory::create(array_merge([
            'stock_level' => 100,
            'reserved_quantity' => 0,
            'cost_price' => 10.00,
            'damaged_quantity' => 0,
            'quarantine_quantity' => 0,
            'in_transit_quantity' => 0,
            'low_stock_alert_sent' => false,
        ], $attributes));
    }

    protected function createLowStockInventory(array $attributes = []): Inventory
    {
        return $this->createInventory(array_merge([
            'stock_level' => 5,
        ], $attributes));
    }

    protected function createOutOfStockInventory(array $attributes = []): Inventory
    {
        return $this->createInventory(array_merge([
            'stock_level' => 0,
        ], $attributes));
    }

    protected function createDamagedInventory(array $attributes = []): Inventory
    {
        return $this->createInventory(array_merge([
            'stock_level' => 100,
            'damaged_quantity' => 30,
        ], $attributes));
    }

    protected function createQuarantineInventory(array $attributes = []): Inventory
    {
        return $this->createInventory(array_merge([
            'stock_level' => 100,
            'quarantine_quantity' => 25,
        ], $attributes));
    }
}
