<?php

namespace App\Http\Controllers\Admin\School;

use App\Http\Controllers\Admin\PageController;
use App\Models\AcademicYear;
use App\Models\SchoolClass;
use App\Models\Staff;
use App\Models\Student;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class ClassController extends PageController
{
    public function index(): View
    {
        $classes = SchoolClass::query()
            ->with(['academicYear', 'classTeacher'])
            ->withCount('students')
            ->orderBy('name')
            ->paginate(25);

        return $this->page('admin.classes.index', [
            'crumbTitle' => 'Classes',
            'crumbSub' => 'Class groups & enrolment',
            'classes' => $classes,
        ]);
    }

    public function create(): View
    {
        return $this->page('admin.classes.create', [
            'crumbTitle' => 'Classes',
            'crumbSub' => 'New class',
            'academicYears' => AcademicYear::query()->orderByDesc('starts_on')->get(),
            'staffMembers' => Staff::query()->where('status', 'active')->orderBy('last_name')->get(),
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        $validated = $this->validateClass($request);
        $schoolClass = SchoolClass::query()->create($validated);

        return redirect()
            ->route('school.classes.show', $schoolClass)
            ->with('success', 'Class created successfully.');
    }

    public function show(SchoolClass $class): View
    {
        $class->load(['academicYear', 'classTeacher', 'students']);

        $availableStudents = Student::query()
            ->where('status', 'active')
            ->whereDoesntHave('classes', fn ($q) => $q->where('classes.id', $class->id))
            ->orderBy('last_name')
            ->limit(100)
            ->get();

        return $this->page('admin.classes.show', [
            'crumbTitle' => 'Classes',
            'crumbSub' => $class->name,
            'schoolClass' => $class,
            'availableStudents' => $availableStudents,
        ]);
    }

    public function edit(SchoolClass $class): View
    {
        return $this->page('admin.classes.edit', [
            'crumbTitle' => 'Classes',
            'crumbSub' => 'Edit '.$class->name,
            'schoolClass' => $class,
            'academicYears' => AcademicYear::query()->orderByDesc('starts_on')->get(),
            'staffMembers' => Staff::query()->where('status', 'active')->orderBy('last_name')->get(),
        ]);
    }

    public function update(Request $request, SchoolClass $class): RedirectResponse
    {
        $class->update($this->validateClass($request));

        return redirect()
            ->route('school.classes.show', $class)
            ->with('success', 'Class updated successfully.');
    }

    public function destroy(SchoolClass $class): RedirectResponse
    {
        $class->delete();

        return redirect()
            ->route('school.classes.index')
            ->with('success', 'Class removed.');
    }

    public function enroll(Request $request, SchoolClass $class): RedirectResponse
    {
        $validated = $request->validate([
            'student_ids' => ['required', 'array', 'min:1'],
            'student_ids.*' => ['exists:students,id'],
        ]);

        foreach ($validated['student_ids'] as $studentId) {
            $class->students()->syncWithoutDetaching([
                $studentId => [
                    'enrolled_on' => now()->toDateString(),
                    'status' => 'active',
                ],
            ]);
        }

        return back()->with('success', count($validated['student_ids']).' student(s) admitted to '.$class->name.'.');
    }

    public function removeStudent(SchoolClass $class, Student $student): RedirectResponse
    {
        $class->students()->detach($student->id);

        return back()->with('success', 'Student removed from class.');
    }

    /**
     * @return array<string, mixed>
     */
    private function validateClass(Request $request): array
    {
        return $request->validate([
            'name' => ['required', 'string', 'max:100'],
            'code' => ['required', 'string', 'max:30', 'unique:classes,code,'.$request->route('class')?->id],
            'academic_year_id' => ['required', 'exists:academic_years,id'],
            'class_teacher_id' => ['nullable', 'exists:staff,id'],
            'capacity' => ['nullable', 'integer', 'min:1', 'max:200'],
            'room' => ['nullable', 'string', 'max:50'],
            'level' => ['nullable', 'string', 'max:50'],
            'status' => ['nullable', 'string', 'max:30'],
        ]);
    }
}
