<?php

use App\Enums\Gender;
use App\Enums\UserStatus;
use App\Livewire\Studio\Master\User\Create;
use App\Models\Outlet;
use App\Models\User;
use Carbon\Carbon;
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' => 'create user']);
    $role->givePermissionTo('create user');
    $this->user->assignRole($role);
});

it('renders the create user page correctly', function () {
    $this->actingAs($this->user)
        ->get(route('studio.master.user.create'))
        ->assertOk()
        ->assertSeeLivewire(Create::class);
});

it('validates required fields', function () {
    Livewire::actingAs($this->user)
        ->test(Create::class)
        ->call('save')
        ->assertHasErrors([
            'form.full_name' => 'required',
            'form.username' => 'required',
            'form.email' => 'required',
            'form.phone_number' => 'required',
            'form.base_salary' => 'required',
            'form.birthdate' => 'required',
            'form.hire_date' => 'required',
            'form.gender' => 'required',
            'form.outlet_ids' => 'required',
            'form.role_ids' => 'required',
        ]);
});

it('validates username minimum length', function () {
    Livewire::actingAs($this->user)
        ->test(Create::class)
        ->set('form.username', 'abc')
        ->call('save')
        ->assertHasErrors(['form.username' => 'min']);
});

it('validates birthdate must be at least 18 years ago', function () {
    Livewire::actingAs($this->user)
        ->test(Create::class)
        ->set('form.birthdate', Carbon::now()->subYears(17)->format('Y-m-d'))
        ->call('save')
        ->assertHasErrors(['form.birthdate' => 'before']);
});

it('can store a new user/employee', function () {
    $outlet = Outlet::factory()->create();
    $role = Role::firstOrCreate(['name' => 'Admin']);

    Livewire::actingAs($this->user)
        ->test(Create::class)
        ->set('form.full_name', 'Pegawai Baru')
        ->set('form.username', 'pegawaibaru')
        ->set('form.email', 'pegawai@example.com')
        ->set('form.phone_number', '0812 3456 7890')
        ->set('form.base_salary', '5.000.000')
        ->set('form.birthdate', '2000-01-01')
        ->set('form.hire_date', '2024-01-01')
        ->set('form.gender', Gender::MALE->value)
        ->set('form.status', UserStatus::ACTIVE->value)
        ->set('form.outlet_ids', [$outlet->id])
        ->set('form.role_ids', [$role->id])
        ->call('save')
        ->assertHasNoErrors()
        ->assertRedirect(route('studio.master.user.index', ['notification' => 'Pegawai berhasil ditambahkan.']));

    $this->assertDatabaseHas('users', [
        'username' => 'pegawaibaru',
        'email' => 'pegawai@example.com',
    ]);

    $user = User::where('username', 'pegawaibaru')->first();
    $this->assertDatabaseHas('employees', [
        'user_id' => $user->id,
        'full_name' => 'Pegawai Baru',
        'base_salary' => 5000000,
    ]);

    expect($user->outlets)->toHaveCount(1);
    expect($user->hasRole('Admin'))->toBeTrue();
});

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

    Livewire::actingAs($this->user)
        ->test(Create::class)
        ->set('form.full_name', 'Unauthorized User')
        ->call('save')
        ->assertForbidden();
});
