<?php

namespace App\Modules\Inventory\Stock\Services;

use App\Modules\Inventory\Models\Item;
use App\Modules\Inventory\Models\Warehouse;
use App\Modules\Inventory\Stock\Exceptions\StockMovementValidationException;
use App\Modules\Inventory\Stock\Support\InventoryStockMovementType;
use App\Modules\Inventory\Support\InventoryLifecycleState;

final class StockCatalogGate
{
    public function assertMovable(int $tenantId, int $warehouseId, int $itemId, ?int $unitId, InventoryStockMovementType $type): void
    {
        $w = Warehouse::withoutGlobalScopes()
            ->where('tenant_id', $tenantId)
            ->whereKey($warehouseId)
            ->first();
        if ($w === null) {
            throw new StockMovementValidationException('warehouse_invalid');
        }
        if (! $w->is_active || $w->lifecycle_state !== InventoryLifecycleState::Active) {
            throw new StockMovementValidationException('warehouse_not_active');
        }

        $item = Item::withoutGlobalScopes()
            ->where('tenant_id', $tenantId)
            ->whereKey($itemId)
            ->first();
        if ($item === null) {
            throw new StockMovementValidationException('item_invalid');
        }

        $allowInactiveAdjustment = $type === InventoryStockMovementType::Adjustment
            && (bool) config('inventory.allow_adjustment_on_inactive_item', false);

        if (! $item->is_active && ! $allowInactiveAdjustment) {
            throw new StockMovementValidationException('item_inactive');
        }
        if ($item->lifecycle_state !== InventoryLifecycleState::Active && ! $allowInactiveAdjustment) {
            throw new StockMovementValidationException('item_lifecycle_blocked');
        }

        $expectedUnit = $item->default_unit_id;
        if ($unitId !== null && (int) $unitId !== (int) $expectedUnit) {
            throw new StockMovementValidationException('unit_mismatch');
        }
    }
}
