<?php

app_require('routes/systemSearchRoute.php');

use routes\systemSearchRoute;

function system_search_route_invoke_private(systemSearchRoute $route, string $method, array $args = []): mixed
{
    $reflection = new ReflectionClass($route);
    $target = $reflection->getMethod($method);
    return $target->invokeArgs($route, $args);
}

it('normalizes type lists from csv json and arrays', function (): void {
    $_SERVER['REQUEST_URI'] = '/search/system';
    $route = new systemSearchRoute();

    $csv = system_search_route_invoke_private($route, 'parseTypeList', [' Orders,customers ,ORDERS']);
    $json = system_search_route_invoke_private($route, 'parseTypeList', ['["invoices","Orders","invoices"]']);
    $array = system_search_route_invoke_private($route, 'parseTypeList', [[
        ' Vehicles ',
        'vehicles',
        'ORDERS',
        123,
    ]]);

    expect($csv)->toBe(['orders', 'customers']);
    expect($json)->toBe(['invoices', 'orders']);
    expect($array)->toBe(['vehicles', 'orders']);
});

it('parses booleans and clamps integers using route defaults', function (): void {
    $_SERVER['REQUEST_URI'] = '/search/system';
    $route = new systemSearchRoute();

    expect(system_search_route_invoke_private($route, 'toBool', ['true', false]))->toBeTrue();
    expect(system_search_route_invoke_private($route, 'toBool', ['0', true]))->toBeFalse();
    expect(system_search_route_invoke_private($route, 'toBool', ['not-a-bool', true]))->toBeTrue();

    expect(system_search_route_invoke_private($route, 'clampInt', [0, 1, 200, 50]))->toBe(50);
    expect(system_search_route_invoke_private($route, 'clampInt', [999, 1, 200, 50]))->toBe(200);
    expect(system_search_route_invoke_private($route, 'clampInt', [-4, 1, 200, 50]))->toBe(1);

    expect(system_search_route_invoke_private($route, 'clampMaxResults', [0]))->toBe(50);
    expect(system_search_route_invoke_private($route, 'clampMaxResults', [999]))->toBe(50);
    expect(system_search_route_invoke_private($route, 'clampMaxResults', [-4]))->toBe(1);
    expect(system_search_route_invoke_private($route, 'clampMaxResults', [12]))->toBe(12);
});

it('exposes expected searchable entity types', function (): void {
    $_SERVER['REQUEST_URI'] = '/search/system';
    $route = new systemSearchRoute();
    $types = system_search_route_invoke_private($route, 'allEntityTypes');

    expect($types)->toContain('orders');
    expect($types)->toContain('customers');
    expect($types)->toContain('users');
    expect($types)->toContain('invoices');
    expect($types)->toContain('module_config');
    expect($types)->toContain('objects');
    expect($types)->toContain('bookings');
    expect($types)->toContain('products');
    expect($types)->toContain('product_options');
    expect($types)->toContain('plate_scans');
    expect($types)->toContain('notifications');
    expect($types)->toContain('department_time_bookings_entries');
    expect($types)->toContain('stripe_module_orders');
    expect($types)->toContain('xlvask_usage_logs');
});

it('does not grant global users search through narrow id and name lookup permissions', function (): void {
    $_SERVER['REQUEST_URI'] = '/search/system';
    $route = new systemSearchRoute();

    $map = system_search_route_invoke_private($route, 'entityPermissionMap');
    $usersAll = $map['users']['all'] ?? [];

    expect($usersAll)->toContain('list_users');
    expect($usersAll)->toContain('get_user');
    expect($usersAll)->not->toContain('get_user_id');
    expect($usersAll)->not->toContain('get_user_name');
});
