<?php

usesApiSuite();

it('requires authentication before checking in-progress wash permissions', function (): void {
    $response = api_client()->get('/modules/self-serve/lane/wash/in-progress?lane_id=1');

    $response
        ->assertStatus(401)
        ->assertMessage('Authentication failed. Invalid or missing token.');
});

it('requires authentication before checking the current customers active self-serve wash', function (): void {
    $response = api_client()->get('/modules/self-serve/lane/wash/my-active-wash');

    $response
        ->assertStatus(401)
        ->assertMessage('Authentication failed. Invalid or missing token.');
});

it('reports both elevated and customer self-serve permissions when lane polling is not allowed', function (): void {
    $session = api_fixtures()->createUserSession([]);

    $response = api_client()->get(
        '/modules/self-serve/lane/wash/in-progress?lane_id=1',
        $session['headers']
    );

    $response
        ->assertStatus(403)
        ->assertMissingPermissions([
            'modules_selfserve_lane_wash_in_progress_view',
            'add_own_department_selfserve_vehicle_conditions',
        ]);
});

it('requires customer self-serve permission before checking my active wash', function (): void {
    $session = api_fixtures()->createUserSession([]);

    $response = api_client()->get('/modules/self-serve/lane/wash/my-active-wash', $session['headers']);

    $response
        ->assertStatus(403)
        ->assertMissingPermissions([
            'add_own_department_selfserve_vehicle_conditions',
        ]);
});

it('denies list-only drivers from operational self-serve active wash restore', function (): void {
    $customer = api_fixtures()->createUser();
    $driverSession = api_fixtures()->createSubuserSession((int)$customer['customer_number'], [
        'SELFSERVE_LIST',
    ]);

    $response = api_client()->get('/modules/self-serve/lane/wash/my-active-wash', $driverSession['headers']);

    $response
        ->assertStatus(403)
        ->assertMissingPermissions([
            'add_own_department_selfserve_vehicle_conditions',
        ]);
});

it('allows customer self-serve permission to view their own in-progress wash details', function (): void {
    $group = api_fixtures()->createGroup([], [
        'list_own_department_selfserve_vehicle_conditions',
        'add_own_department_selfserve_vehicle_conditions',
    ]);
    $scenario = api_fixtures()->createSelfServeScenario([
        'customer' => [
            'group_id' => $group['id'],
        ],
    ]);
    $token = api_fixtures()->createAuthToken((int)$scenario['customer']['id']);

    $response = api_client()->get(
        '/modules/self-serve/lane/wash/in-progress?lane_id=' . (int)$scenario['lane']['id'],
        api_fixtures()->bearerHeaders($token)
    );

    $response
        ->assertStatus(200)
        ->assertSuccess(true);

    expect($response->data()['in_progress'] ?? null)->toBeTrue()
        ->and($response->data()['session']['customer_number'] ?? null)->toBe((int)$scenario['customer']['customer_number'])
        ->and($response->data()['vehicle']['reg'] ?? null)->toBe($scenario['vehicle']['reg']);
});

it('returns the authenticated customers active self-serve wash without requiring a lane id', function (): void {
    $group = api_fixtures()->createGroup([], [
        'list_own_department_selfserve_vehicle_conditions',
        'add_own_department_selfserve_vehicle_conditions',
    ]);
    $scenario = api_fixtures()->createSelfServeScenario([
        'customer' => [
            'group_id' => $group['id'],
        ],
    ]);
    $token = api_fixtures()->createAuthToken((int)$scenario['customer']['id']);

    $response = api_client()->get(
        '/modules/self-serve/lane/wash/my-active-wash',
        api_fixtures()->bearerHeaders($token)
    );

    $response
        ->assertStatus(200)
        ->assertSuccess(true);

    expect($response->data()['in_progress'] ?? null)->toBeTrue()
        ->and($response->data()['lane_id'] ?? null)->toBe((int)$scenario['lane']['id'])
        ->and($response->data()['session']['id'] ?? null)->toBe((int)$scenario['session']['id'])
        ->and($response->data()['session']['lane_id'] ?? null)->toBe((int)$scenario['lane']['id'])
        ->and($response->data()['session']['customer_number'] ?? null)->toBe((int)$scenario['customer']['customer_number'])
        ->and($response->data()['vehicle']['reg'] ?? null)->toBe($scenario['vehicle']['reg']);
});

