<?php

namespace Tests\Feature\Api\V1\FullSurface;

use Tests\Feature\Api\V1\FullSurface\Support\FullSurfaceE2EContractCase;

class ApiBatch13InventoryProcurementReceivingIntegrityContractTest extends FullSurfaceE2EContractCase
{
    public function test_inventory_receiving_routes_reject_negative_or_impossible_stock_movements(): void
    {
        $routes = $this->apiRoutesContainingAny(['inventory', 'procurement', 'purchase', 'receiving', 'supplier', 'supply']);

        foreach ($routes as $route) {
            $method = $this->primaryMethod($route);
            if (! in_array($method, ['POST', 'PUT', 'PATCH'], true)) {
                continue;
            }

            $payload = $this->payloadFor($method, $route->uri()) + [
                'item_id' => $this->ids['itemId'],
                'supplier_id' => $this->ids['supplierId'],
                'quantity' => -1000000,
                'received_quantity' => 999999999,
                'unit_cost' => -1,
                'total_cost' => -999999,
                'movement_type' => 'receive',
                'force_negative_stock' => true,
            ];

            $response = $this->requestAs($this->admin, $method, $route->uri(), $payload);
            $this->assertControlled($response, $method, $route->uri());
            $this->assertStringNotContainsString('SQLSTATE', $response->getContent());
        }
    }

    public function test_non_admins_cannot_adjust_inventory_or_procurement_state(): void
    {
        $routes = $this->apiRoutesContainingAny(['inventory', 'procurement', 'purchase', 'receiving', 'supplier']);

        foreach ($routes as $route) {
            $method = $this->primaryMethod($route);
            if (! in_array($method, ['POST', 'PUT', 'PATCH', 'DELETE'], true)) {
                continue;
            }

            foreach ([$this->teacher, $this->parent, $this->studentUser] as $actor) {
                $response = $this->requestAs($actor, $method, $route->uri(), $this->payloadFor($method, $route->uri()));
                $this->assertControlled($response, $method, $route->uri());
                $this->assertNotContains($response->getStatusCode(), [200, 201]);
            }
        }
    }
}
