<?php

namespace App\Http\Requests\Mentorship;

use Illuminate\Foundation\Http\FormRequest;

class ApplicationRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     */
    public function rules(): array
    {
        $isPublic = $this->routeIs('mentorship.public.*');
        $isUpdate = in_array($this->method(), ['PUT', 'PATCH']);

        $rules = [
            // Programme selection
            'programme_id' => [
                'required',
                'exists:mentorship_programmes,id',
            ],
            'category_id' => [
                'nullable',
                'exists:mentorship_categories,id',
            ],
            
            // Personal information
            'name' => [
                'required',
                'string',
                'max:191',
                'min:2',
                'regex:/^[a-zA-Z\s\-\.\']+$/', // Allow letters, spaces, hyphens, dots, apostrophes
            ],
            'email' => [
                'required',
                'email',
                'max:191',
            ],
            'phone' => [
                'required',
                'string',
                'max:50',
                'regex:/^[\+]?[0-9\s\-\(\)]{8,20}$/',
            ],
            'country' => [
                'nullable',
                'string',
                'max:100',
            ],
            'city' => [
                'nullable',
                'string',
                'max:100',
            ],
            'address' => [
                'nullable',
                'string',
                'max:500',
            ],
            
            // Professional information
            'occupation' => [
                'nullable',
                'string',
                'max:191',
            ],
            'organization' => [
                'nullable',
                'string',
                'max:191',
            ],
            'education_level' => [
                'nullable',
                'string',
                'max:100',
            ],
            'bio' => [
                'nullable',
                'string',
                'max:2000',
            ],
            
            // Role preference
            'role_preference' => [
                'required',
                'in:mentor,mentee',
            ],
            
            // Areas of interest
            'areas_of_interest' => [
                'nullable',
                'array',
                'max:10',
            ],
            'areas_of_interest.*' => [
                'string',
                'max:191',
            ],
            'skills' => [
                'nullable',
                'array',
                'max:20',
            ],
            'skills.*' => [
                'string',
                'max:100',
            ],
            'experience' => [
                'nullable',
                'string',
                'max:3000',
            ],
            'motivation' => [
                'required',
                'string',
                'min:50',
                'max:3000',
            ],
            'expectations' => [
                'nullable',
                'string',
                'max:2000',
            ],
            
            // Mentor-specific fields
            'expertise_areas' => [
                'nullable',
                'string',
                'max:2000',
            ],
            'years_of_experience' => [
                'nullable',
                'integer',
                'min:0',
                'max:60',
            ],
            'mentoring_experience' => [
                'nullable',
                'string',
                'max:2000',
            ],
            'availability' => [
                'nullable',
                'string',
                'max:500',
            ],
            
            // Mentee-specific fields
            'learning_goals' => [
                'nullable',
                'string',
                'max:2000',
            ],
            'preferred_mentor_qualities' => [
                'nullable',
                'string',
                'max:2000',
            ],
            'time_commitment' => [
                'nullable',
                'string',
                'max:500',
            ],
            
            // Documents
            'documents' => [
                'nullable',
                'array',
                'max:5',
            ],
            'documents.*' => [
                'file',
                'max:10240', // 10MB max
                'mimes:pdf,doc,docx,jpg,jpeg,png',
            ],
            'profile_image' => [
                'nullable',
                'image',
                'max:5120', // 5MB max
                'mimes:jpg,jpeg,png',
            ],
            
            // Source tracking
            'source' => [
                'nullable',
                'string',
                'max:100',
            ],
            
            // Consent
            'terms_accepted' => [
                $isPublic && !$isUpdate ? 'accepted' : 'nullable',
                'boolean',
            ],
            'privacy_accepted' => [
                $isPublic && !$isUpdate ? 'accepted' : 'nullable',
                'boolean',
            ],
        ];

        // Payment fields (for chargeable programmes) — supports both mobile money and card
        if ($this->input('payment_required')) {
            $paymentMethod = $this->input('payment_method', 'mobile');
            $rules['payment_method'] = ['nullable', 'string', 'in:mobile,card'];

            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 {
                // payment-method-toggle submits 'phone_number'
                $rules['phone_number'] = [
                    'required',
                    'string',
                    'max:50',
                    'regex:/^[0-9]{10,15}$/',
                ];
            }
        }

        return $rules;
    }

    /**
     * Get custom messages for validator errors.
     */
    public function messages(): array
    {
        return [
            'name.required' => 'Please enter your full name.',
            'name.regex' => 'The name may only contain letters, spaces, hyphens, and apostrophes.',
            'email.required' => 'Please enter your email address.',
            'email.email' => 'Please enter a valid email address.',
            'phone.required' => 'Please enter your phone number.',
            'phone.regex' => 'Please enter a valid phone number (8-20 digits).',
            'role_preference.required' => 'Please select whether you want to be a mentor or mentee.',
            'role_preference.in' => 'Please select a valid role (mentor or mentee).',
            'motivation.required' => 'Please tell us about your motivation for joining.',
            'motivation.min' => 'Please provide at least 50 characters for your motivation.',
            'areas_of_interest.max' => 'You can select a maximum of 10 areas of interest.',
            'skills.max' => 'You can add a maximum of 20 skills.',
            'years_of_experience.min' => 'Years of experience cannot be negative.',
            'years_of_experience.max' => 'Years of experience cannot exceed 60.',
            'documents.max' => 'You can upload a maximum of 5 documents.',
            'documents.*.max' => 'Each document must not exceed 10MB.',
            'documents.*.mimes' => 'Documents must be in PDF, Word, or image format.',
            'profile_image.max' => 'Profile image must not exceed 5MB.',
            'profile_image.mimes' => 'Profile image must be in JPG or PNG format.',
            'terms_accepted.accepted' => 'You must accept the terms and conditions.',
            'privacy_accepted.accepted' => 'You must accept the privacy policy.',
            'phone_number.required' => 'Please enter your MTN MoMo phone number for payment.',
            'phone_number.regex'   => 'Please enter a valid phone number (10-15 digits).',
            'card_number.required' => 'Card number is required.',
            'card_expiry.required' => 'Card expiry date is required.',
            'card_cvv.required'    => 'CVV is required.',
        ];
    }

    /**
     * Prepare the data for validation.
     */
    protected function prepareForValidation(): void
    {
        $this->merge([
            'terms_accepted' => $this->boolean('terms_accepted'),
            'privacy_accepted' => $this->boolean('privacy_accepted'),
        ]);

        // Normalize phone number
        if ($this->has('phone')) {
            $phone = preg_replace('/[^0-9]/', '', $this->input('phone'));
            $this->merge(['phone' => $phone]);
        }

        // Set consent timestamp
        if ($this->boolean('terms_accepted') && $this->boolean('privacy_accepted')) {
            $this->merge(['consent_at' => now()]);
        }
    }

    /**
     * Get validated data with additional processing.
     */
    public function validated($key = null, $default = null): array
    {
        $validated = parent::validated($key, $default);

        // XSS Prevention
        $textFields = [
            'name', 'bio', 'experience', 'motivation', 'expectations',
            'expertise_areas', 'mentoring_experience', 'availability',
            'learning_goals', 'preferred_mentor_qualities', 'time_commitment'
        ];
        foreach ($textFields as $field) {
            if (isset($validated[$field])) {
                $validated[$field] = strip_tags($validated[$field], '<p><br><strong><em><u><ol><ul><li><a>');
            }
        }

        return $validated;
    }

    /**
     * Configure the validator instance.
     */
    public function withValidator($validator): void
    {
        $validator->after(function ($validator) {
            // Check if programme is open for registration
            if ($this->has('programme_id')) {
                $programme = \App\Models\Mentorship\Programme::find($this->input('programme_id'));
                if ($programme && !$programme->canApply()) {
                    $validator->errors()->add('programme_id', 'This programme is not currently accepting applications.');
                }
            }
        });
    }
}
