<?php
/**
 * Action: Generate AI teacher remarks for terminal report cards.
 *
 * Remarks are written in batches rather than one API call per student. The
 * previous loop made one call per pupil — 34s for a 15-pupil class, ~90s for
 * 40 — which on a slower provider ran past the request time limit and left the
 * class half-written. It also burned through Groq's per-minute token cap.
 */

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

/** Pupils per AI call. Small enough to stay well inside any provider's cap. */
if (!defined('RBC_REMARK_BATCH_SIZE')) {
    define('RBC_REMARK_BATCH_SIZE', 5);
}

if (!function_exists('rbcGenerateRemarkBatch')) {
    /**
     * Ask for one remark per pupil in a single call.
     *
     * @param array  $batch Each: ['id','name','scores_text','avg','conduct','interest']
     * @return array<int,string> student_id => remark (missing entries fall back)
     */
    function rbcGenerateRemarkBatch(array $batch, string $class_name, string $term, string $academic_year): array
    {
        if (!$batch) return [];

        $lines = [];
        foreach ($batch as $b) {
            $lines[] = sprintf(
                '{"student_id": %d, "name": "%s", "average": %s, "scores": "%s", "conduct": "%s", "interest": "%s"}',
                $b['id'],
                str_replace('"', "'", $b['name']),
                $b['avg'],
                str_replace('"', "'", $b['scores_text']),
                str_replace('"', "'", (string) $b['conduct']),
                str_replace('"', "'", (string) $b['interest'])
            );
        }

        $prompt =
            "Write a terminal report remark for each pupil below, in {$class_name}.\n" .
            "This report is for {$term} of the {$academic_year} academic year — if you mention " .
            "the term at all it must be {$term}. Do not name any other term.\n" .
            "Each remark must be 2 sentences, encouraging and constructive, and must refer to that " .
            "pupil's own subjects and average. Do not reuse wording between pupils.\n\n" .
            "Pupils:\n" . implode("\n", $lines) . "\n\n" .
            'Return JSON only, an array of {"student_id": <number>, "remark": "<text>"} — one entry per pupil.';

        $result = RBCAIEngine::generate(
            $prompt,
            'You are an experienced school teacher writing report card remarks for Ghanaian students.',
            400 * count($batch) + 300,
            true
        );
        if (!$result['success']) return [];

        $raw = (string) $result['content'];
        $raw = preg_replace('/^```json\s*/i', '', trim($raw));
        $raw = preg_replace('/^```\s*/i', '', (string) $raw);
        $raw = preg_replace('/\s*```$/', '', (string) $raw);
        $parsed = json_decode(trim((string) $raw), true);

        // Accept a bare array or a wrapper such as {"remarks": [...]}.
        if (is_array($parsed) && !isset($parsed[0])) {
            foreach ($parsed as $v) {
                if (is_array($v) && isset($v[0])) { $parsed = $v; break; }
            }
        }
        if (!is_array($parsed)) return [];

        $out = [];
        foreach ($parsed as $row) {
            if (!is_array($row)) continue;
            $sid    = (int) ($row['student_id'] ?? 0);
            $remark = trim((string) ($row['remark'] ?? ''));
            if ($sid > 0 && $remark !== '') $out[$sid] = $remark;
        }
        return $out;
    }
}

