<?php

namespace App\Http\Controllers\Teacher;

use App\Http\Controllers\Concerns\RestrictsTeacherLessons;
use App\Http\Controllers\Controller;
use App\Models\Classroom;
use App\Models\Exam;
use App\Models\Question;
use Illuminate\Http\Request;

class ExamController extends Controller
{
    use RestrictsTeacherLessons;

    public function index()
    {
        $exams = $this->teacherExams()
            ->when(request()->q, function ($query) {
                $query->where('title', 'like', '%' . request()->q . '%');
            })
            ->with(['lesson', 'classroom'])
            ->withCount('questions')
            ->latest()
            ->paginate(5);

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

        return inertia('Admin/Exams/Index', [
            'exams' => $exams,
        ]);
    }

    public function create()
    {
        return inertia('Admin/Exams/Create', [
            'lessons' => $this->teacherLessons()->orderBy('title')->get(),
            'classrooms' => Classroom::orderBy('title')->get(),
        ]);
    }

    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required',
            'lesson_id' => 'required|integer|exists:lessons,id',
            'classroom_id' => 'required|integer|exists:classrooms,id',
            'duration' => 'required|integer',
            'description' => 'required',
            'random_question' => 'required',
            'random_answer' => 'required',
            'show_answer' => 'required',
            'question_weights' => 'nullable|array',
        ]);

        $this->ensureTeacherOwnsLesson((int) $request->lesson_id);

        $exam = Exam::create($request->only([
            'title',
            'lesson_id',
            'classroom_id',
            'duration',
            'description',
            'random_question',
            'random_answer',
            'show_answer',
            'question_weights',
        ]));

        return redirect()->back()->with([
            'new_exam_id' => $exam->id,
            'new_exam_title' => $exam->title,
        ]);
    }

    public function show($id)
    {
        $exam = $this->teacherExams()->with('lesson', 'classroom')->findOrFail($id);

        $alreadyAssignedIds = $exam->questions()->pluck('questions.id')->toArray();

        $availableQuestions = Question::where('lesson_id', $exam->lesson_id)
            ->whereNotIn('id', $alreadyAssignedIds)
            ->get();

        $exam->setRelation('questions', $exam->questions()->paginate(5));

        return inertia('Admin/Exams/Show', [
            'exam' => $exam,
            'availableQuestions' => $availableQuestions,
        ]);
    }

    public function edit($id)
    {
        $exam = $this->teacherExams()->findOrFail($id);

        return inertia('Admin/Exams/Edit', [
            'exam' => $exam,
            'lessons' => $this->teacherLessons()->orderBy('title')->get(),
            'classrooms' => Classroom::orderBy('title')->get(),
        ]);
    }

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

        $request->validate([
            'title' => 'required',
            'lesson_id' => 'required|integer|exists:lessons,id',
            'classroom_id' => 'required|integer|exists:classrooms,id',
            'duration' => 'required|integer',
            'description' => 'required',
            'random_question' => 'required',
            'random_answer' => 'required',
            'show_answer' => 'required',
            'question_weights' => 'nullable|array',
        ]);

        $this->ensureTeacherOwnsLesson((int) $request->lesson_id);

        $exam->update($request->only([
            'title',
            'lesson_id',
            'classroom_id',
            'duration',
            'description',
            'random_question',
            'random_answer',
            'show_answer',
            'question_weights',
        ]));

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

    public function destroy($id)
    {
        $this->teacherExams()->findOrFail($id)->delete();

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

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

        $request->validate([
            'question_count' => 'required|integer|min:1',
        ]);

        $questionIds = Question::where('lesson_id', $exam->lesson_id)
            ->inRandomOrder()
            ->limit($request->question_count)
            ->pluck('id');

        if ($questionIds->isEmpty()) {
            return back()->with('error', 'Tidak ada soal tersedia di bank soal untuk Mata Pelajaran ini.');
        }

        $exam->questions()->syncWithoutDetaching($questionIds);

        return back()->with('success', count($questionIds) . ' soal berhasil ditambahkan secara acak.');
    }

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

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

        $allowedIds = Question::where('lesson_id', $exam->lesson_id)
            ->whereIn('id', $request->question_ids)
            ->pluck('id')
            ->all();

        $exam->questions()->syncWithoutDetaching($allowedIds);

        return back()->with('success', 'Soal berhasil ditambahkan.');
    }

    public function removeQuestion(Exam $exam, Question $question)
    {
        abort_unless(in_array($exam->lesson_id, $this->teacherLessonIds(), true), 403);
        abort_unless($question->lesson_id === $exam->lesson_id, 403);

        $exam->questions()->detach($question->id);

        return back()->with('success', 'Soal berhasil dilepas dari ujian.');
    }
}
