<?php

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

uses(RefreshDatabase::class);

it('loads app data when appinfo event is dispatched', function () {
    $user = User::factory()->create(['is_admin' => true]);
    $app = Application::factory()->create([
        'name' => 'Test Application',
        'icon' => 'https://example.com/test-icon.png'
    ]);
    
    $this->actingAs($user);
    
    $component = Livewire::test(AppInfoModal::class)
        ->call('loadApp', $app->id);
    
    expect($component->get('app')->id)->toBe($app->id);
    expect($component->get('name'))->toBe('Test Application');
    expect($component->get('icon'))->toBe('https://example.com/test-icon.png');
});

it('updates icon when query is changed', function () {
    $user = User::factory()->create(['is_admin' => true]);
    $app = Application::factory()->create();
    
    $this->actingAs($user);
    
    $component = Livewire::test(AppInfoModal::class)
        ->call('loadApp', $app->id)
        ->set('query', 'nextcloud');
    
    expect($component->get('icon'))->toBe('https://cdn.jsdelivr.net/gh/selfhst/icons/webp/nextcloud.webp');
});

it('does not update icon when query is empty', function () {
    $user = User::factory()->create(['is_admin' => true]);
    $app = Application::factory()->create();
    
    $this->actingAs($user);
    
    $component = Livewire::test(AppInfoModal::class)
        ->call('loadApp', $app->id)
        ->set('query', 'test')
        ->set('query', '');
    
    // Icon should remain the same as before setting empty query
    expect($component->get('icon'))->toBe('https://cdn.jsdelivr.net/gh/selfhst/icons/webp/test.webp');
});

it('converts query to kebab case for icon URL', function () {
    $user = User::factory()->create(['is_admin' => true]);
    $app = Application::factory()->create();
    
    $this->actingAs($user);
    
    $component = Livewire::test(AppInfoModal::class)
        ->call('loadApp', $app->id)
        ->set('query', 'Home Assistant');
    
    expect($component->get('icon'))->toBe('https://cdn.jsdelivr.net/gh/selfhst/icons/webp/home-assistant.webp');
});

it('can save updated app information', function () {
    $user = User::factory()->create(['is_admin' => true]);
    $app = Application::factory()->create([
        'name' => 'Original Name',
        'icon' => 'https://example.com/original.png'
    ]);
    
    $this->actingAs($user);
    
    Livewire::test(AppInfoModal::class)
        ->call('loadApp', $app->id)
        ->set('name', 'Updated App Name')
        ->set('icon', 'https://example.com/new-icon.png')
        ->call('save');
    
    $app->refresh();
    expect($app->name)->toBe('Updated App Name');
    expect($app->icon)->toBe('https://example.com/new-icon.png');
});

it('dispatches app-updated event after saving', function () {
    $user = User::factory()->create(['is_admin' => true]);
    $app = Application::factory()->create();
    
    $this->actingAs($user);
    
    Livewire::test(AppInfoModal::class)
        ->call('loadApp', $app->id)
        ->set('name', 'Updated App Name')
        ->call('save')
        ->assertDispatched('app-updated', ['id' => $app->id]);
});

it('can update only name without changing icon', function () {
    $user = User::factory()->create(['is_admin' => true]);
    $app = Application::factory()->create([
        'name' => 'Original Name',
        'icon' => 'https://example.com/original.png'
    ]);
    
    $this->actingAs($user);
    
    $originalIcon = $app->icon;
    
    Livewire::test(AppInfoModal::class)
        ->call('loadApp', $app->id)
        ->set('name', 'New Name Only')
        ->call('save');
    
    $app->refresh();
    expect($app->name)->toBe('New Name Only');
    expect($app->icon)->toBe($originalIcon);
});

it('can update only icon without changing name', function () {
    $user = User::factory()->create(['is_admin' => true]);
    $app = Application::factory()->create([
        'name' => 'Original Name',
        'icon' => 'https://example.com/original.png'
    ]);
    
    $this->actingAs($user);
    
    $originalName = $app->name;
    
    Livewire::test(AppInfoModal::class)
        ->call('loadApp', $app->id)
        ->set('icon', 'https://example.com/new-icon-only.png')
        ->call('save');
    
    $app->refresh();
    expect($app->name)->toBe($originalName);
    expect($app->icon)->toBe('https://example.com/new-icon-only.png');
});

it('handles special characters in query correctly', function () {
    $user = User::factory()->create(['is_admin' => true]);
    $app = Application::factory()->create();
    
    $this->actingAs($user);
    
    $component = Livewire::test(AppInfoModal::class)
        ->call('loadApp', $app->id)
        ->set('query', 'App with Spaces & Special-Chars!');
    
    expect($component->get('icon'))->toBe('https://cdn.jsdelivr.net/gh/selfhst/icons/webp/app-with-spaces&-special--chars!.webp');
});

it('loads app with null icon correctly', function () {
    $user = User::factory()->create(['is_admin' => true]);
    $appWithNullIcon = Application::factory()->create(['icon' => null]);
    
    $this->actingAs($user);
    
    $component = Livewire::test(AppInfoModal::class)
        ->call('loadApp', $appWithNullIcon->id);
    
    expect($component->get('icon'))->toBeNull();
    expect($component->get('name'))->toBe($appWithNullIcon->name);
});

it('preserves original icon when setting empty query', function () {
    $user = User::factory()->create(['is_admin' => true]);
    $app = Application::factory()->create(['icon' => 'https://example.com/original.png']);
    
    $this->actingAs($user);
    
    $component = Livewire::test(AppInfoModal::class)
        ->call('loadApp', $app->id);
    
    $originalIcon = $component->get('icon');
    
    // Setting empty query should not change the icon
    $component->set('query', '');
    expect($component->get('icon'))->toBe($originalIcon);
});

it('updates properties correctly when loading different apps', function () {
    $user = User::factory()->create(['is_admin' => true]);
    $app1 = Application::factory()->create([
        'name' => 'First Application',
        'icon' => 'https://example.com/first-icon.png'
    ]);
    $app2 = Application::factory()->create([
        'name' => 'Second Application',
        'icon' => 'https://example.com/second-icon.png'
    ]);
    
    $this->actingAs($user);
    
    $component = Livewire::test(AppInfoModal::class)
        ->call('loadApp', $app1->id);
    
    expect($component->get('name'))->toBe('First Application');
    
    $component->call('loadApp', $app2->id);
    
    expect($component->get('app')->id)->toBe($app2->id);
    expect($component->get('name'))->toBe('Second Application');
    expect($component->get('icon'))->toBe('https://example.com/second-icon.png');
});

it('query to icon conversion handles edge cases', function () {
    $user = User::factory()->create(['is_admin' => true]);
    $app = Application::factory()->create();
    
    $this->actingAs($user);
    
    $component = Livewire::test(AppInfoModal::class)
        ->call('loadApp', $app->id);
    
    // Test uppercase conversion
    $component->set('query', 'NEXTCLOUD');
    expect($component->get('icon'))->toBe('https://cdn.jsdelivr.net/gh/selfhst/icons/webp/n-e-x-t-c-l-o-u-d.webp');
    
    // Test numbers and special chars
    $component->set('query', 'App123-test_name');
    expect($component->get('icon'))->toBe('https://cdn.jsdelivr.net/gh/selfhst/icons/webp/app123-test_name.webp');
});