<?php

use App\Domains\QrCode\Models\QrCode;
use App\Domains\Workspace\Models\Workspace;
use App\Domains\Workspace\Models\WorkspaceMember;
use App\Livewire\Modals\CreateQrCode;
use App\Livewire\Modals\DeleteQrCode;
use App\Livewire\Modals\EditQrCode;
use App\Models\User;
use Livewire\Livewire;

function makeUserWithWsForQr(): array
{
    $user = User::factory()->create();
    $ws = Workspace::factory()->create(['owner_id' => $user->id]);
    WorkspaceMember::create([
        'workspace_id' => $ws->id,
        'user_id' => $user->id,
        'role' => 'owner',
        'joined_at' => now(),
    ]);

    return [$user, $ws];
}

// CreateQrCode

it('renders create qr code modal', function () {
    [$user, $ws] = makeUserWithWsForQr();
    app()->instance('current_workspace', $ws);

    Livewire::actingAs($user)->test(CreateQrCode::class)
        ->assertOk()
        ->assertSee('QR Code');
});

it('validates required url on create qr code', function () {
    [$user, $ws] = makeUserWithWsForQr();
    app()->instance('current_workspace', $ws);

    Livewire::actingAs($user)->test(CreateQrCode::class)
        ->call('save')
        ->assertHasErrors(['url' => 'required']);
});

it('validates url format on create qr code', function () {
    [$user, $ws] = makeUserWithWsForQr();
    app()->instance('current_workspace', $ws);

    Livewire::actingAs($user)->test(CreateQrCode::class)
        ->set('url', 'not-a-url')
        ->call('save')
        ->assertHasErrors(['url']);
});

it('creates qr code and dispatches event', function () {
    [$user, $ws] = makeUserWithWsForQr();
    app()->instance('current_workspace', $ws);

    Livewire::actingAs($user)->test(CreateQrCode::class)
        ->set('url', 'https://example.com')
        ->set('label', 'My QR')
        ->call('save')
        ->assertDispatched('qr-created')
        ->assertDispatched('toast');

    $this->assertDatabaseHas('qr_codes', [
        'workspace_id' => $ws->id,
        'type' => 'url',
    ]);
});

// EditQrCode

it('renders edit qr code modal with existing data', function () {
    [$user, $ws] = makeUserWithWsForQr();
    app()->instance('current_workspace', $ws);
    $qr = QrCode::factory()->create(['workspace_id' => $ws->id, 'payload' => ['url' => 'https://old.com']]);

    Livewire::actingAs($user)->test(EditQrCode::class, ['qrUlid' => $qr->ulid])
        ->assertOk()
        ->assertSet('url', 'https://old.com');
});

it('updates qr code and dispatches event', function () {
    [$user, $ws] = makeUserWithWsForQr();
    app()->instance('current_workspace', $ws);
    $qr = QrCode::factory()->create(['workspace_id' => $ws->id, 'payload' => ['url' => 'https://old.com']]);

    Livewire::actingAs($user)->test(EditQrCode::class, ['qrUlid' => $qr->ulid])
        ->set('url', 'https://new.com')
        ->call('save')
        ->assertDispatched('qr-updated')
        ->assertDispatched('toast');

    expect($qr->fresh()->payload['url'])->toBe('https://new.com');
});

// DeleteQrCode

it('renders delete qr code modal', function () {
    [$user, $ws] = makeUserWithWsForQr();
    app()->instance('current_workspace', $ws);
    $qr = QrCode::factory()->create(['workspace_id' => $ws->id]);

    Livewire::actingAs($user)->test(DeleteQrCode::class, ['qrUlid' => $qr->ulid])
        ->assertOk();
});

it('deletes qr code and dispatches event', function () {
    [$user, $ws] = makeUserWithWsForQr();
    app()->instance('current_workspace', $ws);
    $qr = QrCode::factory()->create(['workspace_id' => $ws->id]);

    Livewire::actingAs($user)->test(DeleteQrCode::class, ['qrUlid' => $qr->ulid])
        ->call('delete')
        ->assertDispatched('qr-deleted')
        ->assertDispatched('toast');

    $this->assertSoftDeleted('qr_codes', ['id' => $qr->id]);
});
