<?php
/**
 * Action: Generate an exam paper using AI, save to database.
 */

if (!defined('DB_HOST')) {
    require_once __DIR__ . '/../../config.php';
}
require_once __DIR__ . '/../provider_engine.php';

function action_generate_exam_paper(array $params): array
{
    $conn          = getDBConnection();
    $subject_name  = $params['subject_name'] ?? $params['subject'] ?? '';
    $class_name    = $params['class_name'] ?? $params['class'] ?? '';
    $term          = $params['term'] ?? getSettingValue('current_term') ?? 'First Term';
    $academic_year = $params['academic_year'] ?? getSettingValue('academic_year') ?? date('Y');
    $mcq_count     = (int) ($params['mcq_count'] ?? 10);
    $theory_count  = (int) ($params['theory_count'] ?? 5);
    $fill_count    = (int) ($params['fill_blank_count'] ?? 5);
    $difficulty    = $params['difficulty'] ?? 'mixed';
    $paper_title   = $params['paper_title'] ?? "{$subject_name} Examination — {$term} {$academic_year}";

    if (empty($subject_name) || empty($class_name)) {
        return ['success' => false, 'error' => 'subject_name and class_name are required'];
    }

    // Find subject_id
    $sub_stmt = $conn->prepare("SELECT id FROM subjects WHERE subject_name LIKE ? LIMIT 1");
    $subject_like = '%' . $subject_name . '%';
    $sub_stmt->bind_param('s', $subject_like);
    $sub_stmt->execute();
    $sub_row   = $sub_stmt->get_result()->fetch_assoc();
    // Use NULL (not 0) when no matching subject exists — exam_papers.subject_id
    // has a foreign key to subjects.id, so 0 would violate the constraint.
    $subject_id = $sub_row ? (int) $sub_row['id'] : null;

    $questions_generated = 0;
    $questions_from_bank = 0;
    $provider_used       = 'none';
    $all_question_ids    = [];

    // Try to pull from question bank first
    if ($subject_id) {
        $bank_stmt = $conn->prepare(
            "SELECT id FROM exam_questions
             WHERE subject_id = ? AND class_name = ? AND is_active = 1
             ORDER BY RAND() LIMIT ?"
        );
        $bank_limit = $mcq_count + $theory_count + $fill_count;
        $bank_stmt->bind_param('isi', $subject_id, $class_name, $bank_limit);
        $bank_stmt->execute();
        $bank_qs = $bank_stmt->get_result()->fetch_all(MYSQLI_ASSOC);
        foreach ($bank_qs as $bq) {
            $all_question_ids[] = (int) $bq['id'];
        }
        $questions_from_bank = count($all_question_ids);
    }

    $total_needed = $mcq_count + $theory_count + $fill_count;
    $still_needed = $total_needed - $questions_from_bank;

    if ($still_needed > 0 && !empty($subject_name) && !empty($class_name)) {
        $prompt = "Generate {$still_needed} exam questions for {$subject_name} for {$class_name} students in Ghana. " .
                  "Term: {$term}. Difficulty: {$difficulty}. " .
                  "Include a mix of: MCQ (with options A,B,C,D and correct_answer), theory, and fill-in-blank types. " .
                  "Return a JSON array of objects: [{\"question_type\":\"mcq|theory|fill_blank\", \"question\":\"...\", " .
                  "\"option_a\":\"...\",\"option_b\":\"...\",\"option_c\":\"...\",\"option_d\":\"...\", " .
                  "\"correct_answer\":\"A|B|C|D\",\"marks\":2,\"difficulty\":\"easy|medium|hard\"}]. " .
                  "For theory and fill_blank, omit options and correct_answer.";

        $ai_result = RBCAIEngine::generate(
            $prompt,
            "You are a Ghana Education Service exam setter. Generate curriculum-appropriate exam questions.",
            3000,
            true
        );

        if ($ai_result['success']) {
            $provider_used = $ai_result['provider'];
            $raw = preg_replace('/^```json\s*/i', '', trim($ai_result['content']));
            $raw = preg_replace('/^```\s*/i', '', $raw);
            $raw = preg_replace('/\s*```$/', '', $raw);
            $ai_questions = json_decode(trim($raw), true);

            if (is_array($ai_questions)) {
                $q_stmt = $conn->prepare(
                    "INSERT INTO exam_questions
                     (subject_id, class_name, term, academic_year, question_type,
                      question, option_a, option_b, option_c, option_d,
                      correct_answer, marks, difficulty, ai_generated, created_at)
                     VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,1,NOW())"
                );

                foreach ($ai_questions as $q) {
                    if (empty($q['question'])) continue;
                    $q_type  = $q['question_type'] ?? 'mcq';
                    $q_text  = $q['question'];
                    $opt_a   = $q['option_a'] ?? null;
                    $opt_b   = $q['option_b'] ?? null;
                    $opt_c   = $q['option_c'] ?? null;
                    $opt_d   = $q['option_d'] ?? null;
                    $correct = $q['correct_answer'] ?? null;
                    $marks   = (int) ($q['marks'] ?? 2);
                    $diff    = $q['difficulty'] ?? 'medium';

                    // issssssssssis = 13 types for 13 ? in SQL
                    $q_stmt->bind_param(
                        'issssssssssis',
                        $subject_id, $class_name, $term, $academic_year,
                        $q_type, $q_text, $opt_a, $opt_b, $opt_c, $opt_d,
                        $correct, $marks, $diff
                    );
                    if ($q_stmt->execute()) {
                        $all_question_ids[] = (int) $conn->insert_id;
                        $questions_generated++;
                    }
                }
            }
        }
    }

    // Create exam paper record
    $paper_stmt = $conn->prepare(
        "INSERT INTO exam_papers
         (title, subject_id, class_name, term, academic_year, status, created_by, created_at)
         VALUES (?,?,?,?,?,'draft',?,NOW())"
    );
    $created_by = $_SESSION['user_id'] ?? 0;
    $paper_stmt->bind_param('sisssi', $paper_title, $subject_id, $class_name, $term, $academic_year, $created_by);
    try {
        $paper_stmt->execute();
    } catch (Throwable $e) {
        error_log('generate_exam_paper: failed to save exam paper - ' . $e->getMessage());
        return ['success' => false, 'error' => 'Could not save the exam paper. Please try again.'];
    }
    $paper_id = (int) $conn->insert_id;

    // Link questions to paper
    if ($paper_id && !empty($all_question_ids)) {
        $link_stmt = $conn->prepare(
            "INSERT IGNORE INTO exam_paper_questions (paper_id, question_id, order_num)
             VALUES (?, ?, ?)"
        );
        foreach ($all_question_ids as $idx => $qid) {
            $link_stmt->bind_param('iii', $paper_id, $qid, $idx);
            $link_stmt->execute();
        }
    }

    return [
        'success'              => true,
        'paper_id'             => $paper_id,
        'paper_title'          => $paper_title,
        'questions_generated'  => $questions_generated,
        'questions_from_bank'  => $questions_from_bank,
        'provider_used'        => $provider_used,
        'total_questions'      => count($all_question_ids),
    ];
}
