<?php

use App\Enums\UserType;
use App\Models\AdminLog;
use App\Models\User;
use App\Notifications\AccountTypeChangedNotification;
use Illuminate\Support\Facades\Notification;
use Livewire\Volt\Volt;

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

// ===========================================
// Individual to Company Conversion Tests
// ===========================================

test('admin can access individual client show page', function () {
    $individual = User::factory()->individual()->create();

    $this->actingAs($this->admin)
        ->get(route('admin.clients.individual.show', $individual))
        ->assertOk()
        ->assertSee(__('clients.convert_to_company'));
});

test('admin can convert individual to company with all valid data', function () {
    $individual = User::factory()->individual()->create([
        'full_name' => 'John Doe',
        'national_id' => '123456789',
        'email' => 'john@example.com',
    ]);

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

    Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
        ->assertSet('contact_person_name', 'John Doe')
        ->assertSet('contact_person_id', '123456789')
        ->set('company_name', 'Doe Corp')
        ->set('company_cert_number', 'CR-12345')
        ->call('convertToCompany')
        ->assertHasNoErrors()
        ->assertRedirect(route('admin.clients.company.show', $individual));

    $individual->refresh();
    expect($individual->user_type)->toBe(UserType::Company);
    expect($individual->company_name)->toBe('Doe Corp');
    expect($individual->company_cert_number)->toBe('CR-12345');
    expect($individual->contact_person_name)->toBe('John Doe');
    expect($individual->contact_person_id)->toBe('123456789');
    expect($individual->national_id)->toBeNull();
    expect($individual->email)->toBe('john@example.com');
});

test('form pre-fills contact_person_name with user current name', function () {
    $individual = User::factory()->individual()->create([
        'full_name' => 'Jane Smith',
    ]);

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

    Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
        ->assertSet('contact_person_name', 'Jane Smith');
});

test('form pre-fills contact_person_id with user national_id', function () {
    $individual = User::factory()->individual()->create([
        'national_id' => '987654321',
    ]);

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

    Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
        ->assertSet('contact_person_id', '987654321');
});

test('cannot convert to company without required company_name field', function () {
    $individual = User::factory()->individual()->create();

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

    Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
        ->set('company_name', '')
        ->set('company_cert_number', 'CR-12345')
        ->call('convertToCompany')
        ->assertHasErrors(['company_name' => 'required']);
});

test('cannot convert to company without required company_cert_number field', function () {
    $individual = User::factory()->individual()->create();

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

    Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
        ->set('company_name', 'Test Corp')
        ->set('company_cert_number', '')
        ->call('convertToCompany')
        ->assertHasErrors(['company_cert_number' => 'required']);
});

test('cannot convert with duplicate company_cert_number', function () {
    User::factory()->company()->create([
        'company_cert_number' => 'CR-EXISTING',
    ]);
    $individual = User::factory()->individual()->create();

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

    Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
        ->set('company_name', 'New Corp')
        ->set('company_cert_number', 'CR-EXISTING')
        ->set('contact_person_name', 'Test Person')
        ->set('contact_person_id', '111222333')
        ->call('convertToCompany')
        ->assertHasErrors(['company_cert_number']);
});

test('converted individual has user_type set to company', function () {
    $individual = User::factory()->individual()->create();

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

    Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
        ->set('company_name', 'Test Corp')
        ->set('company_cert_number', 'CR-TEST')
        ->call('convertToCompany')
        ->assertHasNoErrors();

    $individual->refresh();
    expect($individual->user_type)->toBe(UserType::Company);
});

test('original email phone password preserved after conversion to company', function () {
    $individual = User::factory()->individual()->create([
        'email' => 'original@example.com',
        'phone' => '+970599000000',
    ]);
    $originalPassword = $individual->password;

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

    Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
        ->set('company_name', 'Test Corp')
        ->set('company_cert_number', 'CR-TEST')
        ->call('convertToCompany')
        ->assertHasNoErrors();

    $individual->refresh();
    expect($individual->email)->toBe('original@example.com');
    expect($individual->phone)->toBe('+970599000000');
    expect($individual->password)->toBe($originalPassword);
});

test('admin log entry created on individual to company conversion', function () {
    $individual = User::factory()->individual()->create();

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

    Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
        ->set('company_name', 'Test Corp')
        ->set('company_cert_number', 'CR-TEST')
        ->call('convertToCompany')
        ->assertHasNoErrors();

    expect(AdminLog::where('action', 'convert_account')
        ->where('target_type', 'user')
        ->where('target_id', $individual->id)
        ->where('admin_id', $this->admin->id)
        ->exists())->toBeTrue();

    $log = AdminLog::where('action', 'convert_account')->first();
    expect($log->old_values['user_type'])->toBe(UserType::Individual->value);
    expect($log->new_values['user_type'])->toBe(UserType::Company->value);
});

test('email notification sent after conversion to company', function () {
    $individual = User::factory()->individual()->create();

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

    Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
        ->set('company_name', 'Test Corp')
        ->set('company_cert_number', 'CR-TEST')
        ->call('convertToCompany')
        ->assertHasNoErrors();

    Notification::assertSentTo($individual, AccountTypeChangedNotification::class);
});

// ===========================================
// Company to Individual Conversion Tests
// ===========================================

test('admin can access company client show page', function () {
    $company = User::factory()->company()->create();

    $this->actingAs($this->admin)
        ->get(route('admin.clients.company.show', $company))
        ->assertOk()
        ->assertSee(__('clients.convert_to_individual'));
});

