<?php

namespace Tests\Feature;

use App\Models\Allocation;
use App\Models\Role;
use App\Models\TeamMember;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class UtilizationTest extends TestCase
{
    use RefreshDatabase;

    protected function loginAsManager(): string
    {
        $user = User::factory()->create([
            'email' => 'manager@test.com',
            'password' => bcrypt('password123'),
            'role' => 'manager',
            'active' => true,
        ]);

        $response = $this->postJson('/api/auth/login', [
            'email' => 'manager@test.com',
            'password' => 'password123',
        ]);

        return $response->json('access_token');
    }

    // 7.1.9 GET /api/utilization/running calculates YTD
    public function test_get_utilization_running_calculates_ytd(): void
    {
        $token = $this->loginAsManager();

        $role = Role::factory()->create();
        $member = TeamMember::factory()->create(['role_id' => $role->id, 'active' => true]);

        // Create allocations for Jan, Feb, Mar 2026
        Allocation::factory()->create([
            'team_member_id' => $member->id,
            'month' => '2026-01-01',
            'allocated_hours' => 140,
        ]);
        Allocation::factory()->create([
            'team_member_id' => $member->id,
            'month' => '2026-02-01',
            'allocated_hours' => 150,
        ]);
        Allocation::factory()->create([
            'team_member_id' => $member->id,
            'month' => '2026-03-01',
            'allocated_hours' => 160,
        ]);

        $response = $this->withHeader('Authorization', "Bearer {$token}")
            ->getJson("/api/utilization/running?team_member_id={$member->id}&month=2026-03");

        $response->assertStatus(200)
            ->assertJsonStructure([
                'capacity_ytd',
                'allocated_ytd',
                'utilization',
                'indicator',
                'months_included',
            ])
            ->assertJson([
                'allocated_ytd' => 450.0,
                'months_included' => 3,
            ]);
    }

    // 7.1.10 GET /api/utilization/overall calculates monthly
    public function test_get_utilization_overall_calculates_monthly(): void
    {
        $token = $this->loginAsManager();

        $role = Role::factory()->create();
        $member = TeamMember::factory()->create(['role_id' => $role->id, 'active' => true]);

        Allocation::factory()->create([
            'team_member_id' => $member->id,
            'month' => '2026-02-01',
            'allocated_hours' => 140,
        ]);

        $response = $this->withHeader('Authorization', "Bearer {$token}")
            ->getJson("/api/utilization/overall?team_member_id={$member->id}&month=2026-02");

        $response->assertStatus(200)
            ->assertJsonStructure([
                'capacity',
                'allocated',
                'utilization',
                'indicator',
            ])
            ->assertJson([
                'allocated' => 140.0,
            ]);
    }

    // 7.1.11 Utilization includes in allocation response
    public function test_utilization_included_in_team_members_response(): void
    {
        $token = $this->loginAsManager();

        $role = Role::factory()->create();
        $member = TeamMember::factory()->create(['role_id' => $role->id, 'active' => true]);

        Allocation::factory()->create([
            'team_member_id' => $member->id,
            'month' => '2026-02-01',
            'allocated_hours' => 140,
        ]);

        // Get team member with utilization data
        $response = $this->withHeader('Authorization', "Bearer {$token}")
            ->getJson("/api/team-members/{$member->id}?include_utilization=true&month=2026-02");

        $response->assertStatus(200)
            ->assertJsonStructure([
                'data' => [
                    'id',
                    'name',
                    'utilization' => [
                        'overall',
                        'running',
                    ],
                ],
            ]);
    }

    public function test_utilization_team_endpoint_returns_aggregate(): void
    {
        $token = $this->loginAsManager();

        $role = Role::factory()->create();
        $memberA = TeamMember::factory()->create(['role_id' => $role->id, 'active' => true]);
        $memberB = TeamMember::factory()->create(['role_id' => $role->id, 'active' => true]);

        Allocation::factory()->create([
            'team_member_id' => $memberA->id,
            'month' => '2026-02-01',
            'allocated_hours' => 140,
        ]);
        Allocation::factory()->create([
            'team_member_id' => $memberB->id,
            'month' => '2026-02-01',
            'allocated_hours' => 150,
        ]);

        $response = $this->withHeader('Authorization', "Bearer {$token}")
            ->getJson('/api/utilization/team?month=2026-02');

        $response->assertStatus(200)
            ->assertJsonStructure([
                'average_utilization',
                'average_indicator',
                'member_count',
                'by_member',
            ])
            ->assertJson([
                'member_count' => 2,
            ]);
    }

    public function test_utilization_requires_authentication(): void
    {
        $response = $this->getJson('/api/utilization/overall?team_member_id=123&month=2026-02');

        $response->assertStatus(401);
    }

    public function test_utilization_validates_required_parameters(): void
    {
        $token = $this->loginAsManager();

        $response = $this->withHeader('Authorization', "Bearer {$token}")
            ->getJson('/api/utilization/overall');

        $response->assertStatus(422)
            ->assertJsonValidationErrors(['team_member_id', 'month']);
    }
}
