<?php

use App\Enums\ResponseStatus;
use App\Models\Website;

use function Pest\Laravel\assertDatabaseHas;
use function Pest\Laravel\postJson;

beforeEach(function (): void {
    $this->website = Website::factory()->create([
        'domain' => 'example.com',
        'is_active' => true,
    ]);

    $this->token = $this->website->createToken('test')->plainTextToken;

    $this->headers = [
        'Authorization' => "Bearer {$this->token}",
        'Origin' => 'https://example.com',
    ];
});

test('requires authentication', function (): void {
    postJson('/api/contact', [
        'registration_number' => 'AB12CDE',
        'contact_data' => ['name' => 'John Doe'],
    ])->assertUnauthorized();
});

test('requires registration number', function (): void {
    postJson('/api/contact', [
        'contact_data' => ['name' => 'John Doe'],
    ], $this->headers)
        ->assertUnprocessable()
        ->assertJsonValidationErrors(['registration_number']);
});

test('rejects invalid registration number format', function (): void {
    postJson('/api/contact', [
        'registration_number' => 'ovidiu',
        'contact_data' => ['name' => 'John Doe'],
    ], $this->headers)
        ->assertUnprocessable()
        ->assertJsonValidationErrors(['registration_number']);
});

test('requires contact data', function (): void {
    postJson('/api/contact', [
        'registration_number' => 'AB12CDE',
    ], $this->headers)
        ->assertUnprocessable()
        ->assertJsonValidationErrors(['contact_data']);
});

test('stores contact submission and returns success', function (): void {
    postJson('/api/contact', [
        'registration_number' => 'AB12CDE',
        'contact_data' => [
            'name' => 'John Doe',
            'email' => 'john@example.com',
            'phone' => '07700900000',
            'address' => '1 High Street',
            'message' => 'Please call me back.',
        ],
    ], $this->headers)
        ->assertSuccessful()
        ->assertJson(['success' => true]);

    assertDatabaseHas('api_requests', [
        'website_id' => $this->website->id,
        'registration_number' => 'AB12CDE',
        'response_status' => ResponseStatus::ContactSubmitted->value,
    ]);
});

test('requires at least email or phone in contact data', function (): void {
    postJson('/api/contact', [
        'registration_number' => 'AB12CDE',
        'contact_data' => ['name' => 'John Doe'],
    ], $this->headers)
        ->assertUnprocessable()
        ->assertJsonValidationErrors(['contact_data.email', 'contact_data.phone']);
});

test('accepts contact data with email only', function (): void {
    postJson('/api/contact', [
        'registration_number' => 'AB12CDE',
        'contact_data' => ['email' => 'john@example.com'],
    ], $this->headers)->assertSuccessful();
});

test('accepts contact data with phone only', function (): void {
    postJson('/api/contact', [
        'registration_number' => 'AB12CDE',
        'contact_data' => ['phone' => '07700900000'],
    ], $this->headers)->assertSuccessful();
});

test('normalises registration number before storing', function (): void {
    postJson('/api/contact', [
        'registration_number' => 'ab12 cde',
        'contact_data' => ['email' => 'john@example.com', 'phone' => '07700900000'],
    ], $this->headers)->assertSuccessful();

    assertDatabaseHas('api_requests', [
        'registration_number' => 'AB12CDE',
        'response_status' => ResponseStatus::ContactSubmitted->value,
    ]);
});

test('inactive website cannot submit contact', function (): void {
    $this->website->update(['is_active' => false]);

    postJson('/api/contact', [
        'registration_number' => 'AB12CDE',
        'contact_data' => ['name' => 'John Doe'],
    ], $this->headers)->assertForbidden();
});

test('rejects request from wrong origin', function (): void {
    postJson('/api/contact', [
        'registration_number' => 'AB12CDE',
        'contact_data' => ['name' => 'John Doe'],
    ], [
        'Authorization' => "Bearer {$this->token}",
        'Origin' => 'https://malicious-site.com',
    ])->assertForbidden();
});