test('admin can convert company to individual with all valid data', function () {
    $company = User::factory()->company()->create([
        'company_name' => 'Acme Corp',
        'contact_person_name' => 'Jane Smith',
        'contact_person_id' => '987654321',
        'email' => 'contact@acme.com',
    ]);

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

    Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
        ->assertSet('full_name', 'Jane Smith')
        ->assertSet('national_id', '987654321')
        ->call('convertToIndividual')
        ->assertHasNoErrors()
        ->assertRedirect(route('admin.clients.individual.show', $company));

    $company->refresh();
    expect($company->user_type)->toBe(UserType::Individual);
    expect($company->full_name)->toBe('Jane Smith');
    expect($company->national_id)->toBe('987654321');
    expect($company->company_name)->toBeNull();
    expect($company->company_cert_number)->toBeNull();
    expect($company->contact_person_name)->toBeNull();
    expect($company->contact_person_id)->toBeNull();
    expect($company->email)->toBe('contact@acme.com');
});

test('form pre-fills name with contact_person_name or company_name', function () {
    $company = User::factory()->company()->create([
        'contact_person_name' => 'John Contact',
    ]);

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

    Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
        ->assertSet('full_name', 'John Contact');
});

test('form pre-fills national_id with contact_person_id if available', function () {
    $company = User::factory()->company()->create([
        'contact_person_id' => '555666777',
    ]);

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

    Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
        ->assertSet('national_id', '555666777');
});

test('cannot convert to individual without required name field', function () {
    $company = User::factory()->company()->create();

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

    Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
        ->set('full_name', '')
        ->set('national_id', '123456789')
        ->call('convertToIndividual')
        ->assertHasErrors(['full_name' => 'required']);
});

test('cannot convert to individual without required national_id field', function () {
    $company = User::factory()->company()->create();

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

    Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
        ->set('full_name', 'Test User')
        ->set('national_id', '')
        ->call('convertToIndividual')
        ->assertHasErrors(['national_id' => 'required']);
});

test('cannot convert with duplicate national_id', function () {
    User::factory()->individual()->create([
        'national_id' => 'EXISTING-ID',
    ]);
    $company = User::factory()->company()->create();

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

    Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
        ->set('full_name', 'Test User')
        ->set('national_id', 'EXISTING-ID')
        ->call('convertToIndividual')
        ->assertHasErrors(['national_id']);
});

test('converted company has user_type set to individual', function () {
    $company = User::factory()->company()->create();

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

    Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
        ->set('full_name', 'Test User')
        ->set('national_id', 'NEW-ID-123')
        ->call('convertToIndividual')
        ->assertHasNoErrors();

    $company->refresh();
    expect($company->user_type)->toBe(UserType::Individual);
});

test('company fields nulled after conversion to individual', function () {
    $company = User::factory()->company()->create([
        'company_name' => 'Test Corp',
        'company_cert_number' => 'CR-123',
        'contact_person_name' => 'Contact Person',
        'contact_person_id' => '123123123',
    ]);

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

    Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
        ->set('full_name', 'Test User')
        ->set('national_id', 'NEW-ID-456')
        ->call('convertToIndividual')
        ->assertHasNoErrors();

    $company->refresh();
    expect($company->company_name)->toBeNull();
    expect($company->company_cert_number)->toBeNull();
    expect($company->contact_person_name)->toBeNull();
    expect($company->contact_person_id)->toBeNull();
});

test('original email phone password preserved after conversion to individual', function () {
    $company = User::factory()->company()->create([
        'email' => 'company@example.com',
        'phone' => '+970599111111',
    ]);
    $originalPassword = $company->password;

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

    Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
        ->set('full_name', 'Test User')
        ->set('national_id', 'NEW-ID-789')
        ->call('convertToIndividual')
        ->assertHasNoErrors();

    $company->refresh();
    expect($company->email)->toBe('company@example.com');
    expect($company->phone)->toBe('+970599111111');
    expect($company->password)->toBe($originalPassword);
});

test('admin log entry created on company to individual conversion', function () {
    $company = User::factory()->company()->create();

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

    Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
        ->set('full_name', 'Test User')
        ->set('national_id', 'NEW-ID-999')
        ->call('convertToIndividual')
        ->assertHasNoErrors();

    expect(AdminLog::where('action', 'convert_account')
        ->where('target_type', 'user')
        ->where('target_id', $company->id)
        ->where('admin_id', $this->admin->id)
        ->exists())->toBeTrue();

    $log = AdminLog::where('action', 'convert_account')->first();
    expect($log->old_values['user_type'])->toBe(UserType::Company->value);
    expect($log->new_values['user_type'])->toBe(UserType::Individual->value);
});

test('email notification sent after conversion to individual', function () {
    $company = User::factory()->company()->create();

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

    Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
        ->set('full_name', 'Test User')
        ->set('national_id', 'NEW-ID-000')
        ->call('convertToIndividual')
        ->assertHasNoErrors();

    Notification::assertSentTo($company, AccountTypeChangedNotification::class);
});

// ===========================================
// Confirmation Dialog Tests
// ===========================================

test('conversion shows confirmation step before executing', function () {
    $individual = User::factory()->individual()->create();

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

    Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
        ->set('company_name', 'Test Corp')
        ->set('company_cert_number', 'CR-CONFIRM')
        ->call('showConfirmationDialog')
        ->assertSet('showConfirmation', true)
        ->assertHasNoErrors();
});

test('can cancel confirmation and go back', function () {
    $individual = User::factory()->individual()->create();

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

    Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
        ->set('company_name', 'Test Corp')
        ->set('company_cert_number', 'CR-CANCEL')
        ->call('showConfirmationDialog')
        ->assertSet('showConfirmation', true)
        ->call('cancelConfirmation')
        ->assertSet('showConfirmation', false);
});
