<?php

use App\Livewire\AppContainer;
use App\Models\Application;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;

uses(RefreshDatabase::class);

beforeEach(function () {
    $this->admin = User::factory()->create(['is_admin' => true]);
    $this->user = User::factory()->create(['is_admin' => false]);
});

describe('AppContainer Component', function () {
    
    it('loads applications for authorized users', function () {
        $app1 = Application::factory()->create(['name' => 'Test App 1']);
        $app2 = Application::factory()->create(['name' => 'Test App 2']);
        
        $this->actingAs($this->admin);
        
        $component = Livewire::test(AppContainer::class);
        
        expect($component->get('apps')->count())->toBe(2);
        expect($component->get('apps')->pluck('name')->toArray())->toContain('Test App 1', 'Test App 2');
    });

    it('initializes apps as empty collection for unauthorized users', function () {
        Application::factory()->create(['name' => 'Test App']);
        
        $this->actingAs($this->user);
        
        // Test using Livewire test helper but only verify the mount logic
        $component = new AppContainer();
        
        // Initialize apps as empty Eloquent collection since it's a typed property
        $component->apps = new \Illuminate\Database\Eloquent\Collection();
        $component->mount();
        
        // Apps should remain empty for unauthorized users
        expect($component->apps->count())->toBe(0);
    });

    it('can confirm deletion of an application', function () {
        $app = Application::factory()->create(['name' => 'Test App']);
        
        $this->actingAs($this->admin);
        
        $component = Livewire::test(AppContainer::class)
            ->call('confirmDelete', $app->id);
            
        expect($component->get('confirmDeleteApp'))->not()->toBeNull();
        expect($component->get('confirmDeleteApp')->id)->toBe($app->id);
    });

    it('can cancel deletion of an application', function () {
        $app = Application::factory()->create(['name' => 'Test App']);
        
        $this->actingAs($this->admin);
        
        $component = Livewire::test(AppContainer::class)
            ->call('confirmDelete', $app->id)
            ->call('cancelDelete');
            
        expect($component->get('confirmDeleteApp'))->toBeNull();
    });

    it('can delete an application when authorized', function () {
        $app = Application::factory()->create(['name' => 'Test App']);
        
        $this->actingAs($this->admin);
        
        $component = Livewire::test(AppContainer::class)
            ->call('confirmDelete', $app->id)
            ->call('deleteApp');
            
        // Verify app was deleted from database
        $this->assertDatabaseMissing('applications', ['id' => $app->id]);
        
        // Verify app was removed from component state
        expect($component->get('apps')->where('id', $app->id)->count())->toBe(0);
        expect($component->get('confirmDeleteApp'))->toBeNull();
    });

    it('prevents unauthorized users from deleting applications', function () {
        $app = Application::factory()->create(['name' => 'Test App']);
        
        $this->actingAs($this->user);
        
        // Test the component logic directly to avoid view rendering issues
        $component = new AppContainer();
        $component->confirmDeleteApp = $app;
        
        $this->expectException(\Illuminate\Auth\Access\AuthorizationException::class);
        $component->deleteApp();
    });

    it('handles app-updated event', function () {
        $app = Application::factory()->create(['name' => 'Original Name']);
        
        $this->actingAs($this->admin);
        
        $component = Livewire::test(AppContainer::class);
        
        // Update the app in the database
        $app->update(['name' => 'Updated Name']);
        
        // Trigger the event
        $component->dispatch('app-updated', $app->id);
        
        // Verify the app in the component was updated
        $updatedApp = $component->get('apps')->where('id', $app->id)->first();
        expect($updatedApp->name)->toBe('Updated Name');
    });

    it('orders applications by id', function () {
        $app1 = Application::factory()->create(['name' => 'App Z']);
        $app2 = Application::factory()->create(['name' => 'App A']);
        $app3 = Application::factory()->create(['name' => 'App M']);
        
        $this->actingAs($this->admin);
        
        $component = Livewire::test(AppContainer::class);
        
        $appIds = $component->get('apps')->pluck('id')->toArray();
        
        // Should be ordered by ID (which is typically creation order)
        expect($appIds)->toBe([$app1->id, $app2->id, $app3->id]);
    });

    it('can reload apps manually', function () {
        $this->actingAs($this->admin);
        
        $component = Livewire::test(AppContainer::class);
        
        // Initially no apps
        expect($component->get('apps')->count())->toBe(0);
        
        // Create an app after component is loaded
        $app = Application::factory()->create(['name' => 'New App']);
        
        // Reload apps
        $component->call('loadApps');
        
        // Should now include the new app
        expect($component->get('apps')->count())->toBe(1);
        expect($component->get('apps')->first()->name)->toBe('New App');
    });

    it('handles empty application list', function () {
        $this->actingAs($this->admin);
        
        $component = Livewire::test(AppContainer::class);
        
        expect($component->get('apps')->count())->toBe(0);
        expect($component->get('apps'))->toBeInstanceOf(\Illuminate\Database\Eloquent\Collection::class);
    });
});