<?php

namespace Tests\Traits;

use App\Models\Settings;
use App\Models\User;
use Spatie\Permission\Models\Role;

/**
 * Helper trait for creating test users with various roles.
 */
trait CreatesUsers
{
    /**
     * Create and return an admin user.
     */
    protected function createAdmin(array $attributes = []): User
    {
        $this->ensureRoleExists('admin');

        return User::factory()->admin()->create($attributes);
    }

    /**
     * Create and return an HR user.
     */
    protected function createHrUser(array $attributes = []): User
    {
        $this->ensureRoleExists('hr');

        return User::factory()->hr()->create($attributes);
    }

    /**
     * Create and return a manager user.
     */
    protected function createManager(array $attributes = []): User
    {
        $this->ensureRoleExists('manager');

        return User::factory()->manager()->create($attributes);
    }

    /**
     * Create and return a field employee user.
     */
    protected function createFieldEmployee(array $attributes = []): User
    {
        $this->ensureRoleExists('field_employee');

        return User::factory()->fieldEmployee()->create($attributes);
    }

    /**
     * Create a regular user without any role.
     */
    protected function createUser(array $attributes = []): User
    {
        return User::factory()->create($attributes);
    }

    /**
     * Act as an admin user for the current test.
     */
    protected function actingAsAdmin(array $attributes = []): self
    {
        return $this->actingAs($this->createAdmin($attributes));
    }

    /**
     * Act as an HR user for the current test.
     */
    protected function actingAsHr(array $attributes = []): self
    {
        return $this->actingAs($this->createHrUser($attributes));
    }

    /**
     * Act as a manager user for the current test.
     */
    protected function actingAsManager(array $attributes = []): self
    {
        return $this->actingAs($this->createManager($attributes));
    }

    /**
     * Act as a field employee user for the current test.
     */
    protected function actingAsFieldEmployee(array $attributes = []): self
    {
        return $this->actingAs($this->createFieldEmployee($attributes));
    }

    /**
     * Act as the given user for API requests.
     */
    protected function actingAsApiUser(User $user, string $guard = 'api'): self
    {
        return $this->actingAs($user, $guard);
    }

    /**
     * Ensure a role exists in the database with web access enabled.
     */
    protected function ensureRoleExists(string $roleName): void
    {
        if (! Role::where('name', $roleName)->exists()) {
            Role::create([
                'name' => $roleName,
                'guard_name' => 'web',
                'is_web_access_enabled' => true,
                'is_mobile_app_access_enabled' => in_array($roleName, ['field_employee', 'admin']),
            ]);
        }
    }

    /**
     * Ensure Settings exists for view rendering.
     * Required for views that reference $settings->app_logo etc.
     */
    protected function ensureSettingsExist(): Settings
    {
        $settings = Settings::first();
        if ($settings) {
            return $settings;
        }

        return Settings::create([
            'website' => 'https://test.example.com',
            'support_email' => 'test@example.com',
            'support_phone' => '+1234567890',
            'company_name' => 'Test Company',
            'company_logo' => 'test_logo.png',
            'app_logo' => 'test_logo.png',
            'company_address' => '123 Test Street',
            'company_email' => 'company@example.com',
        ]);
    }
}
