<?php

namespace Modules\Enrollment\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Modules\Enrollment\Models\Enrollment;
use Modules\Academic\Models\Classroom;

class UpdateEnrollmentRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return $this->user()->hasRole('admin');
    }

    /**
     * Get the validation rules that apply to the request.
     */
    public function rules(): array
    {
        return [
            'classroom_id' => [
                'sometimes',
                'integer',
                'exists:classrooms,id'
            ],
            'academic_year_id' => [
                'sometimes',
                'integer',
                'exists:academic_years,id'
            ],
            'enrolled_at' => [
                'sometimes',
                'date',
                'before_or_equal:today'
            ],
            'is_active' => [
                'sometimes',
                'boolean'
            ],
        ];
    }

    /**
     * Get custom validation messages.
     */
    public function messages(): array
    {
        return [
            'classroom_id.exists' => 'Selected classroom does not exist.',
            'academic_year_id.exists' => 'Selected academic year does not exist.',
            'enrolled_at.date' => 'Please enter a valid enrollment date.',
            'enrolled_at.before_or_equal' => 'Enrollment date cannot be in the future.',
            'is_active.boolean' => 'Status must be active or inactive.',
        ];
    }

    /**
     * Configure the validator instance.
     */
    public function withValidator($validator): void
    {
        $validator->after(function ($validator) {
            $enrollment = $this->route('enrollment');

            // Check if classroom's academic year is active (if changing classroom)
            if ($this->classroom_id && $this->classroom_id != $enrollment->classroom_id) {
                $classroom = Classroom::with('academicYear')->find($this->classroom_id);
                if ($classroom && $classroom->academicYear && !$classroom->academicYear->is_active) {
                    $validator->errors()->add('classroom_id', 'Cannot transfer to classroom with inactive academic year.');
                }
            }

            // Check if academic year is valid for the classroom (if changing either)
            if ($this->classroom_id || $this->academic_year_id) {
                $classroomId = $this->classroom_id ?? $enrollment->classroom_id;
                $academicYearId = $this->academic_year_id ?? $enrollment->academic_year_id;

                $classroom = Classroom::find($classroomId);
                if ($classroom && $classroom->academic_year_id !== (int)$academicYearId) {
                    $validator->errors()->add('academic_year_id', 'Selected academic year does not match the classroom\'s academic year.');
                }
            }

            // Check for duplicate enrollment (if changing classroom or academic year)
            if (($this->classroom_id && $this->classroom_id != $enrollment->classroom_id) ||
                ($this->academic_year_id && $this->academic_year_id != $enrollment->academic_year_id)) {

                $classroomId = $this->classroom_id ?? $enrollment->classroom_id;
                $academicYearId = $this->academic_year_id ?? $enrollment->academic_year_id;

                $existingEnrollment = Enrollment::where('student_id', $enrollment->student_id)
                    ->where('classroom_id', $classroomId)
                    ->where('academic_year_id', $academicYearId)
                    ->where('id', '!=', $enrollment->id)
                    ->where('is_active', true)
                    ->first();

                if ($existingEnrollment) {
                    $validator->errors()->add('classroom_id', 'Student is already enrolled in this classroom for the selected academic year.');
                }
            }

            // Check classroom capacity (if changing classroom)
            if ($this->classroom_id && $this->classroom_id != $enrollment->classroom_id) {
                $classroom = Classroom::find($this->classroom_id);
                $academicYearId = $this->academic_year_id ?? $enrollment->academic_year_id;

                if ($classroom && $classroom->capacity) {
                    $currentEnrollments = Enrollment::where('classroom_id', $this->classroom_id)
                        ->where('academic_year_id', $academicYearId)
                        ->where('is_active', true)
                        ->count();

                    if ($currentEnrollments >= $classroom->capacity) {
                        $validator->errors()->add('classroom_id', 'Target classroom has reached its maximum capacity.');
                    }
                }
            }

            // Validate enrollment date is within academic year (if changing either)
            if ($this->enrolled_at || $this->academic_year_id) {
                $enrolledAt = $this->enrolled_at ?? $enrollment->enrolled_at;
                $academicYearId = $this->academic_year_id ?? $enrollment->academic_year_id;

                $academicYear = \Modules\Academic\Models\AcademicYear::find($academicYearId);
                if ($academicYear) {
                    $enrolledDate = \Carbon\Carbon::parse($enrolledAt);
                    $startDate = \Carbon\Carbon::parse($academicYear->start_date);
                    $endDate = \Carbon\Carbon::parse($academicYear->end_date);

                    if ($enrolledDate->lt($startDate) || $enrolledDate->gt($endDate)) {
                        $validator->errors()->add('enrolled_at', 'Enrollment date must be within the academic year period.');
                    }
                }
            }

            // Prevent reactivation if student is already enrolled elsewhere
            if ($this->is_active === true && !$enrollment->is_active) {
                $existingEnrollment = Enrollment::where('student_id', $enrollment->student_id)
                    ->where('academic_year_id', $enrollment->academic_year_id)
                    ->where('id', '!=', $enrollment->id)
                    ->where('is_active', true)
                    ->first();

                if ($existingEnrollment) {
                    $classroom = Classroom::find($existingEnrollment->classroom_id);
                    $validator->errors()->add('is_active', "Cannot reactivate: Student is already enrolled in {$classroom->name} for this academic year.");
                }
            }

            // Prevent deactivation if student has recent results
            if ($this->is_active === false && $enrollment->is_active) {
                $recentResults = $enrollment->student->results()
                    ->where('classroom_id', $enrollment->classroom_id)
                    ->where('entered_at', '>=', now()->subDays(30))
                    ->count();

                if ($recentResults > 0) {
                    $validator->errors()->add('is_active', 'Cannot deactivate enrollment: Student has recent results in this classroom.');
                }
            }
        });
    }

    /**
     * Get custom attributes for validator errors.
     */
    public function attributes(): array
    {
        return [
            'classroom_id' => 'classroom',
            'academic_year_id' => 'academic year',
            'enrolled_at' => 'enrollment date',
            'is_active' => 'status',
        ];
    }
}
