<?php

namespace App\Modules\Procurement\Services;

use App\Modules\Procurement\Exceptions\GoodsReceiptIntegrityViolationException;
use App\Modules\Procurement\Models\GoodsReceipt;
use App\Modules\Procurement\Models\PurchaseOrderItem;
use App\Modules\Procurement\Support\GoodsReceiptViolationCode;

/**
 * Aggregate invariant: receipt lines must bind to PO lines on the SAME PO, tenant-aligned, not soft-deleted.
 */
final class GoodsReceiptLineIntegrityValidator
{
    public function assertWritableLine(GoodsReceipt $receipt, PurchaseOrderItem $poi): void
    {
        if ((int) $poi->tenant_id !== (int) $receipt->tenant_id) {
            throw new GoodsReceiptIntegrityViolationException(
                'Purchase order line tenant does not match receipt.',
                'tenant_mismatch',
            );
        }
        if ($poi->trashed()) {
            throw new GoodsReceiptIntegrityViolationException(
                'Purchase order line is deleted.',
                GoodsReceiptViolationCode::DELETED_PO_ITEM,
            );
        }
        if ((int) $poi->purchase_order_id !== (int) $receipt->purchase_order_id) {
            throw new GoodsReceiptIntegrityViolationException(
                'Purchase order line does not belong to this receipt purchase order.',
                GoodsReceiptViolationCode::CROSS_PO,
            );
        }
    }
}
