<?php

declare(strict_types=1);

usesApiSuite();

function daily_report_product_from_overview(array $overview, int $productId): array
{
    foreach (($overview['products'] ?? []) as $product) {
        if ((int)($product['product_id'] ?? 0) === $productId) {
            return $product;
        }
    }

    return [];
}

it('stores clears and permission-gates department daily report product targets', function (): void {
    api_test_covers('PUT /departments/daily-reports/product-targets', 'happy');
    api_test_covers('GET /departments/daily-reports/overview', 'happy');

    $department = api_fixtures()->createDepartment([
        'name' => 'Daily Report Product Target ' . uniqid('', false),
    ]);
    $departmentId = (int)$department['id'];
    $editorPermissions = [
        'list_department_daily_reports',
        'list_bookings',
        'set_department_daily_report_product_targets',
        'department_access_' . $departmentId,
    ];
    $editorSession = api_fixtures()->createUserSession($editorPermissions);
    $viewerSession = api_fixtures()->createUserSession([
        'list_department_daily_reports',
        'list_bookings',
        'department_access_' . $departmentId,
    ]);

    try {
        $saveResponse = api_client()->put('/departments/daily-reports/product-targets', [
            'department_id' => $departmentId,
            'product_id' => 24,
            'target_percentage' => 47.55,
        ], $editorSession['headers']);

        $saveResponse
            ->assertStatus(200)
            ->assertEnvelope()
            ->assertSuccess();

        expect($saveResponse->data())->toMatchArray([
            'department_id' => $departmentId,
            'product_id' => 24,
            'target_percentage' => 47.6,
        ]);

        $overviewResponse = api_client()->get(
            '/departments/daily-reports/overview?date=2026-07-06&department_ids=' . $departmentId,
            $editorSession['headers']
        );

        $overviewResponse
            ->assertStatus(200)
            ->assertEnvelope()
            ->assertSuccess();

        $editorProduct = daily_report_product_from_overview($overviewResponse->data(), 24);
        expect($editorProduct['target_percentage'])->toBe(47.6);
        expect($editorProduct['target_department_id'])->toBe($departmentId);

        $viewerOverviewResponse = api_client()->get(
            '/departments/daily-reports/overview?date=2026-07-06&department_ids=' . $departmentId,
            $viewerSession['headers']
        );

        $viewerOverviewResponse
            ->assertStatus(200)
            ->assertEnvelope()
            ->assertSuccess();

        $viewerProduct = daily_report_product_from_overview($viewerOverviewResponse->data(), 24);
        expect($viewerProduct['target_percentage'])->toBeNull();
        expect($viewerProduct['target_department_id'])->toBeNull();

        $clearResponse = api_client()->put('/departments/daily-reports/product-targets', [
            'department_id' => $departmentId,
            'product_id' => 24,
            'target_percentage' => null,
        ], $editorSession['headers']);

        $clearResponse
            ->assertStatus(200)
            ->assertEnvelope()
            ->assertSuccess();

        expect($clearResponse->data())->toMatchArray([
            'department_id' => $departmentId,
            'product_id' => 24,
            'target_percentage' => null,
        ]);

        $clearedOverviewResponse = api_client()->get(
            '/departments/daily-reports/overview?date=2026-07-06&department_ids=' . $departmentId,
            $editorSession['headers']
        );

        $clearedProduct = daily_report_product_from_overview($clearedOverviewResponse->data(), 24);
        expect($clearedProduct['target_percentage'])->toBeNull();
        expect($clearedProduct['target_department_id'])->toBeNull();
    } finally {
        api_client()->put('/departments/daily-reports/product-targets', [
            'department_id' => $departmentId,
            'product_id' => 24,
            'target_percentage' => null,
        ], $editorSession['headers']);
    }
});

it('rejects product target updates without permission access or valid input', function (): void {
    api_test_covers('PUT /departments/daily-reports/product-targets', 'auth');
    api_test_covers('PUT /departments/daily-reports/product-targets', 'failure');

    $department = api_fixtures()->createDepartment();
    $departmentId = (int)$department['id'];

    $missingPermissionSession = api_fixtures()->createUserSession([
        'department_access_' . $departmentId,
    ]);

    api_client()->put('/departments/daily-reports/product-targets', [
        'department_id' => $departmentId,
        'product_id' => 24,
        'target_percentage' => 50,
    ], $missingPermissionSession['headers'])
        ->assertStatus(403)
        ->assertEnvelope()
        ->assertSuccess(false)
        ->assertMissingPermissions(['set_department_daily_report_product_targets']);

    $missingDepartmentAccessSession = api_fixtures()->createUserSession([
        'set_department_daily_report_product_targets',
    ]);

    api_client()->put('/departments/daily-reports/product-targets', [
        'department_id' => $departmentId,
        'product_id' => 24,
        'target_percentage' => 50,
    ], $missingDepartmentAccessSession['headers'])
        ->assertStatus(403)
        ->assertEnvelope()
        ->assertSuccess(false)
        ->assertMissingPermissions(['department_access_' . $departmentId]);

    $editorSession = api_fixtures()->createUserSession([
        'set_department_daily_report_product_targets',
        'department_access_' . $departmentId,
    ]);

    api_client()->put('/departments/daily-reports/product-targets', [
        'department_id' => $departmentId,
        'product_id' => 999999,
        'target_percentage' => 50,
    ], $editorSession['headers'])
        ->assertStatus(400)
        ->assertEnvelope()
        ->assertSuccess(false)
        ->assertMessage('Invalid daily report product_id');

    api_client()->put('/departments/daily-reports/product-targets', [
        'department_id' => $departmentId,
        'product_id' => 24,
        'target_percentage' => 101,
    ], $editorSession['headers'])
        ->assertStatus(400)
        ->assertEnvelope()
        ->assertSuccess(false)
        ->assertMessage('Parameter target_percentage must be between 0 and 100');
});
