<?php

namespace Tests\Feature\Auth;

use App\Domains\Attachable\Enums\AttachmentType;
use App\Domains\Attachable\Models\Attachment;
use App\Domains\Auth\Models\User;
use App\Domains\Notification\Events\UserRegistered;
use App\Domains\Tenant\Models\Tenant;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Event;
use Tests\TestCase;

class RegisterControllerTest extends TestCase
{
    use RefreshDatabase;

    public function test_it_registers_a_user(): void
    {
        $response = $this->postJson('/api/register', [
            'nombre_apellido' => 'Ada Lovelace',
            'email' => 'ada@example.com',
            'password' => 'Secret!123',
            'password_confirmation' => 'Secret!123',
            'dni' => '12345678A',
            'telefono' => '+541122334455',
        ]);

        $response
            ->assertCreated()
            ->assertJsonPath('message', 'Usuario registrado correctamente.')
            ->assertJsonPath('data.nombre_apellido', 'Ada Lovelace')
            ->assertJsonPath('data.email', 'ada@example.com')
            ->assertJsonPath('data.dni', '12345678A')
            ->assertJsonPath('data.telefono', '+541122334455');

        $this->assertDatabaseHas('users', [
            'nombre_apellido' => 'Ada Lovelace',
            'email' => 'ada@example.com',
            'dni' => '12345678A',
            'telefono' => '+541122334455',
        ]);

        $user = User::query()->where('email', 'ada@example.com')->firstOrFail();

        $this->assertNotSame('Secret!123', $user->password);
    }

    public function test_it_registers_a_user_without_optional_fields(): void
    {
        $response = $this->postJson('/api/register', [
            'nombre_apellido' => 'Alan Turing',
            'email' => 'alan@example.com',
            'password' => 'Secret!123',
            'password_confirmation' => 'Secret!123',
        ]);

        $response
            ->assertCreated()
            ->assertJsonPath('message', 'Usuario registrado correctamente.')
            ->assertJsonPath('data.nombre_apellido', 'Alan Turing')
            ->assertJsonPath('data.email', 'alan@example.com')
            ->assertJsonPath('data.dni', null)
            ->assertJsonPath('data.telefono', null);

        $this->assertDatabaseHas('users', [
            'nombre_apellido' => 'Alan Turing',
            'email' => 'alan@example.com',
            'dni' => null,
            'telefono' => null,
        ]);
    }

    public function test_it_dispatches_the_welcome_notification_with_tenant_context(): void
    {
        Event::fake([UserRegistered::class]);
        $header = Attachment::query()->create([
            'path' => 'test/welcome-header.png',
            'filename' => 'header.png',
            'type' => AttachmentType::Image,
            'mime_type' => 'image/png',
        ]);
        $footer = Attachment::query()->create([
            'path' => 'test/welcome-footer.png',
            'filename' => 'footer.png',
            'type' => AttachmentType::Image,
            'mime_type' => 'image/png',
        ]);
        $tenant = Tenant::query()->create([
            'codigo' => 'welcome-tenant',
            'nombre' => 'Welcome Tenant',
            'dominio' => 'welcome.local',
            'primary_color' => '#000000',
            'secondary_color' => '#000000',
            'danger_color' => '#000000',
            'success_color' => '#000000',
            'header_bg_color' => '#000000',
            'footer_bg_color' => '#000000',
            'header_logo_id' => $header->id,
            'footer_logo_id' => $footer->id,
        ]);

        $this->postJson('/api/register', [
            'tenant_codigo' => $tenant->codigo,
            'nombre_apellido' => 'Grace Hopper',
            'email' => 'grace@example.com',
            'password' => 'Secret!123',
            'password_confirmation' => 'Secret!123',
        ])->assertCreated();

        Event::assertDispatched(
            UserRegistered::class,
            fn (UserRegistered $event): bool => $event->tenantCode === $tenant->codigo
                && $event->user->email === 'grace@example.com',
        );
    }

    public function test_it_validates_required_fields_and_unique_email(): void
    {
        User::factory()->create([
            'nombre_apellido' => 'Existing User',
            'email' => 'existing@example.com',
        ]);

        $response = $this->postJson('/api/register', [
            'nombre_apellido' => '',
            'email' => 'existing@example.com',
            'password' => 'secret123',
            'password_confirmation' => 'different-secret',
        ]);

        $response->assertUnprocessable()->assertJsonValidationErrors([
            'nombre_apellido',
            'email',
            'password',
        ]);
    }
}
