<?php

use App\Mail\WelcomeEmail;
use App\Models\User;
use App\Notifications\WelcomeAccountNotification;
use Illuminate\Support\Facades\Notification;
use Livewire\Volt\Volt;

beforeEach(function () {
    $this->admin = User::factory()->admin()->create();
});

// ===========================================
// Individual Client Welcome Email Tests
// ===========================================

test('welcome email is queued when creating individual client', function () {
    Notification::fake();

    $this->actingAs($this->admin);

    Volt::test('admin.clients.individual.create')
        ->set('full_name', 'Test Client')
        ->set('email', 'testclient@example.com')
        ->set('national_id', '123456789')
        ->set('phone', '+970599123456')
        ->set('password', 'password123')
        ->set('preferred_language', 'ar')
        ->call('create')
        ->assertHasNoErrors();

    $client = User::where('email', 'testclient@example.com')->first();

    Notification::assertSentTo(
        $client,
        WelcomeAccountNotification::class,
        function ($notification) {
            return $notification->password === 'password123';
        }
    );
});

test('welcome email contains correct password for individual client', function () {
    Notification::fake();

    $this->actingAs($this->admin);

    Volt::test('admin.clients.individual.create')
        ->set('full_name', 'Test Client')
        ->set('email', 'testclient@example.com')
        ->set('national_id', '123456789')
        ->set('phone', '+970599123456')
        ->set('password', 'securePassword456')
        ->set('preferred_language', 'en')
        ->call('create')
        ->assertHasNoErrors();

    $client = User::where('email', 'testclient@example.com')->first();

    Notification::assertSentTo(
        $client,
        WelcomeAccountNotification::class,
        function ($notification) {
            return $notification->password === 'securePassword456';
        }
    );
});

// ===========================================
// Company Client Welcome Email Tests
// ===========================================

test('welcome email is queued when creating company client', function () {
    Notification::fake();

    $this->actingAs($this->admin);

    Volt::test('admin.clients.company.create')
        ->set('company_name', 'Test Company Ltd')
        ->set('company_cert_number', 'COMP123456')
        ->set('contact_person_name', 'John Doe')
        ->set('contact_person_id', '987654321')
        ->set('email', 'company@example.com')
        ->set('phone', '+970599123456')
        ->set('password', 'companyPass123')
        ->set('preferred_language', 'ar')
        ->call('create')
        ->assertHasNoErrors();

    $client = User::where('email', 'company@example.com')->first();

    Notification::assertSentTo(
        $client,
        WelcomeAccountNotification::class,
        function ($notification) {
            return $notification->password === 'companyPass123';
        }
    );
});

test('welcome email contains correct password for company client', function () {
    Notification::fake();

    $this->actingAs($this->admin);

    Volt::test('admin.clients.company.create')
        ->set('company_name', 'Another Company')
        ->set('company_cert_number', 'COMP789012')
        ->set('contact_person_name', 'Jane Smith')
        ->set('contact_person_id', '111222333')
        ->set('email', 'another@example.com')
        ->set('phone', '+970599999999')
        ->set('password', 'anotherSecure789')
        ->set('preferred_language', 'en')
        ->call('create')
        ->assertHasNoErrors();

    $client = User::where('email', 'another@example.com')->first();

    Notification::assertSentTo(
        $client,
        WelcomeAccountNotification::class,
        function ($notification) {
            return $notification->password === 'anotherSecure789';
        }
    );
});

// ===========================================
// Language Support Tests
// ===========================================

test('welcome email uses arabic subject for arabic preference', function () {
    $user = User::factory()->individual()->create(['preferred_language' => 'ar']);

    $mailable = new WelcomeEmail($user, 'password123');
    $envelope = $mailable->envelope();

    expect($envelope->subject)->toBe('مرحباً بك في مكتب ليبرا للمحاماة');
});

test('welcome email uses english subject for english preference', function () {
    $user = User::factory()->individual()->create(['preferred_language' => 'en']);

    $mailable = new WelcomeEmail($user, 'password123');
    $envelope = $mailable->envelope();

    expect($envelope->subject)->toBe('Welcome to Libra Law Firm');
});

test('welcome email defaults to arabic when preferred_language is null', function () {
    $user = User::factory()->individual()->create(['preferred_language' => 'ar']);
    // Simulate a scenario where preferred_language could be null in memory
    $user->preferred_language = null;

    $mailable = new WelcomeEmail($user, 'password123');
    $envelope = $mailable->envelope();

    expect($envelope->subject)->toBe('مرحباً بك في مكتب ليبرا للمحاماة');
});

test('welcome email uses correct arabic template', function () {
    $user = User::factory()->individual()->create(['preferred_language' => 'ar']);

    $mailable = new WelcomeEmail($user, 'password123');
    $content = $mailable->content();

    expect($content->markdown)->toBe('emails.welcome.ar');
});

