<?php

declare(strict_types=1);

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Spatie\Activitylog\Models\Activity;
use Spatie\Permission\Models\Role;

uses(RefreshDatabase::class);

beforeEach(function () {
    $this->seed();
});

test('unauthorized users cannot view or manage users list', function () {
    $user = User::where('email', 'user@example.com')->first();
    
    $this->actingAs($user)
        ->get(route('users.index'))
        ->assertStatus(403);
});

test('authorized users can view users list', function () {
    $admin = User::where('email', 'admin@example.com')->first();
    
    $this->actingAs($admin)
        ->get(route('users.index'))
        ->assertOk();
});

test('authorized users can create a new user with roles and trigger activity log', function () {
    $admin = User::where('email', 'admin@example.com')->first();
    
    $this->actingAs($admin)
        ->post(route('users.store'), [
            'name' => 'New Staff',
            'email' => 'staff@example.com',
            'password' => 'password123',
            'roles' => ['Manager'],
        ])
        ->assertRedirect();

    $newUser = User::where('email', 'staff@example.com')->first();
    expect($newUser)->not->toBeNull();
    expect($newUser->name)->toBe('New Staff');
    expect($newUser->hasRole('Manager'))->toBeTrue();

    // Verify activity was logged
    $this->assertDatabaseHas('activity_log', [
        'description' => 'Created user: New Staff (staff@example.com)',
        'causer_id' => $admin->id,
        'subject_id' => $newUser->id,
    ]);
});

test('user creation validations enforce unique email and robust inputs', function () {
    $admin = User::where('email', 'admin@example.com')->first();
    
    $this->actingAs($admin)
        ->post(route('users.store'), [
            'name' => '',
            'email' => 'not-an-email',
            'password' => '123', // Too short
        ])
        ->assertSessionHasErrors(['name', 'email', 'password']);
});

test('authorized users can update user details and roles', function () {
    $admin = User::where('email', 'admin@example.com')->first();
    $targetUser = User::where('email', 'user@example.com')->first();

    $this->actingAs($admin)
        ->put(route('users.update', $targetUser->id), [
            'name' => 'Updated User Name',
            'email' => 'user.updated@example.com',
            'roles' => ['Manager', 'User'],
        ])
        ->assertRedirect();

    $targetUser->refresh();
    expect($targetUser->name)->toBe('Updated User Name');
    expect($targetUser->email)->toBe('user.updated@example.com');
    expect($targetUser->hasRole('Manager'))->toBeTrue();
    expect($targetUser->hasRole('User'))->toBeTrue();

    // Verify activity log
    $this->assertDatabaseHas('activity_log', [
        'description' => 'Updated user: Updated User Name (user.updated@example.com)',
        'causer_id' => $admin->id,
        'subject_id' => $targetUser->id,
    ]);
});

test('users cannot delete their own account', function () {
    $admin = User::where('email', 'admin@example.com')->first();

    $this->actingAs($admin)
        ->delete(route('users.destroy', $admin->id))
        ->assertRedirect()
        ->assertSessionHas('error', 'You cannot delete your own account.');

    // Verify user is not deleted
    expect(User::where('id', $admin->id)->exists())->toBeTrue();
});

test('authorized users can delete other users', function () {
    $admin = User::where('email', 'admin@example.com')->first();
    $targetUser = User::where('email', 'user@example.com')->first();

    $this->actingAs($admin)
        ->delete(route('users.destroy', $targetUser->id))
        ->assertRedirect()
        ->assertSessionHas('success', 'User deleted successfully.');

    // Verify user is deleted
    expect(User::where('id', $targetUser->id)->exists())->toBeFalse();

    // Verify activity log has deletion entry
    $this->assertDatabaseHas('activity_log', [
        'description' => 'Deleted user: Regular User (user@example.com)',
        'causer_id' => $admin->id,
    ]);
});