function action_generate_terminal_reports(array $params): array
{
    $conn          = getDBConnection();
    $class_name    = $params['class_name'] ?? '';
    $term          = $params['term'] ?? '';
    $academic_year = $params['academic_year'] ?? getSettingValue('academic_year') ?? date('Y');

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

    $stmt = $conn->prepare("SELECT id, first_name, last_name FROM students WHERE class = ? AND status = 'active'");
    $stmt->bind_param('s', $class_name);
    $stmt->execute();
    $students = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
    $stmt->close();

    // ── Gather everything the model needs, in two queries rather than 2N ──
    $pending = [];
    $skipped = 0;

    $score_stmt = $conn->prepare(
        "SELECT sub.subject_name, sr.total_score
         FROM scores sr
         JOIN subjects sub ON sub.id = sr.subject_id
         WHERE sr.student_id = ? AND sr.term = ? AND sr.academic_year = ?"
    );
    $rd_stmt = $conn->prepare(
        "SELECT conduct, interest FROM report_details
         WHERE student_id = ? AND term = ? AND academic_year = ? LIMIT 1"
    );

    foreach ($students as $student) {
        $student_id = (int) $student['id'];

        $score_stmt->bind_param('iss', $student_id, $term, $academic_year);
        $score_stmt->execute();
        $scores = $score_stmt->get_result()->fetch_all(MYSQLI_ASSOC);

        if (empty($scores)) { $skipped++; continue; }

        $list = []; $sum = 0.0;
        foreach ($scores as $row) {
            $list[] = $row['subject_name'] . ': ' . $row['total_score'];
            $sum   += (float) $row['total_score'];
        }

        $rd_stmt->bind_param('iss', $student_id, $term, $academic_year);
        $rd_stmt->execute();
        $rd = $rd_stmt->get_result()->fetch_assoc() ?: [];

        $pending[] = [
            'id'          => $student_id,
            'name'        => trim($student['first_name'] . ' ' . $student['last_name']),
            'scores_text' => implode(', ', $list),
            'avg'         => round($sum / count($scores), 1),
            'conduct'     => $rd['conduct']  ?? '',
            'interest'    => $rd['interest'] ?? '',
        ];
    }
    $score_stmt->close();
    $rd_stmt->close();

    // ── Generate in batches ────────────────────────────────────────────────
    $remarks   = [];
    $ai_calls  = 0;
    foreach (array_chunk($pending, RBC_REMARK_BATCH_SIZE) as $chunk) {
        $ai_calls++;
        $remarks += rbcGenerateRemarkBatch($chunk, (string) $class_name, (string) $term, (string) $academic_year);
    }

    // Any pupil the model missed gets one targeted retry, then a safe default.
    $missing = array_values(array_filter($pending, fn($p) => !isset($remarks[$p['id']])));
    if ($missing) {
        foreach (array_chunk($missing, 1) as $one) {
            $ai_calls++;
            $remarks += rbcGenerateRemarkBatch($one, (string) $class_name, (string) $term, (string) $academic_year);
        }
    }

    // ── Persist ────────────────────────────────────────────────────────────
    $generated = 0;
    $fallbacks = 0;

    $check_stmt = $conn->prepare("SELECT id FROM report_details WHERE student_id = ? AND term = ? AND academic_year = ?");
    $up_stmt    = $conn->prepare(
        "UPDATE report_details SET teacher_remark = ?, updated_at = NOW()
         WHERE student_id = ? AND term = ? AND academic_year = ?"
    );
    $in_stmt    = $conn->prepare(
        "INSERT INTO report_details (student_id, term, academic_year, teacher_remark, created_at)
         VALUES (?, ?, ?, ?, NOW())"
    );

    foreach ($pending as $p) {
        $student_id = $p['id'];
        if (isset($remarks[$student_id])) {
            $remark = $remarks[$student_id];
        } else {
            $remark = 'A good student who shows potential. Keep up the hard work and continue to strive for excellence.';
            $fallbacks++;
        }

        $check_stmt->bind_param('iss', $student_id, $term, $academic_year);
        $check_stmt->execute();
        $exists = (bool) $check_stmt->get_result()->fetch_assoc();

        if ($exists) {
            $up_stmt->bind_param('siss', $remark, $student_id, $term, $academic_year);
            $up_stmt->execute();
        } else {
            $in_stmt->bind_param('isss', $student_id, $term, $academic_year, $remark);
            $in_stmt->execute();
        }
        $generated++;
    }

    $check_stmt->close();
    $up_stmt->close();
    $in_stmt->close();

    return [
        'success'           => true,
        'reports_generated' => $generated,
        'skipped'           => $skipped,
        'class_name'        => $class_name,
        'term'              => $term,
        'academic_year'     => $academic_year,
        'ai_calls'          => $ai_calls,
        'fallback_remarks'  => $fallbacks,
    ];
}
