<?php

namespace App\Filament\Student\Pages;

use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Illuminate\Support\Facades\Mail;
use App\Mail\QuizPassedMail;
use App\Mail\QuizFailedMail;
use App\Mail\CertificateReadyMail;

class ExamRunner extends Page
{
    protected string $view = 'filament.student.pages.exam-runner';

    protected static bool $shouldRegisterNavigation = false;

    public $exam_id;

    public $exam;

    public $attempt;

    public $currentQuestionIndex = 0;

    public $answers = []; // question_id => option_id

    public $isSubmitted = false;

    public $score = 0;

    public $isPassed = false;

    public $remainingSeconds = 0;

    public function mount($exam_id = null)
    {
        $this->exam_id = $exam_id ?? request()->query('exam_id');

        if (! $this->exam_id) {
            return redirect()->route('filament.student.pages.my-courses');
        }

        $this->exam = \App\Models\Exam::with(['questionSet.questions', 'course'])->find($this->exam_id);

        if (! $this->exam || ! $this->exam->is_active) {
            Notification::make()->title('Exam is not active')->danger()->send();

            return redirect()->route('filament.student.pages.my-courses');
        }

        // Check attempts
        $attemptsCount = \App\Models\ExamAttempt::where('user_id', auth()->id())
            ->where('exam_id', $this->exam_id)
            ->count();

        if ($attemptsCount >= $this->exam->max_attempts) {
            Notification::make()->title('Max attempts reached')->danger()->send();

            return redirect()->route('filament.student.pages.my-courses');
        }

        // Pick random questions from the exam's Question Set
        $selectedQuestionIds = \App\Models\Question::where('question_set_id', $this->exam->question_set_id)
            ->inRandomOrder()
            ->limit($this->exam->questions_count)
            ->pluck('id')
            ->toArray();

        if (empty($selectedQuestionIds)) {
            Notification::make()
                ->title('No questions available')
                ->body('This exam has no questions configured. Please contact the administrator.')
                ->danger()
                ->send();

            return redirect()->route('filament.student.pages.my-courses');
        }

        // Start new attempt
        $this->attempt = \App\Models\ExamAttempt::create([
            'user_id' => auth()->id(),
            'exam_id' => $this->exam_id,
            'selected_question_ids' => $selectedQuestionIds,
            'completed_at' => null,
            'is_passed' => false,
            'score' => 0,
        ]);

        $this->remainingSeconds = $this->exam->time_limit_minutes * 60;

        // Load selected questions for the runner
        $this->loadQuestions();
    }

    public $questions;

    public function loadQuestions()
    {
        $questionIds = $this->attempt->selected_question_ids ?? [];
        if (empty($questionIds)) {
            // Fallback for attempts started before randomization logic
            $this->questions = $this->exam->questionSet->questions;
        } else {
            $questionsCollection = \App\Models\Question::whereIn('id', $questionIds)
                ->with('questionSet') // If needed
                ->get();

            // Restore order based on IDs array
            $this->questions = collect($questionIds)->map(function ($id) use ($questionsCollection) {
                return $questionsCollection->firstWhere('id', $id);
            })->filter()->values();
        }
    }

    public function checkTimer()
    {
        if ($this->isSubmitted) {
            return;
        }

        $secondsElapsed = now()->diffInSeconds($this->attempt->created_at);
        $allowedSeconds = $this->exam->time_limit_minutes * 60;

        $this->remainingSeconds = max(0, $allowedSeconds - $secondsElapsed);

        if ($this->remainingSeconds <= 0) {
            $this->submitExam();
        }
    }

    public function selectAnswer($questionId, $optionId)
    {
        $this->answers[$questionId] = $optionId;
    }

    public function nextQuestion()
    {
        if ($this->currentQuestionIndex < $this->questions->count() - 1) {
            $this->currentQuestionIndex++;
        }
    }

    public function previousQuestion()
    {
        if ($this->currentQuestionIndex > 0) {
            $this->currentQuestionIndex--;
        }
    }

    public function submitExam()
    {
        if ($this->isSubmitted) {
            return;
        }

        // Use loaded questions instead of all questions
        $questions = $this->questions;
        $totalMarks = $questions->sum('marks');
        $obtainedMarks = 0;

        foreach ($questions as $question) {
            if (isset($this->answers[$question->id]) && $this->answers[$question->id] == $question->correct_option_id) {
                $obtainedMarks += $question->marks;
            }
        }

        // Prevent division by zero
        $percentage = $totalMarks > 0 ? ($obtainedMarks / $totalMarks) * 100 : 0;

        $this->isPassed = $percentage >= $this->exam->passing_percentage;
        $this->score = $percentage;

        $this->attempt->update([
            'score' => $percentage,
            'is_passed' => $this->isPassed,
            'answers_snapshot' => $this->answers,
            'completed_at' => now(),
        ]);

        if ($this->isPassed) {
            Mail::to(auth()->user()->email)->queue(new QuizPassedMail(
                auth()->user()->name,
                $percentage,
                route('filament.student.pages.certificates')
            ));
            
            // Generate Certificate Record
            $certificate = \App\Models\Certificate::firstOrCreate([
                'user_id' => auth()->id(),
                'course_id' => $this->exam->course_id,
                'exam_attempt_id' => $this->attempt->id,
            ], [
                'certificate_code' => 'CERT-'.strtoupper(uniqid()),
                'issued_at' => now(),
            ]);

            // Generate and save Certificate PDF
            \App\Services\CertificateService::generate($certificate);
            
            Mail::to(auth()->user()->email)->queue(new CertificateReadyMail(
                auth()->user()->name,
                route('filament.student.pages.certificates') // OR direct URL to serve if available
            ));
        } else {
            Mail::to(auth()->user()->email)->queue(new QuizFailedMail(
                auth()->user()->name,
                $percentage,
                route('filament.student.pages.exam-runner', ['exam_id' => $this->exam_id])
            ));
        }

        $this->isSubmitted = true;
    }
}
