<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use App\Models\Exam;
use App\Models\ExamAttempt;
use App\Models\ExamQuestion;
use App\Models\Question;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

class ExamController extends Controller
{
    public function index(): View
    {
        $exams = Exam::with('course')
            ->where('is_active', true)
            ->latest()
            ->paginate(15);

        return view('user.exams.index', compact('exams'));
    }

    public function show(Request $request, Exam $exam): View
    {
        abort_unless($exam->is_active, 404);

        $exam->load('course');

        $activeAttempt = ExamAttempt::where('user_id', $request->user()->id)
            ->where('exam_id', $exam->id)
            ->where('status', 'in_progress')
            ->latest()
            ->first();

        $previousAttempts = ExamAttempt::where('user_id', $request->user()->id)
            ->where('exam_id', $exam->id)
            ->where('status', 'completed')
            ->latest()
            ->limit(10)
            ->get();

        return view('user.exams.show', compact(
            'exam',
            'activeAttempt',
            'previousAttempts'
        ));
    }

    public function start(Request $request, Exam $exam): RedirectResponse
    {
        abort_unless($exam->is_active, 404);

        $existingAttempt = ExamAttempt::where('user_id', $request->user()->id)
            ->where('exam_id', $exam->id)
            ->where('status', 'in_progress')
            ->latest()
            ->first();

        if ($existingAttempt) {
            return redirect()
                ->route('user.attempts.take', $existingAttempt)
                ->with('success', 'Continue your existing exam.');
        }

        $attempt = DB::transaction(function () use ($request, $exam) {
            $questions = Question::with('options')
                ->where('is_active', true)
                ->when($exam->course_id, function ($query) use ($exam) {
                    $query->where('course_id', $exam->course_id);
                })
                ->inRandomOrder()
                ->limit($exam->total_questions)
                ->get();

            if ($questions->count() < 1) {
                abort(422, 'No questions available for this exam yet.');
            }

            $attempt = ExamAttempt::create([
                'user_id' => $request->user()->id,
                'exam_id' => $exam->id,
                'started_at' => now(),
                'submitted_at' => null,
                'score' => 0,
                'percentage' => 0,
                'correct_answers' => 0,
                'wrong_answers' => 0,
                'unanswered' => $questions->count(),
                'status' => 'in_progress',
            ]);

            foreach ($questions as $index => $question) {
                $correctOption = $question->options->firstWhere('is_correct', true);

                ExamQuestion::create([
                    'exam_attempt_id' => $attempt->id,
                    'exam_id' => $exam->id,
                    'question_id' => $question->id,
                    'course_id' => $question->course_id,

                    'question_text' => $question->question,
                    'explanation' => $question->explanation,

                    'options_snapshot' => $question->options->map(function ($option) {
                        return [
                            'id' => $option->id,
                            'key' => $option->option_key,
                            'text' => $option->option_text,
                            'is_correct' => (bool) $option->is_correct,
                        ];
                    })->values()->toArray(),

                    'correct_option_id' => $correctOption?->id,
                    'correct_option_key' => $correctOption?->option_key,
                    'correct_option_text' => $correctOption?->option_text,

                    'selected_option_id' => null,
                    'selected_option_key' => null,
                    'selected_option_text' => null,
                    'is_correct' => null,

                    'sort_order' => $index + 1,
                ]);
            }

            return $attempt;
        });

        return redirect()
            ->route('user.attempts.take', $attempt)
            ->with('success', 'Exam started successfully.');
    }
}