<?php

namespace App\Http\Requests;

use App\Models\PermanentEmployee;
use App\Models\PermanentEmployeeSalaryPayment;
use App\Support\SalaryMonth;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Validator;

class StorePermanentEmployeeSalaryPaymentRequest extends FormRequest
{
    public function authorize(): bool
    {
        return (bool) $this->user()?->can('permanent-salaries.manage');
    }

    protected function prepareForValidation(): void
    {
        $this->merge([
            'salary_month' => SalaryMonth::urlKey(
                SalaryMonth::normalizeStart($this->input('salary_month')),
            ),
        ]);
    }

    /**
     * @return array<string, array<int, mixed>>
     */
    public function rules(): array
    {
        return [
            'salary_month' => ['required', 'date_format:Y-m-d'],
            'amount' => ['required', 'numeric', 'min:0'],
            'payment_method' => [
                'required',
                'string',
                Rule::in([
                    PermanentEmployeeSalaryPayment::PAYMENT_METHOD_FINGERPRINT,
                    PermanentEmployeeSalaryPayment::PAYMENT_METHOD_MANUAL,
                ]),
            ],
            'fingerprint_data' => [
                'exclude_unless:payment_method,'.PermanentEmployeeSalaryPayment::PAYMENT_METHOD_FINGERPRINT,
                'required',
                'string',
                'min:32',
                'max:65535',
            ],
            'manual_confirmed' => [
                'exclude_unless:payment_method,'.PermanentEmployeeSalaryPayment::PAYMENT_METHOD_MANUAL,
                'accepted',
            ],
        ];
    }

    public function withValidator(Validator $validator): void
    {
        $validator->after(function (Validator $validator): void {
            if ($validator->errors()->isNotEmpty()) {
                return;
            }

            /** @var PermanentEmployee $employee */
            $employee = $this->route('permanentEmployee');
            $salaryMonth = $this->string('salary_month')->toString();

            $existing = PermanentEmployeeSalaryPayment::query()
                ->where('permanent_employee_id', $employee->id)
                ->whereDate('salary_month', $salaryMonth)
                ->first();

            if ($existing === null) {
                $validator->errors()->add(
                    'salary_month',
                    __('Generate salaries for this month before recording payment.'),
                );

                return;
            }

            if (! $existing->isDraft()) {
                $validator->errors()->add(
                    'salary_month',
                    __('Salary for this month has already been paid.'),
                );
            }
        });
    }

    /**
     * @return array<string, string>
     */
    public function messages(): array
    {
        return [
            'manual_confirmed.accepted' => __('You must confirm that payment was made to the staff member.'),
            'salary_month.date_format' => __('Select a valid Shamsi salary month.'),
        ];
    }
}
