<?php
/**
 * Generate exam questions from curriculum TOPICS — no study-material upload.
 *
 * Mirrors generate_questions.php's contract (plan/quota, job record, refinement,
 * response shape) but sources questions from the standard GES curriculum for the
 * given subject/class/term and the supplied topics, via the shared
 * generateChunkQuestions($fromCurriculum = true) path.
 */
declare(strict_types=1);
require_once __DIR__ . '/_json_guard.php';
session_start();
require_once '../../config.php';
require_once dirname(__DIR__) . '/includes/question_builder.php';
require_once dirname(__DIR__) . '/lib/content_chunker.php';   // plan helpers: planHasAIExamAddon(), getPlanJobQuota(), planSupportsRefinement()
require_once dirname(__DIR__) . '/lib/question_refiner.php';
header('Content-Type: application/json');

if (!isset($_SESSION['user_id'])) {
    http_response_code(401);
    echo json_encode(['success' => false]);
    exit;
}

$conn = getDBConnection();
if (!$conn instanceof mysqli) {
    echo json_encode(['success' => false, 'message' => 'Database connection failed']);
    exit;
}

// ── Ensure supporting tables exist (mirrors generate_questions.php) ─────────
$conn->query("CREATE TABLE IF NOT EXISTS ai_generation_jobs (
    id               INT AUTO_INCREMENT PRIMARY KEY,
    material_id      INT NOT NULL,
    subject_id       INT NOT NULL,
    class_name       VARCHAR(100) NOT NULL,
    term             VARCHAR(50)  DEFAULT NULL,
    academic_year    VARCHAR(20)  DEFAULT NULL,
    difficulty       VARCHAR(20)  DEFAULT 'medium',
    mcq_count        INT          DEFAULT 0,
    theory_count     INT          DEFAULT 0,
    fill_blank_count INT          DEFAULT 0,
    diagram_count    INT          DEFAULT 0,
    chunk_count      INT          DEFAULT 0,
    status           VARCHAR(20)  DEFAULT 'processing',
    result_summary   TEXT         DEFAULT NULL,
    engine_used      VARCHAR(50)  DEFAULT NULL,
    refined          TINYINT(1)   NOT NULL DEFAULT 0,
    refiner_engine   VARCHAR(50)  DEFAULT NULL,
    error_message    TEXT         DEFAULT NULL,
    created_by       INT          NOT NULL,
    created_at       TIMESTAMP    DEFAULT CURRENT_TIMESTAMP,
    completed_at     TIMESTAMP    NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

$conn->query("CREATE TABLE IF NOT EXISTS ai_generation_quota (
    id          INT AUTO_INCREMENT PRIMARY KEY,
    school_code VARCHAR(50)  NOT NULL,
    month_year  CHAR(7)      NOT NULL,
    jobs_used   INT          NOT NULL DEFAULT 0,
    word_count  INT          NOT NULL DEFAULT 0,
    updated_at  TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uq_school_month (school_code, month_year)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

// ── Plan & quota check ─────────────────────────────────────────────────────
if (!planHasAIExamAddon()) {
    echo json_encode(['success' => false, 'message' => 'AI Exam Generator is not included in your current plan.']);
    exit;
}

$monthYear  = date('Y-m');
$schoolCode = defined('SCHOOL_CODE') ? SCHOOL_CODE : 'DEMO';
$jobQuota   = getPlanJobQuota();

$qRow = $conn->query(
    "SELECT jobs_used FROM ai_generation_quota
     WHERE school_code = '" . $conn->real_escape_string($schoolCode) . "'
       AND month_year  = '" . $conn->real_escape_string($monthYear) . "'"
);
$qData    = $qRow ? $qRow->fetch_assoc() : null;
$jobsUsed = (int) ($qData['jobs_used'] ?? 0);

if ($jobsUsed >= $jobQuota) {
    echo json_encode([
        'success' => false,
        'message' => "Monthly AI generation quota reached ({$jobsUsed}/{$jobQuota}). Resets on the 1st of next month.",
    ]);
    exit;
}

// ── Parse request ──────────────────────────────────────────────────────────
$subjectId      = (int)   ($_POST['subject_id']       ?? 0);
$className      = trim((string) ($_POST['class_name']  ?? ''));
$term           = trim((string) ($_POST['term']        ?? ''));
$academicYear   = trim((string) ($_POST['academic_year'] ?? ''));
$difficulty     = trim((string) ($_POST['difficulty']  ?? 'medium'));
$topics         = trim((string) ($_POST['topics']      ?? ''));
$mcqCount       = max(0, (int) ($_POST['mcq_count']        ?? 0));
$theoryCount    = max(0, (int) ($_POST['theory_count']     ?? 0));
$fillBlankCount = max(0, (int) ($_POST['fill_blank_count'] ?? 0));
$trueFalseCount = max(0, (int) ($_POST['true_false_count'] ?? 0));
$matchingCount  = max(0, (int) ($_POST['matching_count']   ?? 0));
$comprehensionCount = max(0, (int) ($_POST['comprehension_count'] ?? 0));
$diagramCount   = max(0, (int) ($_POST['diagram_count']    ?? 0));

if ($subjectId <= 0 || $className === '' || $topics === '') {
    echo json_encode(['success' => false, 'message' => 'Select a subject and class, and enter at least one topic.']);
    exit;
}
$totalQuestions = $mcqCount + $theoryCount + $fillBlankCount + $trueFalseCount + $matchingCount + $comprehensionCount;
if ($totalQuestions <= 0) {
    echo json_encode(['success' => false, 'message' => 'Set at least one question to generate.']);
    exit;
}

// ── Fetch subject info ─────────────────────────────────────────────────────
$subjectStmt = $conn->prepare("SELECT subject_code, subject_name FROM subjects WHERE id = ? LIMIT 1");
$subjectStmt->bind_param('i', $subjectId);
$subjectStmt->execute();
$subject = $subjectStmt->get_result()->fetch_assoc();
$subjectStmt->close();
if (!$subject) {
    echo json_encode(['success' => false, 'message' => 'Subject not found']);
    exit;
}
$subjectCode = (string) ($subject['subject_code'] ?? '');
$subjectName = (string) ($subject['subject_name'] ?? '');

$userId = (int) $_SESSION['user_id'];

// ── Create job record (material_id = NULL — no material in topic mode; the
//    column has an FK to ai_study_materials, so 0 would violate it) ──────────
$materialId = null;
$chunkCount = 1;
$insertJob = $conn->prepare(
    "INSERT INTO ai_generation_jobs
      (material_id, subject_id, class_name, term, academic_year, difficulty,
       mcq_count, theory_count, fill_blank_count, diagram_count, chunk_count,
       status, created_by)
     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'processing', ?)"
);
$insertJob->bind_param(
    'iissssiiiiii',
    $materialId, $subjectId, $className, $term, $academicYear, $difficulty,
    $mcqCount, $theoryCount, $fillBlankCount, $diagramCount, $chunkCount,
    $userId
);
$insertJob->execute();
$jobId = (int) $insertJob->insert_id;
$insertJob->close();

set_time_limit(300);

// ── Generate (single curriculum-sourced call) ──────────────────────────────
$engineUsed     = '';
$allQuestions   = [];
$allInsertedIds = [];

try {
    $result = generateChunkQuestions(
        $conn,
        $subjectId,
        $subjectCode,
        $subjectName,
        $className,
        $term,
        $academicYear,
        $difficulty,
        $mcqCount,
        $theoryCount,
        $fillBlankCount,
        $diagramCount,
        $topics,                 // "content" = the topics to cover
        'Curriculum topics',     // chunk topic label
        $jobId,
        $userId,
        true,                    // $fromCurriculum
        $trueFalseCount,
        $matchingCount,
        $comprehensionCount
    );
    $engineUsed     = (string) ($result['engine'] ?? '');
    $allQuestions   = $result['questions'] ?? [];
    $allInsertedIds = $result['inserted_ids'] ?? [];
} catch (Throwable $e) {
    $msg = $e->getMessage();
    $fail = $conn->prepare("UPDATE ai_generation_jobs SET status='failed', error_message=?, completed_at=NOW() WHERE id=?");
    $fail->bind_param('si', $msg, $jobId);
    $fail->execute();
    $fail->close();
    echo json_encode(['success' => false, 'message' => 'Generation failed: ' . $msg]);
    exit;
}

if (empty($allInsertedIds)) {
    $err = 'No questions were generated. Try rephrasing or narrowing the topics.';
    $fail = $conn->prepare("UPDATE ai_generation_jobs SET status='failed', error_message=?, completed_at=NOW() WHERE id=?");
    $fail->bind_param('si', $err, $jobId);
    $fail->execute();
    $fail->close();
    echo json_encode(['success' => false, 'message' => $err]);
    exit;
}

// ── Refinement pass (Growth / Premium only) ────────────────────────────────
$refined       = false;
$refinerEngine = '';
if (planSupportsRefinement() && !empty($allQuestions)) {
    $refineResult = refineQuestions($allQuestions, $subjectName, $className, $difficulty, $engineUsed);
    if ($refineResult['refined'] && !empty($refineResult['questions'])) {
        $refined       = true;
        $refinerEngine = (string) $refineResult['engine'];
        $refinedQs     = $refineResult['questions'];
        $updateQ = $conn->prepare(
            "UPDATE exam_questions
             SET question=?, option_a=?, option_b=?, option_c=?, option_d=?,
                 correct_answer=?, marks=?, moderation_note=?, refined=1
             WHERE id=?"
        );
        foreach ($refinedQs as $i => $rq) {
            $id = $allInsertedIds[$i] ?? 0;
            if ($id <= 0) {
                continue;
            }
            $rQ   = trim((string) ($rq['question']       ?? ''));
            $rA   = (string) ($rq['option_a']            ?? '');
            $rB   = (string) ($rq['option_b']            ?? '');
            $rC   = (string) ($rq['option_c']            ?? '');
            $rD   = (string) ($rq['option_d']            ?? '');
            $rCor = (string) ($rq['correct_answer']      ?? '');
            $rM   = max(1, (int) ($rq['marks']           ?? 1));
            $rN   = (string) ($rq['moderation_note']     ?? '');
            $updateQ->bind_param('ssssssiis', $rQ, $rA, $rB, $rC, $rD, $rCor, $rM, $rN, $id);
            $updateQ->execute();
        }
        $updateQ->close();
    }
}

// ── Update quota ───────────────────────────────────────────────────────────
$wc        = str_word_count($topics);
$safeCode  = $conn->real_escape_string($schoolCode);
$safeMonth = $conn->real_escape_string($monthYear);
$conn->query(
    "INSERT INTO ai_generation_quota (school_code, month_year, jobs_used, word_count)
     VALUES ('{$safeCode}', '{$safeMonth}', 1, {$wc})
     ON DUPLICATE KEY UPDATE jobs_used = jobs_used + 1, word_count = word_count + {$wc}"
);

// ── Finalise job ───────────────────────────────────────────────────────────
$savedCount = count($allInsertedIds);
$summary    = "Generated {$savedCount} questions from curriculum topics: "
            . "{$mcqCount} MCQ, {$theoryCount} Theory, {$fillBlankCount} Fill in Blank, {$trueFalseCount} True/False, {$matchingCount} Matching, {$comprehensionCount} Comprehension";
$doneStmt = $conn->prepare(
    "UPDATE ai_generation_jobs
     SET status='done', result_summary=?, engine_used=?, refined=?, refiner_engine=?, completed_at=NOW()
     WHERE id=?"
);
$refinedInt = $refined ? 1 : 0;
$doneStmt->bind_param('ssisi', $summary, $engineUsed, $refinedInt, $refinerEngine, $jobId);
$doneStmt->execute();
$doneStmt->close();

echo json_encode([
    'success'        => true,
    'job_id'         => $jobId,
    'engine'         => $engineUsed,
    'summary'        => $summary,
    'refined'        => $refined,
    'refiner_engine' => $refinerEngine,
    'chunk_count'    => 1,
    'quota_used'     => $jobsUsed + 1,
    'quota_limit'    => $jobQuota,
    'partial_errors' => [],
]);
