<?php

namespace Tests\Unit\Models;

use App\Models\Project;
use App\Models\ProjectStatus;
use App\Services\ProjectService;
use Database\Seeders\ProjectStatusSeeder;
use Database\Seeders\ProjectTypeSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ProjectForecastTest extends TestCase
{
    use RefreshDatabase;

    // 3.1.24 Unit test: Forecasted effort validation
    public function test_forecasted_effort_validation()
    {
        $this->seed([ProjectStatusSeeder::class, ProjectTypeSeeder::class]);

        $service = app(ProjectService::class);

        $status = ProjectStatus::firstOrFail();
        $project = Project::factory()->create([
            'status_id' => $status->id,
        ]);

        $forecast = ['2026-01' => 20, '2026-02' => 30];

        $updated = $service->setForecastedEffort($project, $forecast);

        $this->assertSame($forecast, $updated->forecasted_effort);
    }

    public function test_forecasted_sum_must_equal_approved_estimate()
    {
        $this->seed([ProjectStatusSeeder::class, ProjectTypeSeeder::class]);

        $service = app(ProjectService::class);

        $status = ProjectStatus::firstOrFail();
        $project = Project::factory()->create([
            'status_id' => $status->id,
        ]);

        $service->setApprovedEstimate($project, 100);

        $forecast = ['2026-01' => 40, '2026-02' => 60];
        $updated = $service->setForecastedEffort($project, $forecast);

        $this->assertEquals(100, array_sum($updated->forecasted_effort));
    }

    public function test_forecasted_effort_tolerance()
    {
        $this->seed([ProjectStatusSeeder::class, ProjectTypeSeeder::class]);

        $service = app(ProjectService::class);

        $status = ProjectStatus::firstOrFail();
        $project = Project::factory()->create([
            'status_id' => $status->id,
        ]);

        $service->setApprovedEstimate($project, 100);

        $forecastWithinTolerance = ['2026-01' => 50, '2026-02' => 55];
        $service->setForecastedEffort($project, $forecastWithinTolerance);

        $this->assertEquals(105, array_sum($project->refresh()->forecasted_effort));

        $forecastTooHigh = ['2026-01' => 60, '2026-02' => 50];

        $this->expectException(\RuntimeException::class);
        $service->setForecastedEffort($project, $forecastTooHigh);
    }
}
