<?php

namespace App\Http\Requests\Mentorship;

use Illuminate\Foundation\Http\FormRequest;

class AssignmentRequest 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
    {
        $isUpdate = in_array($this->method(), ['PUT', 'PATCH']);

        $rules = [
            'programme_id' => [
                'required',
                'exists:mentorship_programmes,id',
            ],
            'mentor_id' => [
                'required',
                'exists:users,id',
                function ($attribute, $value, $fail) {
                    // Verify user has mentor role
                    $user = \App\Models\User::find($value);
                    if (!$user || !$user->hasRole('Mentor')) {
                        $fail('The selected user is not a mentor.');
                    }
                },
            ],
            'mentee_id' => [
                'required',
                'exists:users,id',
                'different:mentor_id',
                function ($attribute, $value, $fail) {
                    // Verify user has mentee role
                    $user = \App\Models\User::find($value);
                    if (!$user || !$user->hasRole('Mentee')) {
                        $fail('The selected user is not a mentee.');
                    }
                },
            ],
            'mentor_application_id' => [
                'nullable',
                'exists:mentorship_applications,id',
            ],
            'mentee_application_id' => [
                'nullable',
                'exists:mentorship_applications,id',
            ],
            'matching_criteria' => [
                'nullable',
                'string',
                'max:2000',
            ],
            'goals' => [
                'nullable',
                'string',
                'max:3000',
            ],
            'notes' => [
                'nullable',
                'string',
                'max:2000',
            ],
            'start_date' => [
                'required',
                'date',
                'after_or_equal:today',
            ],
            'end_date' => [
                'nullable',
                'date',
                'after:start_date',
            ],
            'preferred_meeting_time' => [
                'nullable',
                'string',
                'max:100',
            ],
            'meeting_frequency' => [
                'nullable',
                'string',
                'in:daily,weekly,biweekly,monthly',
            ],
            'milestones' => [
                'nullable',
                'array',
                'max:20',
            ],
            'milestones.*.title' => [
                'required',
                'string',
                'max:191',
            ],
            'milestones.*.description' => [
                'nullable',
                'string',
                'max:500',
            ],
            'milestones.*.due_date' => [
                'nullable',
                'date',
            ],
        ];

        return $rules;
    }

    /**
     * Get custom messages for validator errors.
     */
    public function messages(): array
    {
        return [
            'programme_id.required' => 'Please select a programme.',
            'programme_id.exists' => 'The selected programme does not exist.',
            'mentor_id.required' => 'Please select a mentor.',
            'mentor_id.exists' => 'The selected mentor does not exist.',
            'mentee_id.required' => 'Please select a mentee.',
            'mentee_id.exists' => 'The selected mentee does not exist.',
            'mentee_id.different' => 'A user cannot be both mentor and mentee in the same assignment.',
            'start_date.required' => 'Please select a start date.',
            'start_date.after_or_equal' => 'The start date must be today or a future date.',
            'end_date.after' => 'The end date must be after the start date.',
            'meeting_frequency.in' => 'Please select a valid meeting frequency.',
            'milestones.max' => 'You can add a maximum of 20 milestones.',
        ];
    }

    /**
     * Configure the validator instance.
     */
    public function withValidator($validator): void
    {
        $validator->after(function ($validator) {
            // Check if mentor is already assigned to this mentee in the same programme
            if ($this->has('programme_id') && $this->has('mentor_id') && $this->has('mentee_id')) {
                $exists = \App\Models\Mentorship\Assignment::where('programme_id', $this->input('programme_id'))
                    ->where('mentor_id', $this->input('mentor_id'))
                    ->where('mentee_id', $this->input('mentee_id'))
                    ->whereIn('status', ['pending_acceptance', 'active'])
                    ->exists();

                if ($exists) {
                    $validator->errors()->add('mentee_id', 'This mentor is already assigned to this mentee in this programme.');
                }
            }

            // Check if mentor has capacity
            if ($this->has('programme_id') && $this->has('mentor_id')) {
                $programme = \App\Models\Mentorship\Programme::find($this->input('programme_id'));
                if ($programme && $programme->max_mentees > 0) {
                    $currentMentees = \App\Models\Mentorship\Assignment::where('programme_id', $this->input('programme_id'))
                        ->where('mentor_id', $this->input('mentor_id'))
                        ->whereIn('status', ['pending_acceptance', 'active'])
                        ->count();

                    if ($currentMentees >= $programme->max_mentees) {
                        $validator->errors()->add('mentor_id', 'This mentor has reached their maximum mentee capacity for this programme.');
                    }
                }
            }
        });
    }

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

        // XSS Prevention
        $textFields = ['matching_criteria', 'goals', 'notes'];
        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;
    }
}
