<?php

use App\Domains\Domain\Models\Domain;
use App\Domains\Workspace\Models\Workspace;
use App\Domains\Workspace\Models\WorkspaceMember;
use App\Livewire\Modals\AddDomain;
use App\Livewire\Modals\DeleteDomain;
use App\Livewire\Modals\VerifyDomain;
use App\Models\User;
use Livewire\Livewire;

function makeUserWithWsForDomain(): 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];
}

// AddDomain

it('renders add domain modal', function () {
    [$user, $ws] = makeUserWithWsForDomain();
    app()->instance('current_workspace', $ws);

    Livewire::actingAs($user)->test(AddDomain::class)
        ->assertOk()
        ->assertSee('Domain');
});

it('validates required hostname on add domain', function () {
    [$user, $ws] = makeUserWithWsForDomain();
    app()->instance('current_workspace', $ws);

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

it('adds domain and dispatches event', function () {
    [$user, $ws] = makeUserWithWsForDomain();
    app()->instance('current_workspace', $ws);

    Livewire::actingAs($user)->test(AddDomain::class)
        ->set('hostname', 'links.example.com')
        ->call('save')
        ->assertDispatched('domainAdded')
        ->assertDispatched('toast');

    $this->assertDatabaseHas('domains', [
        'workspace_id' => $ws->id,
        'hostname' => 'links.example.com',
    ]);
});

// VerifyDomain

it('renders verify domain modal', function () {
    [$user, $ws] = makeUserWithWsForDomain();
    app()->instance('current_workspace', $ws);
    $domain = Domain::factory()->create(['workspace_id' => $ws->id]);

    Livewire::actingAs($user)->test(VerifyDomain::class, ['domainId' => $domain->id])
        ->assertOk()
        ->assertSee($domain->hostname);
});

it('shows verification token in verify domain modal', function () {
    [$user, $ws] = makeUserWithWsForDomain();
    app()->instance('current_workspace', $ws);
    $domain = Domain::factory()->create(['workspace_id' => $ws->id]);

    Livewire::actingAs($user)->test(VerifyDomain::class, ['domainId' => $domain->id])
        ->assertSee($domain->verification_token);
});

// DeleteDomain

it('renders delete domain modal', function () {
    [$user, $ws] = makeUserWithWsForDomain();
    app()->instance('current_workspace', $ws);
    $domain = Domain::factory()->create(['workspace_id' => $ws->id]);

    Livewire::actingAs($user)->test(DeleteDomain::class, ['domainId' => $domain->id])
        ->assertOk()
        ->assertSee($domain->hostname);
});

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

    Livewire::actingAs($user)->test(DeleteDomain::class, ['domainId' => $domain->id])
        ->call('delete')
        ->assertDispatched('domainDeleted')
        ->assertDispatched('toast');

    $this->assertDatabaseMissing('domains', ['id' => $domain->id]);
});
