<?php

namespace Tests\Feature;

use App\Models\Attendance;
use App\Models\Company;
use App\Models\Role;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class UserTypeDirectoryTest extends TestCase
{
    use RefreshDatabase;

    public function test_tenant_hr_admin_visible_ids_exclude_company_admin_user_type(): void
    {
        $company = Company::query()->create([
            'name' => 'ACME',
            'short_name' => 'ACME',
            'email' => 'co@acme.test',
            'status' => 'active',
        ]);

        $adminRole = Role::withoutCompanyScope()->create([
            'company_id' => $company->id,
            'name' => 'admin',
            'display_name' => 'Admin',
        ]);
        $empRole = Role::withoutCompanyScope()->create([
            'company_id' => $company->id,
            'name' => 'employee',
            'display_name' => 'Employee',
        ]);

        $companyAdmin = User::factory()->create([
            'company_id' => $company->id,
            'role_id' => $adminRole->id,
            'user_type' => User::USER_TYPE_ADMIN,
        ]);

        $regular = User::factory()->create([
            'company_id' => $company->id,
            'role_id' => $empRole->id,
            'user_type' => User::USER_TYPE_STAFF,
        ]);

        $ids = $companyAdmin->visibleStaffUserIds();
        $this->assertContains($regular->id, $ids);
        $this->assertNotContains($companyAdmin->id, $ids);
    }

    public function test_cannot_change_user_type_to_admin_when_attendance_exists(): void
    {
        $company = Company::query()->create([
            'name' => 'ACME2',
            'short_name' => 'ACM2',
            'email' => 'co2@acme.test',
            'status' => 'active',
        ]);

        $u = User::factory()->create([
            'company_id' => $company->id,
            'user_type' => User::USER_TYPE_STAFF,
        ]);

        Attendance::query()->create([
            'company_id' => $company->id,
            'user_id' => $u->id,
            'date' => now()->toDateString(),
            'status' => 'present',
        ]);

        $this->expectException(\InvalidArgumentException::class);
        $u->update(['user_type' => User::USER_TYPE_ADMIN]);
    }

    public function test_for_tenant_directory_scope_lists_only_staff_members_user_type(): void
    {
        $company = Company::query()->create([
            'name' => 'ACME3',
            'short_name' => 'ACM3',
            'email' => 'co3@acme.test',
            'status' => 'active',
        ]);

        User::factory()->create([
            'company_id' => $company->id,
            'user_type' => User::USER_TYPE_ADMIN,
        ]);
        $emp = User::factory()->create([
            'company_id' => $company->id,
            'user_type' => User::USER_TYPE_STAFF,
        ]);

        $this->assertEquals(1, User::forTenantDirectory()->where('company_id', $company->id)->count());
        $this->assertTrue(User::forTenantDirectory()->whereKey($emp->id)->exists());
    }

    public function test_for_active_directory_scope_excludes_inactive_staff(): void
    {
        $company = Company::query()->create([
            'name' => 'ACME4',
            'short_name' => 'ACM4',
            'email' => 'co4@acme.test',
            'status' => 'active',
        ]);

        $active = User::factory()->create([
            'company_id' => $company->id,
            'user_type' => User::USER_TYPE_STAFF,
            'status' => User::STATUS_ACTIVE,
        ]);
        User::factory()->create([
            'company_id' => $company->id,
            'user_type' => User::USER_TYPE_STAFF,
            'status' => User::STATUS_INACTIVE,
        ]);

        $this->assertEquals(2, User::forTenantDirectory()->where('company_id', $company->id)->count());
        $this->assertEquals(1, User::forActiveDirectory()->where('company_id', $company->id)->count());
        $this->assertTrue(User::forActiveDirectory()->whereKey($active->id)->exists());
    }
}