test('welcome email uses correct english template', function () {
    $user = User::factory()->individual()->create(['preferred_language' => 'en']);

    $mailable = new WelcomeEmail($user, 'password123');
    $content = $mailable->content();

    expect($content->markdown)->toBe('emails.welcome.en');
});

// ===========================================
// Email Content Tests
// ===========================================

test('welcome email passes correct data to view', function () {
    $user = User::factory()->individual()->create([
        'full_name' => 'Test User',
        'email' => 'test@example.com',
        'preferred_language' => 'en',
    ]);

    $mailable = new WelcomeEmail($user, 'testPassword123');
    $content = $mailable->content();

    expect($content->with['user']->id)->toBe($user->id);
    expect($content->with['password'])->toBe('testPassword123');
    expect($content->with['loginUrl'])->toBe(route('login'));
});

test('welcome email passes company name for company clients', function () {
    $user = User::factory()->company()->create([
        'company_name' => 'Test Company Ltd',
        'preferred_language' => 'ar',
    ]);

    $mailable = new WelcomeEmail($user, 'companyPass');
    $content = $mailable->content();

    expect($content->with['user']->company_name)->toBe('Test Company Ltd');
    expect($content->markdown)->toBe('emails.welcome.ar');
});

test('arabic template renders correctly', function () {
    $user = User::factory()->individual()->create([
        'full_name' => 'محمد أحمد',
        'email' => 'mohammad@example.com',
        'preferred_language' => 'ar',
    ]);

    $mailable = new WelcomeEmail($user, 'password123');

    $mailable->assertSeeInHtml('مرحباً بك في مكتب ليبرا للمحاماة');
    $mailable->assertSeeInHtml('محمد أحمد');
    $mailable->assertSeeInHtml('mohammad@example.com');
    $mailable->assertSeeInHtml('password123');
    $mailable->assertSeeInHtml('تسجيل الدخول');
});

test('english template renders correctly', function () {
    $user = User::factory()->individual()->create([
        'full_name' => 'John Doe',
        'email' => 'john@example.com',
        'preferred_language' => 'en',
    ]);

    $mailable = new WelcomeEmail($user, 'password456');

    $mailable->assertSeeInHtml('Welcome to Libra Law Firm');
    $mailable->assertSeeInHtml('John Doe');
    $mailable->assertSeeInHtml('john@example.com');
    $mailable->assertSeeInHtml('password456');
    $mailable->assertSeeInHtml('Login Now');
});

test('welcome email contains login url', function () {
    $user = User::factory()->individual()->create(['preferred_language' => 'en']);

    $mailable = new WelcomeEmail($user, 'password123');

    $mailable->assertSeeInHtml(route('login'));
});

// ===========================================
// Notification Queue Tests
// ===========================================

test('welcome notification implements should queue interface', function () {
    $notification = new WelcomeAccountNotification('password');

    expect($notification)->toBeInstanceOf(\Illuminate\Contracts\Queue\ShouldQueue::class);
});

test('welcome notification uses queueable trait', function () {
    $traits = class_uses(WelcomeAccountNotification::class);

    expect($traits)->toContain(\Illuminate\Bus\Queueable::class);
});

test('welcome email mailable implements should queue interface', function () {
    $user = User::factory()->individual()->create();
    $mailable = new WelcomeEmail($user, 'password');

    expect($mailable)->toBeInstanceOf(\Illuminate\Contracts\Queue\ShouldQueue::class);
});

test('welcome email mailable uses queueable trait', function () {
    $traits = class_uses(WelcomeEmail::class);

    expect($traits)->toContain(\Illuminate\Bus\Queueable::class);
});

test('notification returns welcome email mailable', function () {
    $user = User::factory()->individual()->create();
    $notification = new WelcomeAccountNotification('password123');

    $mailable = $notification->toMail($user);

    expect($mailable)->toBeInstanceOf(WelcomeEmail::class);
});

// ===========================================
// Admin Exclusion Tests
// ===========================================

test('no welcome email is sent when admin creates another admin via factory', function () {
    Notification::fake();

    // Admin accounts are not created through the client forms
    // They are created differently (not through the admin client creation flow)
    // This test verifies that the admin factory itself doesn't trigger welcome emails
    $admin = User::factory()->admin()->create();

    // Factory creation doesn't trigger notifications automatically
    Notification::assertNothingSent();
});

// ===========================================
// User Creation Success Tests
// ===========================================

test('user creation succeeds even if notification would fail', function () {
    // Use fake to prevent actual sending, which simulates the queued behavior
    Notification::fake();

    $this->actingAs($this->admin);

    Volt::test('admin.clients.individual.create')
        ->set('full_name', 'Test Client')
        ->set('email', 'testclient@example.com')
        ->set('national_id', '123456789')
        ->set('phone', '+970599123456')
        ->set('password', 'password123')
        ->set('preferred_language', 'ar')
        ->call('create')
        ->assertHasNoErrors()
        ->assertRedirect(route('admin.clients.individual.index'));

    // User was created successfully
    expect(User::where('email', 'testclient@example.com')->exists())->toBeTrue();
});
