<?php

namespace App\Http\Requests;

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

/**
 * ProcessPaymentRequest
 *
 * Validates payment processing requests for MTN MoMo integration.
 *
 * Requirements: 2.3, 9.1, 10.1
 */
class ProcessPaymentRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return auth()->check();
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        $paymentMethod = $this->input('payment_method', 'mobile');

        $rules = [
            // Payment Details
            'amount' => [
                'required',
                'numeric',
                'min:1',
                'max:9999999999.99',
            ],
            'currency' => [
                'required',
                'string',
                Rule::in(['SSP', 'USD']),
            ],
            'payment_frequency' => [
                'required',
                'string',
                Rule::in(['one_time', 'monthly', 'quarterly', 'biannual', 'yearly']),
            ],

            // Payment method selector
            'payment_method' => ['nullable', 'string', Rule::in(['mobile', 'card'])],

            // Optional Messages
            'payer_message' => ['nullable', 'string', 'max:255'],
            'payee_note'    => ['nullable', 'string', 'max:255'],
        ];

        if ($paymentMethod === 'card') {
            $rules['card_number'] = ['required', 'string'];
            $rules['card_expiry'] = ['required', 'regex:/^(0[1-9]|1[0-2])\/\d{2}$/'];
            $rules['card_cvv']    = ['required', 'digits_between:3,4'];
        } else {
            $rules['phone_number'] = [
                'required',
                'string',
                'regex:/^[+]?[0-9]{10,15}$/',
            ];
        }

        return $rules;
    }

    /**
     * Get custom messages for validator errors.
     *
     * @return array<string, string>
     */
    public function messages(): array
    {
        return [
            'amount.required' => 'Payment amount is required.',
            'amount.min' => 'Payment amount must be at least 1.',
            'currency.in' => 'Currency must be SSP or USD.',
            'payment_frequency.required' => 'Please select a payment plan.',
            'phone_number.required' => 'Phone number is required for MTN MoMo payment.',
            'phone_number.regex' => 'Please enter a valid phone number (10-15 digits).',
            'payable_type.required' => 'Payment type is required.',
            'payable_type.in' => 'Invalid payment type.',
            'payable_id.required' => 'The item being paid for is required.',
        ];
    }

    /**
     * Prepare the data for validation.
     */
    protected function prepareForValidation(): void
    {
        // Normalize phone number to MSISDN format
        if ($this->phone_number) {
            $phone = preg_replace('/[^0-9]/', '', $this->phone_number);
            
            // Add South Sudan country code if missing
            if (strlen($phone) === 9 && !str_starts_with($phone, '211')) {
                $phone = '211' . $phone;
            }
            
            $this->merge(['phone_number' => $phone]);
        }
    }

    /**
     * Configure the validator instance.
     * Note: payable_type / payable_id are not sent by the payment form;
     * ownership is verified in the controller via abort_unless() instead.
     */
    public function withValidator($validator): void
    {
        // Ownership check is handled in the controller (abort_unless).
        // No additional cross-field validation needed here.
    }
}
