<?php

use App\Models\User;

beforeEach(function () {
    $this->user = User::factory()->create([
        'first_name' => 'John',
        'last_name' => 'Doe',
        'phone_number' => 61929248,
        'options' => ['address' => '123 Main St'],
        'password' => 'password',
    ]);
});

test('unauthenticated user cannot access profile', function () {
    $response = $this->withHeaders(['Api-Token' => config('ecommerce.api.token')])
        ->getJson('/api/v1/profile');

    $response->assertStatus(401);
});

test('authenticated user can view profile', function () {
    $response = $this->actingAs($this->user, 'sanctum')
        ->withHeaders(['Api-Token' => config('ecommerce.api.token')])
        ->getJson('/api/v1/profile');

    $response->assertStatus(200)
        ->assertJson([
            'data' => [
                'first_name' => 'John',
                'last_name' => 'Doe',
                'phone_number' => 61929248,
                'address' => '123 Main St',
            ],
        ]);
});

test('unauthenticated user cannot update profile', function () {
    $response = $this->withHeaders(['Api-Token' => config('ecommerce.api.token')])
        ->postJson('/api/v1/profile', [
            'name' => 'Jane',
            'phone_number' => 61929248,
            'address' => '456 Another St',
        ]);

    $response->assertStatus(401);
});

test('authenticated user can update profile', function () {
    $response = $this->actingAs($this->user, 'sanctum')
        ->withHeaders(['Api-Token' => config('ecommerce.api.token')])
        ->postJson('/api/v1/profile', [
            'name' => 'Jane',
            'phone_number' => 61929248,
            'address' => '456 Another St',
        ]);

    $response->assertStatus(200);

    $this->assertDatabaseHas('users', [
        'id' => $this->user->id,
        'first_name' => 'Jane',
        'phone_number' => 61929248,
    ]);

    $this->user->refresh();
    expect($this->user->options['address'])->toBe('456 Another St');
});

test('profile update validation fails with invalid data', function () {
    $response = $this->actingAs($this->user, 'sanctum')
        ->withHeaders(['Api-Token' => config('ecommerce.api.token')])
        ->postJson('/api/v1/profile', [
            'name' => '', // Required
            'phone_number' => 'invalid', // Integer required
            'address' => '', // Required
        ]);

    $response->assertStatus(422)
        ->assertJsonValidationErrors(['name', 'phone_number', 'address']);
});

test('profile update validation fails with invalid phone number range', function () {
    $response = $this->actingAs($this->user, 'sanctum')
        ->withHeaders(['Api-Token' => config('ecommerce.api.token')])
        ->postJson('/api/v1/profile', [
            'name' => 'Jane',
            'phone_number' => 12345, // Invalid range
            'address' => '456 Another St',
        ]);

    $response->assertStatus(422)
        ->assertJsonValidationErrors(['phone_number']);
});

test('profile update fails if phone number is already taken by another user', function () {
    User::factory()->create([
        'phone_number' => 61929248,
        'password' => 'password',
    ]);

    $response = $this->actingAs($this->user, 'sanctum')
        ->withHeaders(['Api-Token' => config('ecommerce.api.token')])
        ->postJson('/api/v1/profile', [
            'name' => 'Jane',
            'phone_number' => 61929248, // Taken
            'address' => '456 Another St',
        ]);

    $response->assertStatus(422)
        ->assertJsonValidationErrors(['phone_number']);
});

test('profile update succeeds if phone number is unchanged', function () {
    $response = $this->actingAs($this->user, 'sanctum')
        ->withHeaders(['Api-Token' => config('ecommerce.api.token')])
        ->postJson('/api/v1/profile', [
            'name' => 'Jane',
            'phone_number' => $this->user->phone_number, // Same number
            'address' => 'New Address',
        ]);

    $response->assertStatus(200);

    $this->user->refresh();
    expect($this->user->first_name)->toBe('Jane');
    expect($this->user->options['address'])->toBe('New Address');
});
