<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class ClientPaymentMethodRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        $rules = [
            'client_id'        => ['sometimes', 'integer', 'exists:clients,id'],
            'token'            => ['sometimes', 'string', 'max:255'],
            'gateway_card_id'  => ['sometimes', 'nullable', 'string', 'max:255'],
            'card_number'      => ['sometimes', 'nullable', 'string', 'min:13', 'max:19'],
            'holder_name'      => ['sometimes', 'string', 'max:255'],
            'expiration'       => ['sometimes', 'string', 'regex:/^(0[1-9]|1[0-2])\/\d{4}$/'],
            'cvv'              => ['sometimes', 'nullable', 'string', 'min:3', 'max:4'],
            'card_name'        => ['nullable', 'string', 'max:255'],
            'brand'            => ['nullable', 'string', 'max:50'],
            'last_four_digits' => ['sometimes', 'string', 'size:4'],
            'is_active'        => ['nullable', 'boolean'],
        ];

        if ($this->isMethod('POST')) {
            $rules['client_id']        = ['required', 'integer', 'exists:clients,id'];
            $rules['token']            = ['nullable', 'string', 'max:255', Rule::requiredIf(! $this->filled('gateway_card_id'))];
            $rules['gateway_card_id']  = ['nullable', 'string', 'max:255', Rule::requiredIf(! $this->filled('token'))];
            $rules['card_number']      = ['sometimes', 'nullable', 'string', 'min:13', 'max:19'];
            $rules['holder_name']      = ['required', 'string', 'max:255'];
            $rules['expiration']       = ['required', 'string', 'regex:/^(0[1-9]|1[0-2])\/\d{4}$/'];
            $rules['cvv']              = ['sometimes', 'nullable', 'string', 'min:3', 'max:4'];
            $rules['last_four_digits'] = ['required', 'string', 'size:4'];
        }

        return $rules;
    }

    public function messages(): array
    {
        return [
            'client_id.required'        => __('requests.client_payment_method.client_required'),
            'client_id.exists'          => __('requests.client_payment_method.client_not_found'),
            'token.required'            => __('requests.client_payment_method.token_required'),
            'card_number.required'      => __('requests.client_payment_method.card_number_required'),
            'card_number.min'           => __('requests.client_payment_method.card_number_min'),
            'card_number.max'           => __('requests.client_payment_method.card_number_max'),
            'holder_name.required'      => __('requests.client_payment_method.holder_name_required'),
            'expiration.required'       => __('requests.client_payment_method.expiration_required'),
            'expiration.regex'          => __('requests.client_payment_method.expiration_format'),
            'cvv.required'              => __('requests.client_payment_method.cvv_required'),
            'cvv.min'                   => __('requests.client_payment_method.cvv_min'),
            'cvv.max'                   => __('requests.client_payment_method.cvv_max'),
            'last_four_digits.required' => __('requests.client_payment_method.last_four_required'),
            'last_four_digits.size'     => __('requests.client_payment_method.last_four_size'),
        ];
    }

    protected function prepareForValidation(): void
    {
        if ($this->has('card_number')) {
            $this->merge([
                'card_number' => str_replace(' ', '', $this->card_number),
            ]);
        }

        if ($this->has('cvv')) {
            $this->merge([
                'cvv' => str_replace(' ', '', $this->cvv),
            ]);
        }
    }
}
