<?php

namespace Tests\Feature;

use App\Models\Company;
use App\Models\Complaint;
use App\Models\Permission;
use App\Models\Role;
use App\Models\User;
use App\Services\TenantRoleService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ComplaintAccessTest extends TestCase
{
    use RefreshDatabase;

    private function seedCompanyWithRoles(): array
    {
        $company = Company::query()->create([
            'name' => 'Test Co',
            'short_name' => 'TST',
            'email' => 'test-co@example.com',
            'status' => 'active',
        ]);

        return TenantRoleService::syncAllDefaultRolesForCompany((int) $company->id);
    }

    private function userWithRole(int $companyId, string $roleName): User
    {
        $role = Role::withoutGlobalScopes()
            ->where('company_id', $companyId)
            ->where('name', $roleName)
            ->firstOrFail();

        return User::factory()->create([
            'company_id' => $companyId,
            'role_id' => $role->id,
            'is_superadmin' => false,
            'allow_login' => true,
        ]);
    }

    public function test_hr_sees_all_company_complaints(): void
    {
        $roles = $this->seedCompanyWithRoles();
        $companyId = (int) $roles['hr']->company_id;
        $hr = $this->userWithRole($companyId, 'hr');
        $employeeA = User::factory()->create(['company_id' => $companyId, 'name' => 'Alice']);
        $employeeB = User::factory()->create(['company_id' => $companyId, 'name' => 'Bob']);

        Complaint::withoutGlobalScopes()->create([
            'company_id' => $companyId,
            'from_user_id' => $employeeA->id,
            'subject' => 'Alice complaint',
            'complaint_date' => now(),
            'status' => 'pending',
        ]);
        Complaint::withoutGlobalScopes()->create([
            'company_id' => $companyId,
            'from_user_id' => $employeeB->id,
            'subject' => 'Bob complaint',
            'complaint_date' => now(),
            'status' => 'pending',
        ]);

        $response = $this->actingAs($hr)->get(route('complaints.index'));

        $response->assertOk();
        $response->assertSee('Alice complaint');
        $response->assertSee('Bob complaint');
    }

    public function test_employee_sees_only_own_complaints(): void
    {
        $roles = $this->seedCompanyWithRoles();
        $companyId = (int) $roles['employee']->company_id;
        $employee = $this->userWithRole($companyId, 'employee');
        $other = User::factory()->create(['company_id' => $companyId]);

        Complaint::withoutGlobalScopes()->create([
            'company_id' => $companyId,
            'from_user_id' => $employee->id,
            'subject' => 'My complaint',
            'complaint_date' => now(),
            'status' => 'pending',
        ]);
        Complaint::withoutGlobalScopes()->create([
            'company_id' => $companyId,
            'from_user_id' => $other->id,
            'subject' => 'Someone else complaint',
            'complaint_date' => now(),
            'status' => 'pending',
        ]);

        $response = $this->actingAs($employee)->get(route('complaints.index'));

        $response->assertOk();
        $response->assertSee('My complaint');
        $response->assertDontSee('Someone else complaint');
    }

    public function test_employee_cannot_edit_complaint(): void
    {
        $roles = $this->seedCompanyWithRoles();
        $companyId = (int) $roles['employee']->company_id;
        $employee = $this->userWithRole($companyId, 'employee');
        $complaint = Complaint::withoutGlobalScopes()->create([
            'company_id' => $companyId,
            'from_user_id' => $employee->id,
            'subject' => 'My complaint',
            'complaint_date' => now(),
            'status' => 'pending',
        ]);

        $this->actingAs($employee)
            ->get(route('complaints.edit', $complaint))
            ->assertForbidden();
    }

    public function test_employee_submit_sets_from_user_automatically(): void
    {
        $roles = $this->seedCompanyWithRoles();
        $companyId = (int) $roles['employee']->company_id;
        $employee = $this->userWithRole($companyId, 'employee');

        $this->actingAs($employee)->post(route('complaints.store'), [
            'subject' => 'Harassment report',
            'complaint_date' => now()->toDateString(),
            'description' => 'Details here',
        ])->assertRedirect(route('complaints.index'));

        $this->assertDatabaseHas('complaints', [
            'company_id' => $companyId,
            'from_user_id' => $employee->id,
            'subject' => 'Harassment report',
            'status' => 'pending',
        ]);
    }

    public function test_employee_permissions_exist_after_seeder(): void
    {
        (new \Database\Seeders\RolePermissionSeeder())->run();

        $this->assertNotNull(Permission::where('name', 'complaints_view_own')->first());
        $this->assertNotNull(Permission::where('name', 'complaints_create_own')->first());
    }
}
