<?php

use App\Enums\Gender;
use App\Livewire\Studio\Loyalty\Customer;
use App\Models\Customer as CustomerModel;
use Livewire\Livewire;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

beforeEach(function () {
    $this->setupUser();

    $role = Role::firstOrCreate(['name' => 'Owner']);
    Permission::firstOrCreate(['name' => 'view customer']);
    Permission::firstOrCreate(['name' => 'create customer']);
    Permission::firstOrCreate(['name' => 'update customer']);
    Permission::firstOrCreate(['name' => 'delete customer']);
    $role->givePermissionTo(['view customer', 'create customer', 'update customer', 'delete customer']);
    $this->user->assignRole($role);
});

it('renders the customer page correctly', function () {
    $this->actingAs($this->user)
        ->get(route('studio.loyalty.customer.index'))
        ->assertOk()
        ->assertSeeLivewire(Customer::class);
});

it('can open create modal', function () {
    Livewire::actingAs($this->user)
        ->test(Customer::class)
        ->call('openModal', 'create', 'Tambah Customer')
        ->assertSet('method', 'create')
        ->assertSet('modalTitle', 'Tambah Customer');
});

it('shows validation errors on create', function () {
    Livewire::actingAs($this->user)
        ->test(Customer::class)
        ->call('create')
        ->assertHasErrors([
            'form.name' => 'required',
            'form.gender' => 'required',
        ]);
});

it('can store a new customer', function () {
    Livewire::actingAs($this->user)
        ->test(Customer::class)
        ->set('form.name', 'John Doe')
        ->set('form.phone_number', '0812 3456 7890')
        ->set('form.gender', Gender::MALE->value)
        ->call('create')
        ->assertHasNoErrors()
        ->assertDispatched('refreshDatatable');

    $this->assertDatabaseHas('customers', [
        'name' => 'John Doe',
        'phone_number' => '0812 3456 7890',
        'gender' => Gender::MALE->value,
    ]);
});

it('can open edit modal and load data', function () {
    $customer = CustomerModel::factory()->create(['name' => 'Old Name']);

    Livewire::actingAs($this->user)
        ->test(Customer::class)
        ->call('openModal', 'update', 'Ubah Customer', $customer->hash_id)
        ->set('form.customer', $customer)
        ->set('form.name', 'Old Name')
        ->assertSet('method', 'update')
        ->assertSet('form.name', 'Old Name')
        ->assertSet('form.customer.id', $customer->id);
});

it('can update a customer', function () {
    $customer = CustomerModel::factory()->create(['name' => 'Old Name']);

    Livewire::actingAs($this->user)
        ->test(Customer::class)
        ->call('openModal', 'update', 'Ubah Customer', $customer->hash_id)
        // Manually set because of potential HashId resolution issues in tests
        ->set('form.customer', $customer)
        ->set('form.name', 'Updated Name')
        ->set('form.gender', Gender::FEMALE->value)
        ->call('update')
        ->assertHasNoErrors()
        ->assertDispatched('refreshDatatable');

    $this->assertDatabaseHas('customers', [
        'id' => $customer->id,
        'name' => 'Updated Name',
        'gender' => Gender::FEMALE->value,
    ]);
});

it('can delete a customer', function () {
    $customer = CustomerModel::factory()->create();

    Livewire::actingAs($this->user)
        ->test(Customer::class)
        ->call('delete', $customer->id)
        ->assertHasNoErrors()
        ->assertDispatched('refreshDatatable');

    $this->assertSoftDeleted('customers', ['id' => $customer->id]);
});

it('cannot access customer page without permission', function () {
    $this->user->roles()->detach();
    $this->user->permissions()->detach();

    $this->actingAs($this->user)
        ->get(route('studio.loyalty.customer.index'))
        ->assertForbidden();
});