it('scopes active self-serve wash restore to the authenticated driver under a shared customer number', function (): void {
    $scenario = api_fixtures()->createSelfServeScenario();
    $customerNumber = (int)$scenario['customer']['customer_number'];
    $ownerDriver = api_fixtures()->createSubuserSession($customerNumber, [
        'SELFSERVE_LIST',
        'SELFSERVE_ADD',
    ], [
        'name' => 'Self-Serve Owner Driver',
    ]);
    $otherDriver = api_fixtures()->createSubuserSession($customerNumber, [
        'SELFSERVE_LIST',
        'SELFSERVE_ADD',
    ], [
        'name' => 'Self-Serve Other Driver',
    ]);

    api_test_runtime()->db()->query(
        'UPDATE selfserve_wash_sessions SET subuser_id = '
            . (int)$ownerDriver['subuser']['id']
            . ' WHERE id = '
            . (int)$scenario['session']['id']
    );

    $ownerResponse = api_client()->get(
        '/modules/self-serve/lane/wash/my-active-wash',
        $ownerDriver['headers']
    );
    $otherResponse = api_client()->get(
        '/modules/self-serve/lane/wash/my-active-wash',
        $otherDriver['headers']
    );
    $otherLanePoll = api_client()->get(
        '/modules/self-serve/lane/wash/in-progress?lane_id=' . (int)$scenario['lane']['id'],
        $otherDriver['headers']
    );

    $ownerResponse
        ->assertStatus(200)
        ->assertSuccess(true);
    $otherResponse
        ->assertStatus(404)
        ->assertMessage('No active self-serve wash found.');
    $otherLanePoll
        ->assertStatus(200)
        ->assertSuccess(true);

    expect($ownerResponse->data()['session']['subuser_id'] ?? null)->toBe((int)$ownerDriver['subuser']['id'])
        ->and($ownerResponse->data()['subuser']['id'] ?? null)->toBe((int)$ownerDriver['subuser']['id'])
        ->and($otherLanePoll->data())->toMatchArray([
            'lane_id' => (int)$scenario['lane']['id'],
            'in_progress' => true,
            'session' => null,
            'customer' => null,
            'vehicle' => null,
        ]);
});

it('returns 404 when the authenticated customer has no active self-serve wash', function (): void {
    $session = api_fixtures()->createUserSession([
        'list_own_department_selfserve_vehicle_conditions',
        'add_own_department_selfserve_vehicle_conditions',
    ]);

    $response = api_client()->get('/modules/self-serve/lane/wash/my-active-wash', $session['headers']);

    $response
        ->assertStatus(404)
        ->assertMessage('No active self-serve wash found.');
});

it('redacts another customers in-progress wash from customer self-serve lane polling', function (): void {
    $scenario = api_fixtures()->createSelfServeScenario();
    $otherSession = api_fixtures()->createUserSession([
        'list_own_department_selfserve_vehicle_conditions',
        'add_own_department_selfserve_vehicle_conditions',
    ]);

    $response = api_client()->get(
        '/modules/self-serve/lane/wash/in-progress?lane_id=' . (int)$scenario['lane']['id'],
        $otherSession['headers']
    );

    $response
        ->assertStatus(200)
        ->assertSuccess(true);

    expect($response->data())->toMatchArray([
        'lane_id' => (int)$scenario['lane']['id'],
        'in_progress' => true,
        'session' => null,
        'customer' => null,
        'vehicle' => null,
    ]);
});
