<?php

namespace App\Modules\HR\Employees\Requests;

use App\Modules\Customization\CustomFields\Services\CustomFieldRendererService;
use App\Modules\HR\Employees\Models\Employee;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Validator as ValidatorFacade;
use Illuminate\Validation\Validator;

class UpdateEmployeeRequest extends FormRequest
{
    public function authorize(): bool
    {
        $employee = $this->route('employee');

        return $employee instanceof Employee
            && ($this->user()?->can('employees.update', $employee) ?? false);
    }

    /**
     * @return array<string, mixed>
     */
    public function rules(): array
    {
        $docs = Gate::allows('employees.documents.view') ? EmployeeFormRules::documents() : [];

        return array_merge(
            EmployeeFormRules::employeeCore(Gate::allows('employees.salary.view')),
            EmployeeFormRules::address(),
            $docs,
            EmployeeFormRules::customFieldsShell(),
            [
                'is_active' => ['required', 'boolean'],
            ],
        );
    }

    protected function prepareForValidation(): void
    {
        $merge = [
            'is_active' => $this->boolean('is_active'),
        ];
        $employee = $this->route('employee');
        if ($employee instanceof Employee && ! Gate::allows('employees.salary.view')) {
            $merge['salary'] = (string) $employee->salary;
        }
        $this->merge($merge);
    }

    public function withValidator(Validator $validator): void
    {
        $validator->after(function (Validator $validator): void {
            $employee = $this->route('employee');
            $ignoreId = $employee instanceof Employee ? $employee->id : null;
            EmployeeRequestValidator::after($validator, $this, $ignoreId);
        });

        $validator->after(function (Validator $validator): void {
            if ($validator->errors()->isNotEmpty()) {
                return;
            }
            $employee = $this->route('employee');
            if (! $employee instanceof Employee) {
                return;
            }
            $employee->loadMissing('tenant');
            $tenant = $employee->tenant;
            $rules = app(CustomFieldRendererService::class)->validationRules($tenant, 'hr', 'employees');
            $inner = ValidatorFacade::make($this->all(), $rules);
            if ($inner->fails()) {
                $validator->errors()->merge($inner->errors());
            }
        });
    }
}
