<?php

declare(strict_types=1);

namespace Admin\Controllers;

/**
 * Admin Exam Controller
 *
 * CRUD operations for exams and their MCQ questions.
 */
class AdminExamController extends AdminController
{
    /**
     * List all exams with course info.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function index(array $params = []): void
    {
        requireAdmin();

        $stmt = $this->db->query(
            'SELECT e.*, c.name AS course_name
             FROM `exams` e
             LEFT JOIN `courses` c ON e.course_id = c.id
             ORDER BY e.created_at DESC'
        );
        $exams = $stmt->fetchAll() ?: [];

        $this->adminView('exams', [
            'title'       => 'Manage Exams',
            'currentPage' => 'exams',
            'exams'       => $exams,
            'editExam'    => null,
            'examQuestions' => [],
        ]);
    }

    /**
     * Show the create exam form.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function create(array $params = []): void
    {
        requireAdmin();

        $stmt = $this->db->query('SELECT `id`, `name` FROM `courses` WHERE `active` = 1 ORDER BY `name` ASC');
        $courses = $stmt->fetchAll() ?: [];

        $this->adminView('exams', [
            'title'        => 'Add New Exam',
            'currentPage'  => 'exams',
            'exams'        => [],
            'courses'      => $courses,
            'editExam'     => null,
            'examQuestions' => [],
            'showForm'     => true,
        ]);
    }

    /**
     * Store a new exam.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function store(array $params = []): void
    {
        requireAdmin();
        $this->validateCsrf();

        $title      = sanitize($_POST['title'] ?? '');
        $courseId   = (int) ($_POST['course_id'] ?? 0);
        $duration   = (int) ($_POST['duration_minutes'] ?? 60);
        $totalMarks = (int) ($_POST['total_marks'] ?? 100);
        $passMarks  = (int) ($_POST['pass_marks'] ?? 40);
        $isPublished = isset($_POST['is_published']) ? 1 : 0;

        if (empty($title) || $courseId === 0) {
            flash('error', 'Exam title and course are required.');
            redirect(BASE_PATH . '/admin/exams/create');
        }

        $stmt = $this->db->prepare(
            'INSERT INTO `exams` (`title`, `course_id`, `duration_minutes`, `total_marks`, `pass_marks`, `is_published`)
             VALUES (:title, :course_id, :duration_minutes, :total_marks, :pass_marks, :is_published)'
        );

        $stmt->execute([
            ':title'            => $title,
            ':course_id'        => $courseId,
            ':duration_minutes' => $duration,
            ':total_marks'      => $totalMarks,
            ':pass_marks'       => $passMarks,
            ':is_published'     => $isPublished,
        ]);

        $examId = (int) $this->db->lastInsertId();

        flash('success', 'Exam created successfully. Add questions now.');
        redirect(BASE_PATH . '/admin/exams/' . $examId . '/questions');
    }

    /**
     * Show the edit exam form.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function edit(array $params = []): void
    {
        requireAdmin();

        $id = (int) ($params['id'] ?? 0);

        $stmt = $this->db->prepare(
            'SELECT e.*, c.name AS course_name
             FROM `exams` e
             LEFT JOIN `courses` c ON e.course_id = c.id
             WHERE e.id = :id LIMIT 1'
        );
        $stmt->execute([':id' => $id]);
        $editExam = $stmt->fetch() ?: null;

        if ($editExam === null) {
            flash('error', 'Exam not found.');
            redirect(BASE_PATH . '/admin/exams');
        }

        $stmt = $this->db->query('SELECT `id`, `name` FROM `courses` WHERE `active` = 1 ORDER BY `name` ASC');
        $courses = $stmt->fetchAll() ?: [];

        $this->adminView('exams', [
            'title'        => 'Edit Exam',
            'currentPage'  => 'exams',
            'exams'        => [],
            'courses'      => $courses,
            'editExam'     => $editExam,
            'examQuestions' => [],
            'showForm'     => true,
        ]);
    }

    /**
     * Update an existing exam.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function update(array $params = []): void
    {
        requireAdmin();
        $this->validateCsrf();

        $id = (int) ($params['id'] ?? 0);

        $title      = sanitize($_POST['title'] ?? '');
        $courseId   = (int) ($_POST['course_id'] ?? 0);
        $duration   = (int) ($_POST['duration_minutes'] ?? 60);
        $totalMarks = (int) ($_POST['total_marks'] ?? 100);
        $passMarks  = (int) ($_POST['pass_marks'] ?? 40);
        $isPublished = isset($_POST['is_published']) ? 1 : 0;

        if (empty($title) || $courseId === 0) {
            flash('error', 'Exam title and course are required.');
            redirect(BASE_PATH . '/admin/exams/' . $id . '/edit');
        }

        $stmt = $this->db->prepare(
            'UPDATE `exams` SET `title` = :title, `course_id` = :course_id,
             `duration_minutes` = :duration_minutes, `total_marks` = :total_marks,
             `pass_marks` = :pass_marks, `is_published` = :is_published WHERE `id` = :id'
        );

        $stmt->execute([
            ':title'            => $title,
            ':course_id'        => $courseId,
            ':duration_minutes' => $duration,
            ':total_marks'      => $totalMarks,
            ':pass_marks'       => $passMarks,
            ':is_published'     => $isPublished,
            ':id'               => $id,
        ]);

        flash('success', 'Exam updated successfully.');
        redirect(BASE_PATH . '/admin/exams');
    }

    /**
     * Delete an exam.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function delete(array $params = []): void
    {
        requireAdmin();
        $this->validateCsrf();

        $id = (int) ($params['id'] ?? 0);

        $stmt = $this->db->prepare('DELETE FROM `exams` WHERE `id` = :id');
        $stmt->execute([':id' => $id]);

        if ($stmt->rowCount() > 0) {
            flash('success', 'Exam deleted successfully.');
        } else {
            flash('warning', 'Exam not found or already deleted.');
        }
        redirect(BASE_PATH . '/admin/exams');
    }

    /**
     * Show questions for an exam and allow adding new ones.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function questions(array $params = []): void
    {
        requireAdmin();

        $id = (int) ($params['id'] ?? 0);

        $stmt = $this->db->prepare(
            'SELECT e.*, c.name AS course_name
             FROM `exams` e
             LEFT JOIN `courses` c ON e.course_id = c.id
             WHERE e.id = :id LIMIT 1'
        );
        $stmt->execute([':id' => $id]);
        $editExam = $stmt->fetch() ?: null;

        if ($editExam === null) {
            flash('error', 'Exam not found.');
            redirect(BASE_PATH . '/admin/exams');
        }

        $stmt = $this->db->prepare(
            'SELECT * FROM `exam_questions` WHERE `exam_id` = :exam_id ORDER BY `sort_order` ASC'
        );
        $stmt->execute([':exam_id' => $id]);
        $examQuestions = $stmt->fetchAll() ?: [];

        $this->adminView('exams', [
            'title'         => 'Manage Questions',
            'currentPage'   => 'exams',
            'exams'         => [],
            'courses'       => [],
            'editExam'      => $editExam,
            'examQuestions'  => $examQuestions,
            'showQuestions'  => true,
        ]);
    }

    /**
     * Add a question to an exam.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function addQuestion(array $params = []): void
    {
        requireAdmin();
        $this->validateCsrf();

        $id = (int) ($params['id'] ?? 0);

        $questionText  = $_POST['question_text'] ?? '';
        $optionA       = sanitize($_POST['option_a'] ?? '');
        $optionB       = sanitize($_POST['option_b'] ?? '');
        $optionC       = sanitize($_POST['option_c'] ?? '');
        $optionD       = sanitize($_POST['option_d'] ?? '');
        $correctAnswer = sanitize($_POST['correct_answer'] ?? 'a');
        $marks         = (int) ($_POST['marks'] ?? 1);
        $sortOrder     = (int) ($_POST['sort_order'] ?? 0);

        if (empty($questionText) || empty($optionA) || empty($optionB)) {
            flash('error', 'Question text and at least options A and B are required.');
            redirect(BASE_PATH . '/admin/exams/' . $id . '/questions');
        }

        if (!in_array($correctAnswer, ['a', 'b', 'c', 'd'], true)) {
            $correctAnswer = 'a';
        }

        $stmt = $this->db->prepare(
            'INSERT INTO `exam_questions` (`exam_id`, `question_text`, `option_a`, `option_b`, `option_c`, `option_d`, `correct_answer`, `marks`, `sort_order`)
             VALUES (:exam_id, :question_text, :option_a, :option_b, :option_c, :option_d, :correct_answer, :marks, :sort_order)'
        );

        $stmt->execute([
            ':exam_id'        => $id,
            ':question_text'  => $questionText,
            ':option_a'       => $optionA,
            ':option_b'       => $optionB,
            ':option_c'       => $optionC,
            ':option_d'       => $optionD,
            ':correct_answer' => $correctAnswer,
            ':marks'          => $marks,
            ':sort_order'     => $sortOrder,
        ]);

        flash('success', 'Question added successfully.');
        redirect(BASE_PATH . '/admin/exams/' . $id . '/questions');
    }

    /**
     * Delete a question from an exam.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function deleteQuestion(array $params = []): void
    {
        requireAdmin();
        $this->validateCsrf();

        $examId     = (int) ($params['id'] ?? 0);
        $questionId = (int) ($params['question_id'] ?? 0);

        $stmt = $this->db->prepare(
            'DELETE FROM `exam_questions` WHERE `id` = :id AND `exam_id` = :exam_id'
        );
        $stmt->execute([':id' => $questionId, ':exam_id' => $examId]);

        if ($stmt->rowCount() > 0) {
            flash('success', 'Question deleted successfully.');
        } else {
            flash('warning', 'Question not found or already deleted.');
        }
        redirect(BASE_PATH . '/admin/exams/' . $examId . '/questions');
    }
}
