<?php

namespace App\Http\Requests;

use App\Models\PayComponent;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class PayComponentRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user()?->hasAnyRole(['ADMIN', 'BURSARY']) ?? false;
    }

    public function rules(): array
    {
        $isCreate = $this->route('component') === null;

        return [
            // Code is the stable identifier used by the engine; only settable on create.
            'code' => $isCreate
                ? ['required', 'string', 'max:64', 'regex:/^[a-z][a-z0-9_]*$/', Rule::unique('pay_components', 'code')]
                : ['sometimes'],
            'name' => ['required', 'string', 'max:255'],
            'type' => ['required', Rule::in([PayComponent::TYPE_EARNING, PayComponent::TYPE_DEDUCTION, PayComponent::TYPE_STATUTORY])],
            'calc_method' => ['required', Rule::in([
                PayComponent::CALC_FIXED, PayComponent::CALC_PERCENT_OF,
                PayComponent::CALC_GRADE_TABLE, PayComponent::CALC_FORMULA, PayComponent::CALC_LOAN,
            ])],
            'base_reference' => ['nullable', 'string', 'max:64'],
            'rate' => ['nullable', 'numeric', 'min:0', 'max:1'],
            'amount' => ['nullable', 'numeric', 'min:0', 'max:99999999'],
            'formula' => ['nullable', 'string', 'max:1000'],
            'taxable' => ['boolean'],
            'pensionable' => ['boolean'],
            'tax_exempt' => ['boolean'],
            'prorate' => ['boolean'],
            'gl_account' => ['nullable', 'string', 'max:64'],
            'display_order' => ['nullable', 'integer', 'min:0', 'max:100000'],
            'active' => ['boolean'],
            'effective_from' => ['nullable', 'date'],
            'effective_to' => ['nullable', 'date'],
        ];
    }

    public function messages(): array
    {
        return [
            'code.regex' => 'Code must be lowercase letters, numbers and underscores, starting with a letter.',
            'rate.max' => 'Rate is a fraction (e.g. 0.08 for 8%).',
        ];
    }
}
