<?php

namespace App\Http\Controllers\Teacher;

use App\Http\Controllers\Concerns\RestrictsTeacherLessons;
use App\Http\Controllers\Controller;
use App\Models\ExamGroup;
use App\Models\ExamSession;
use App\Models\Student;
use Illuminate\Http\Request;

class ExamSessionController extends Controller
{
    use RestrictsTeacherLessons;

    public function index()
    {
        $examSessions = ExamSession::when(request()->q, function ($query) {
            $query->where('title', 'like', '%' . request()->q . '%');
        })
            ->whereHas('exam', fn ($query) => $query->whereIn('lesson_id', $this->teacherLessonIds()))
            ->with('exam.classroom', 'exam.lesson', 'exam_groups')
            ->latest()
            ->paginate(5);

        $examSessions->appends(['q' => request()->q]);

        return inertia('Admin/ExamSessions/Index', [
            'exam_sessions' => $examSessions,
            'server_time'   => now()->toISOString(),
        ]);
    }

    public function create()
    {
        return inertia('Admin/ExamSessions/Create', [
            'exams' => $this->teacherExams()->with('classroom', 'lesson')->orderBy('title')->get(),
        ]);
    }

    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required',
            'exam_id' => 'required|integer',
            'start_time' => 'required',
            'end_time' => 'required',
        ]);

        $exam = $this->findTeacherExamOrFail((int) $request->exam_id);

        $examSession = ExamSession::create([
            'title' => $request->title,
            'exam_id' => $exam->id,
            'start_time' => date('Y-m-d H:i:s', strtotime($request->start_time)),
            'end_time' => date('Y-m-d H:i:s', strtotime($request->end_time)),
        ]);

        return redirect()->back()->with([
            'new_session_id' => $examSession->id,
            'new_session_title' => $examSession->title,
        ]);
    }

    public function show($id)
    {
        $examSession = ExamSession::with('exam.classroom', 'exam.lesson')
            ->whereHas('exam', fn ($query) => $query->whereIn('lesson_id', $this->teacherLessonIds()))
            ->findOrFail($id);

        $examSession->setRelation('exam_groups', $examSession->exam_groups()->with('student.classroom')->paginate(5));

        return inertia('Admin/ExamSessions/Show', [
            'exam_session' => $examSession,
        ]);
    }

    public function edit($id)
    {
        $examSession = ExamSession::whereHas('exam', fn ($query) => $query->whereIn('lesson_id', $this->teacherLessonIds()))
            ->findOrFail($id);

        return inertia('Admin/ExamSessions/Edit', [
            'exam_session' => $examSession,
            'exams' => $this->teacherExams()->with('classroom', 'lesson')->orderBy('title')->get(),
        ]);
    }

    public function update(Request $request, ExamSession $exam_session)
    {
        abort_unless(in_array($exam_session->exam->lesson_id, $this->teacherLessonIds(), true), 403);

        $request->validate([
            'title' => 'required',
            'exam_id' => 'required|integer',
            'start_time' => 'required',
            'end_time' => 'required',
        ]);

        $exam = $this->findTeacherExamOrFail((int) $request->exam_id);

        $exam_session->update([
            'title' => $request->title,
            'exam_id' => $exam->id,
            'start_time' => date('Y-m-d H:i:s', strtotime($request->start_time)),
            'end_time' => date('Y-m-d H:i:s', strtotime($request->end_time)),
        ]);

        return redirect()->route('teacher.exam_sessions.index');
    }

    public function destroy($id)
    {
        ExamSession::whereHas('exam', fn ($query) => $query->whereIn('lesson_id', $this->teacherLessonIds()))
            ->findOrFail($id)
            ->delete();

        return redirect()->route('teacher.exam_sessions.index');
    }

    public function createEnrolle(ExamSession $exam_session)
    {
        abort_unless(in_array($exam_session->exam->lesson_id, $this->teacherLessonIds(), true), 403);

        $studentsEnrolled = ExamGroup::where('exam_id', $exam_session->exam_id)
            ->where('exam_session_id', $exam_session->id)
            ->pluck('student_id')
            ->all();

        $students = Student::with('classroom')
            ->where('classroom_id', $exam_session->exam->classroom_id)
            ->whereNotIn('id', $studentsEnrolled)
            ->get();

        return inertia('Admin/ExamGroups/Create', [
            'exam' => $exam_session->exam,
            'exam_session' => $exam_session,
            'students' => $students,
        ]);
    }

    public function storeEnrolle(Request $request, ExamSession $exam_session)
    {
        abort_unless(in_array($exam_session->exam->lesson_id, $this->teacherLessonIds(), true), 403);

        $request->validate([
            'student_id' => 'required|array',
        ]);

        foreach ($request->student_id as $studentId) {
            $student = Student::findOrFail($studentId);

            ExamGroup::firstOrCreate([
                'exam_id' => $exam_session->exam_id,
                'exam_session_id' => $exam_session->id,
                'student_id' => $student->id,
            ]);
        }

        return redirect()->route('teacher.exam_sessions.show', $exam_session->id);
    }

    public function destroyEnrolle(ExamSession $exam_session, ExamGroup $exam_group)
    {
        abort_unless(in_array($exam_session->exam->lesson_id, $this->teacherLessonIds(), true), 403);
        abort_unless($exam_group->exam_session_id === $exam_session->id, 404);

        $exam_group->delete();

        return redirect()->route('teacher.exam_sessions.show', $exam_session->id);
    }
}
