<?php

namespace Tests\Feature;

use App\Models\Room;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class RoomControllerTest extends TestCase
{
    use RefreshDatabase;

    public function test_can_view_rooms_index()
    {
        $user = User::factory()->create();
        $room = Room::create([
            'room_name' => 'TestRoom',
            'room_owner' => $user->username,
            'room_keep' => false,
        ]);

        $response = $this->actingAs($user)->get(route('rooms.index'));

        $response->assertStatus(200);
        $response->assertSee('TestRoom');
    }

    public function test_can_create_room_if_level_is_high_enough()
    {
        // Require level 10
        $user = User::factory()->create(['user_level' => 10]);

        $response = $this->actingAs($user)->post(route('rooms.store'), [
            'name' => 'NewRoom',
            'description' => 'Test Description',
        ]);

        $response->assertRedirect(route('rooms.index'));
        $this->assertDatabaseHas('rooms', [
            'room_name' => 'NewRoom',
            'room_owner' => $user->username,
        ]);
    }

    public function test_cannot_create_room_if_level_too_low()
    {
        $user = User::factory()->create(['user_level' => 9]);

        $response = $this->actingAs($user)->post(route('rooms.store'), [
            'name' => 'NewRoom',
        ]);

        $response->assertStatus(403);
        $this->assertDatabaseMissing('rooms', [
            'room_name' => 'NewRoom',
        ]);
    }

    public function test_room_owner_can_update_room()
    {
        $user = User::factory()->create();
        $room = Room::create([
            'room_name' => 'OldName',
            'room_owner' => $user->username,
            'room_keep' => false,
        ]);

        $response = $this->actingAs($user)->put(route('rooms.update', $room->id), [
            'name' => 'NewName',
        ]);

        $response->assertRedirect();
        $response->assertSessionHas('success');
        $this->assertDatabaseHas('rooms', [
            'id' => $room->id,
            'room_name' => 'NewName',
        ]);
    }

    public function test_non_owner_cannot_update_room()
    {
        $owner = User::factory()->create(['user_level' => 1]);
        $attacker = User::factory()->create(['user_level' => 1]);
        $room = Room::create([
            'room_name' => 'OldName',
            'room_owner' => $owner->username,
            'room_keep' => false,
        ]);

        $response = $this->actingAs($attacker)->put(route('rooms.update', $room->id), [
            'name' => 'HackName',
        ]);

        $response->assertStatus(403);
        $this->assertDatabaseHas('rooms', [
            'id' => $room->id,
            'room_name' => 'OldName',
        ]);
    }

    public function test_admin_can_update_any_room()
    {
        $owner = User::factory()->create(['user_level' => 1]);
        $admin = User::factory()->create(['user_level' => 15]);
        $room = Room::create([
            'room_name' => 'OldName',
            'room_owner' => $owner->username,
            'room_keep' => false,
        ]);

        $response = $this->actingAs($admin)->put(route('rooms.update', $room->id), [
            'name' => 'AdminRoom',
        ]);

        $response->assertRedirect();
        $this->assertDatabaseHas('rooms', [
            'id' => $room->id,
            'room_name' => 'AdminRoom',
        ]);
    }

    public function test_room_owner_can_destroy_non_system_room()
    {
        $user = User::factory()->create();
        $room = Room::create([
            'room_name' => 'ToDelete',
            'room_owner' => $user->username,
            'room_keep' => false,
        ]);

        $response = $this->actingAs($user)->delete(route('rooms.destroy', $room->id));

        $response->assertRedirect(route('rooms.index'));
        $this->assertDatabaseMissing('rooms', [
            'id' => $room->id,
        ]);
    }

    public function test_cannot_destroy_system_room()
    {
        $user = User::factory()->create(['user_level' => 20]);
        $room = Room::create([
            'room_name' => 'SysRoom',
            'room_owner' => $user->username,
            'room_keep' => true,
        ]);

        $response = $this->actingAs($user)->delete(route('rooms.destroy', $room->id));

        $response->assertStatus(403);
        $this->assertDatabaseHas('rooms', [
            'id' => $room->id,
        ]);
    }

    public function test_room_owner_can_transfer_room()
    {
        $owner = User::factory()->create();
        $target = User::factory()->create();

        $room = Room::create([
            'room_name' => 'TransferMe',
            'room_owner' => $owner->username,
            'room_keep' => false,
        ]);

        $response = $this->actingAs($owner)->post(route('rooms.transfer', $room->id), [
            'target_username' => $target->username,
        ]);

        $response->assertRedirect();
        $response->assertSessionHas('success');
        $this->assertDatabaseHas('rooms', [
            'id' => $room->id,
            'room_owner' => $target->username,
        ]);
    }

    public function test_cannot_transfer_to_invalid_user()
    {
        $owner = User::factory()->create();

        $room = Room::create([
            'room_name' => 'TransferMe',
            'room_owner' => $owner->username,
            'room_keep' => false,
        ]);

        $response = $this->actingAs($owner)->post(route('rooms.transfer', $room->id), [
            'target_username' => 'ghost_user_999',
        ]);

        $response->assertRedirect();
        $response->assertSessionHas('error');
        $this->assertDatabaseHas('rooms', [
            'id' => $room->id,
            'room_owner' => $owner->username,
        ]);
    }
}
