<?php

app_require('routes/moduleWeatherAPIRoute.php');

use routes\moduleWeatherAPIRoute;

function weather_status_targets_invoke_private(moduleWeatherAPIRoute $route, string $method, array $args = []): mixed
{
    $reflection = new ReflectionClass($route);
    $target = $reflection->getMethod($method);

    return $target->invokeArgs($route, $args);
}

beforeEach(function (): void {
    $_SERVER['REQUEST_URI'] = '/departments/weather';
});

it('evaluates healthy degraded and unhealthy statuses from configured department targets', function (): void {
    $route = new moduleWeatherAPIRoute();
    $targets = [
        'degraded_threshold' => 1.0,
        'healthy_threshold' => 1.3,
    ];

    $healthy = weather_status_targets_invoke_private($route, 'calculateStatus', [13, 10.0, true, $targets]);
    $degraded = weather_status_targets_invoke_private($route, 'calculateStatus', [10, 10.0, true, $targets]);
    $unhealthy = weather_status_targets_invoke_private($route, 'calculateStatus', [9, 10.0, true, $targets]);

    expect($healthy)->toBe('healthy');
    expect($degraded)->toBe('degraded');
    expect($unhealthy)->toBe('unhealthy');
});

it('returns unknown when configured targets are missing for department status evaluation', function (): void {
    $route = new moduleWeatherAPIRoute();

    $status = weather_status_targets_invoke_private($route, 'calculateStatus', [10, 10.0, true, null]);

    expect($status)->toBe('unknown');
});

it('aggregates multi-department slot statuses using worst severity when any department is unhealthy', function (): void {
    $route = new moduleWeatherAPIRoute();
    $slotKey = '2026-03-24 10:00';
    $targets = [
        1 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
        2 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
    ];

    $worst = weather_status_targets_invoke_private($route, 'calculateAggregatedDepartmentStatus', [
        [1, 2],
        [
            1 => [$slotKey => 14],
            2 => [$slotKey => 8],
        ],
        [
            1 => [$slotKey => 10.0],
            2 => [$slotKey => 10.0],
        ],
        $slotKey,
        true,
        $targets,
    ]);
    expect($worst)->toBe('unhealthy');
});

it('aggregates all-unhealthy multi-department slot statuses as unhealthy', function (): void {
    $route = new moduleWeatherAPIRoute();
    $slotKey = '2026-03-24 10:00';
    $targets = [
        1 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
        2 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
    ];

    $worst = weather_status_targets_invoke_private($route, 'calculateAggregatedDepartmentStatus', [
        [1, 2],
        [
            1 => [$slotKey => 3],
            2 => [$slotKey => 4],
        ],
        [
            1 => [$slotKey => 10.0],
            2 => [$slotKey => 10.0],
        ],
        $slotKey,
        true,
        $targets,
    ]);

    expect($worst)->toBe('unhealthy');
});

it('returns unknown when aggregated multi-department slot targets are missing', function (): void {
    $route = new moduleWeatherAPIRoute();
    $slotKey = '2026-03-24 10:00';

    $missingTargets = weather_status_targets_invoke_private($route, 'calculateAggregatedDepartmentStatus', [
        [1, 2],
        [
            1 => [$slotKey => 14],
            2 => [$slotKey => 8],
        ],
        [
            1 => [$slotKey => 10.0],
            2 => [$slotKey => 10.0],
        ],
        $slotKey,
        true,
        [
            1 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
        ],
    ]);
    expect($missingTargets)->toBe('unknown');
});

it('returns unknown when aggregated multi-department slot has no evaluable hours', function (): void {
    $route = new moduleWeatherAPIRoute();
    $slotKey = '2026-03-24 10:00';
    $targets = [
        1 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
        2 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
    ];

    $noEvaluableHours = weather_status_targets_invoke_private($route, 'calculateAggregatedDepartmentStatus', [
        [1, 2],
        [
            1 => [$slotKey => 0],
            2 => [$slotKey => 0],
        ],
        [
            1 => [$slotKey => 0.0],
            2 => [$slotKey => 0.0],
        ],
        $slotKey,
        true,
        $targets,
    ]);
    expect($noEvaluableHours)->toBe('unknown');
});

it('returns unknown when aggregated multi-department slot has not started yet', function (): void {
    $route = new moduleWeatherAPIRoute();
    $slotKey = '2026-03-24 10:00';
    $targets = [
        1 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
        2 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
    ];

    $futureSlot = weather_status_targets_invoke_private($route, 'calculateAggregatedDepartmentStatus', [
        [1, 2],
        [
            1 => [$slotKey => 14],
            2 => [$slotKey => 8],
        ],
        [
            1 => [$slotKey => 10.0],
            2 => [$slotKey => 10.0],
        ],
        $slotKey,
        false,
        $targets,
    ]);

    expect($futureSlot)->toBe('unknown');
});
