<?php

declare(strict_types=1);

use App\Models\AuditLog;
use App\Models\User;
use Database\Seeders\RoleAndPermissionSeeder;

beforeEach(function (): void {
    $this->seed(RoleAndPermissionSeeder::class);
    $this->adminUrl = 'http://'.config('app.domains.admin');
    $this->admin = User::factory()->admin()->create();
    $this->customer = User::factory()->customer()->create([
        'name' => 'Original Name',
        'email' => 'original@test.com',
    ]);
});

test('admin can view customer edit page', function (): void {
    $this->actingAs($this->admin)
        ->get($this->adminUrl.'/customers/'.$this->customer->id.'/edit')
        ->assertOk()
        ->assertInertia(fn ($page) => $page
            ->component('Admin/Customers/Edit')
            ->has('customer')
        );
});

test('admin can update customer details', function (): void {
    $this->actingAs($this->admin)
        ->put($this->adminUrl.'/customers/'.$this->customer->id, [
            'name' => 'Updated Name',
            'email' => 'updated@test.com',
            'phone' => '555-1234',
            'company' => 'Test Corp',
            'status' => 'active',
            'admin_notes' => 'Test note from admin',
        ])
        ->assertRedirect();

    $this->customer->refresh();
    expect($this->customer->name)->toBe('Updated Name')
        ->and($this->customer->email)->toBe('updated@test.com')
        ->and($this->customer->phone)->toBe('555-1234')
        ->and($this->customer->company)->toBe('Test Corp')
        ->and($this->customer->admin_notes)->toBe('Test note from admin');
});

test('admin can update customer status', function (): void {
    $this->actingAs($this->admin)
        ->put($this->adminUrl.'/customers/'.$this->customer->id, [
            'name' => $this->customer->name,
            'email' => $this->customer->email,
            'status' => 'suspended',
        ])
        ->assertRedirect();

    $this->customer->refresh();
    expect($this->customer->status)->toBe('suspended');

    // Check audit log for status change
    expect(AuditLog::where('action', 'customer_status_changed')->count())->toBeGreaterThan(0);
});

test('customer edit requires valid email', function (): void {
    $this->actingAs($this->admin)
        ->put($this->adminUrl.'/customers/'.$this->customer->id, [
            'name' => 'Test',
            'email' => 'not-an-email',
            'status' => 'active',
        ])
        ->assertSessionHasErrors('email');
});

test('customer edit requires unique email', function (): void {
    User::factory()->customer()->create(['email' => 'taken@test.com']);

    $this->actingAs($this->admin)
        ->put($this->adminUrl.'/customers/'.$this->customer->id, [
            'name' => 'Test',
            'email' => 'taken@test.com',
            'status' => 'active',
        ])
        ->assertSessionHasErrors('email');
});

test('customer can keep their own email on update', function (): void {
    $this->actingAs($this->admin)
        ->put($this->adminUrl.'/customers/'.$this->customer->id, [
            'name' => 'Updated',
            'email' => $this->customer->email,
            'status' => 'active',
        ])
        ->assertRedirect();
});

test('admin notes can be saved and cleared', function (): void {
    // Save notes
    $this->actingAs($this->admin)
        ->put($this->adminUrl.'/customers/'.$this->customer->id, [
            'name' => $this->customer->name,
            'email' => $this->customer->email,
            'status' => 'active',
            'admin_notes' => 'Important customer note',
        ])
        ->assertRedirect();

    $this->customer->refresh();
    expect($this->customer->admin_notes)->toBe('Important customer note');

    // Clear notes
    $this->actingAs($this->admin)
        ->put($this->adminUrl.'/customers/'.$this->customer->id, [
            'name' => $this->customer->name,
            'email' => $this->customer->email,
            'status' => 'active',
            'admin_notes' => '',
        ])
        ->assertRedirect();

    $this->customer->refresh();
    expect($this->customer->admin_notes)->toBeNull();
});

test('non-admin cannot access customer edit', function (): void {
    $regularUser = User::factory()->customer()->create();

    $this->actingAs($regularUser)
        ->get($this->adminUrl.'/customers/'.$this->customer->id.'/edit')
        ->assertForbidden();
});
