<?php

declare(strict_types=1);

/**

 * SchoolContext — builds a real-time snapshot of school data and

 * assembles the full system prompt for the RBC AI Agent.

 */



if (!defined('DB_HOST')) {

    require_once __DIR__ . '/../config.php';

}



class SchoolContext {



    /**

     * Build a keyed array of current school metrics pulled live from the DB.

     */

    public static function build(): array {

        $conn = getDBConnection();

        $ctx  = [];



        // ── Identity ───────────────────────────────────────────────────────

        $ctx['school_name']   = (string) (getSettingValue('school_name')   ?? 'the school');

        $ctx['academic_year'] = (string) (getSettingValue('academic_year') ?? date('Y'));

        $ctx['current_term']  = self::detectTerm();

        $ctx['today']         = date('l, j F Y');

        $ctx['current_user']  = (string) ($_SESSION['full_name']  ?? $_SESSION['username'] ?? 'Admin');

        $ctx['current_role']  = (string) ($_SESSION['role']       ?? 'admin');



        // ── Students ───────────────────────────────────────────────────────

        $r = $conn->query("SELECT COUNT(*) AS n FROM students WHERE status='active'");

        $ctx['total_students'] = $r ? (int) $r->fetch_assoc()['n'] : 0;



        $r = $conn->query(

            "SELECT class, COUNT(*) AS n FROM students

             WHERE status='active' AND class IS NOT NULL AND class != ''

             GROUP BY class ORDER BY class"

        );

        $ctx['classes'] = [];

        if ($r) {

            while ($row = $r->fetch_assoc()) {

                $ctx['classes'][] = $row['class'] . ' (' . $row['n'] . ' students)';

            }

        }



        // ── Fees ───────────────────────────────────────────────────────────

        $year = $conn->real_escape_string($ctx['academic_year']);

        $r = $conn->query(

            "SELECT

               COALESCE(SUM(fs.amount), 0)       AS total_expected,

               COALESCE(SUM(p.amount_paid), 0)   AS total_collected

             FROM fee_structures fs

             LEFT JOIN payments p ON p.fee_structure_id = fs.id

             WHERE fs.academic_year = '{$year}'"

        );

        $fee = $r ? $r->fetch_assoc() : ['total_expected' => 0, 'total_collected' => 0];

        $ctx['total_fees_expected']   = (float) ($fee['total_expected']  ?? 0);

        $ctx['total_fees_collected']  = (float) ($fee['total_collected'] ?? 0);

        $ctx['total_fees_outstanding'] = $ctx['total_fees_expected'] - $ctx['total_fees_collected'];

        $ctx['collection_rate'] = $ctx['total_fees_expected'] > 0

            ? round(($ctx['total_fees_collected'] / $ctx['total_fees_expected']) * 100, 1) . '%'

            : '0%';



        // ── Staff ──────────────────────────────────────────────────────────

        $r = $conn->query("SELECT COUNT(*) AS n FROM staff WHERE status='active'");

        $ctx['total_staff'] = $r ? (int) $r->fetch_assoc()['n'] : 0;



        // ── This month ─────────────────────────────────────────────────────

        $month_start = date('Y-m-01');

        $r = $conn->query(

            "SELECT COALESCE(SUM(amount_paid),0) AS n FROM payments

             WHERE payment_date >= '{$month_start}'"

        );

        $ctx['collections_this_month'] = $r ? (float) $r->fetch_assoc()['n'] : 0;



        $r = $conn->query(

            "SELECT COALESCE(SUM(amount),0) AS n FROM expenses

             WHERE expense_date >= '{$month_start}'"

        );

        $ctx['expenses_this_month'] = $r ? (float) $r->fetch_assoc()['n'] : 0;



        // ── Canteen Module ─────────────────────────────────────────────────

        $ctx['canteen_active'] = false;

        if (function_exists('canteen_is_active')) {

            $ctx['canteen_active'] = canteen_is_active();

        } elseif (file_exists(__DIR__ . '/../includes/canteen_helpers.php')) {

            require_once __DIR__ . '/../includes/canteen_helpers.php';

            $ctx['canteen_active'] = canteen_is_active();

        }



        if ($ctx['canteen_active']) {

            $r = $conn->query(

                "SELECT COUNT(*) AS sessions,

                        SUM(ce.status = 'confirmed') AS confirmed,

                        SUM(ce.status = 'pending')   AS pending

                 FROM canteen_entitlements ce

                 JOIN canteen_sessions cs ON cs.id = ce.session_id

                 WHERE cs.session_date = CURDATE() AND cs.status != 'cancelled'"

            );

            $cm = $r ? $r->fetch_assoc() : [];

            $ctx['canteen_today_confirmed'] = (int) ($cm['confirmed'] ?? 0);

            $ctx['canteen_today_pending']   = (int) ($cm['pending']   ?? 0);

            $ctx['canteen_today_sessions']  = (int) ($cm['sessions']  ?? 0);

        }



        // ── Agent memory ───────────────────────────────────────────────────

        $ctx['memory'] = [];

        $r = $conn->query(

            "SELECT memory_key, memory_value

             FROM ai_agent_memory

             ORDER BY updated_at DESC LIMIT 20"

        );

        if ($r) {

            while ($row = $r->fetch_assoc()) {

                $ctx['memory'][$row['memory_key']] = $row['memory_value'];

            }

        }



        return $ctx;

    }



    /**

     * Build the full system prompt string injected into every AI call.

     */

    public static function buildSystemPrompt(array $ctx): string {

        $classes_list = implode(', ', $ctx['classes']) ?: 'No classes found';

        $memory_str   = '';

        foreach ($ctx['memory'] as $k => $v) {

            $memory_str .= "  - {$k}: {$v}\n";

        }

        if (!$memory_str) {

            $memory_str = "  (No learned facts yet)\n";

        }



        $exp  = number_format($ctx['total_fees_expected'],   2);

        $coll = number_format($ctx['total_fees_collected'],  2);

        $out  = number_format($ctx['total_fees_outstanding'], 2);

        $mon  = number_format($ctx['collections_this_month'], 2);

        $exp_m = number_format($ctx['expenses_this_month'],   2);



        $canteen_state = '';

        if (!empty($ctx['canteen_active'])) {

            $canteen_state = "\n- Canteen Module: ACTIVE"

                . "\n- Today's Meals Confirmed: {$ctx['canteen_today_confirmed']}"

                . "\n- Today's Meals Pending: {$ctx['canteen_today_pending']}"

                . "\n- Today's Sessions: {$ctx['canteen_today_sessions']}";

        } else {

            $canteen_state = "\n- Canteen Module: not active";

        }



        $canteen_actions = !empty($ctx['canteen_active']) ? "

CANTEEN MODULE ACTIONS (available because canteen is active):

11. bulk_create_canteen_entitlements — Params: class_name (required). Trigger phrases: \"Record canteen for [class]\", \"Add feeding for [class]\". Creates entitlements for all students in the class for today's sessions.

12. canteen_daily_report — Params: date (optional, defaults to today). Trigger phrases: \"Canteen report today\", \"How many meals served\", \"Canteen summary\". Returns session-by-session meal counts and revenue.

13. cancel_canteen_session — Params: session_name or session_id, date (optional, defaults to today). Trigger phrases: \"Cancel canteen [session] today\", \"No lunch today\", \"Cancel breakfast session\". Marks session cancelled and SMS notifies parents.

14. send_canteen_reminder_sms — Params: session_id (optional), class_name (optional). Trigger phrases: \"Remind parents about canteen\", \"Send canteen reminder\", \"Notify parents to use canteen pass\". SMS parents of students with pending (unscanned) entitlements." : '';



        return <<<PROMPT

You are RBC AI — the intelligent assistant for {$ctx['school_name']}'s EduTrack school management system. You help school administrators manage students, fees, reports, exams, timetables, and staff.



CURRENT SCHOOL STATE:

- School: {$ctx['school_name']}

- Academic Year: {$ctx['academic_year']}

- Current Term: {$ctx['current_term']}

- Today: {$ctx['today']}

- You are speaking with: {$ctx['current_user']} ({$ctx['current_role']})

- Total Active Students: {$ctx['total_students']}

- Classes: {$classes_list}

- Total Staff: {$ctx['total_staff']}

- Fees Expected This Year: GHS {$exp}

- Fees Collected: GHS {$coll} ({$ctx['collection_rate']})

- Outstanding Fees: GHS {$out}

- Collections This Month: GHS {$mon}

- Expenses This Month: GHS {$exp_m}{$canteen_state}



WHAT YOU REMEMBER ABOUT THIS SCHOOL:

{$memory_str}



YOUR CAPABILITIES:

You can perform the following actions by including them in your response:



1. send_fee_reminders — Params: class_name (optional), min_balance (default 0)

2. generate_terminal_reports — Params: class_name (required), term, academic_year

3. generate_exam_paper — Params: subject_name, class_name, mcq_count, theory_count, fill_blank_count, difficulty_mix

4. detect_at_risk_students — Params: class_name (optional), score_threshold (default 50), fee_threshold (default 100)

5. financial_snapshot — Params: date_from, date_to

6. send_weekly_feeding_summary — Params: week_start, week_end

7. check_timetable_conflicts — Params: academic_year, term

8. bulk_notify_parents — Params: target (all/class/individual), class_name, title, message, send_sms

9. batch_generate_report_pdfs — Params: class_name, term, academic_year

10. create_parent_accounts_bulk — Params: class_name (optional)

{$canteen_actions}



RESPONSE FORMAT — always return valid JSON:

{

  "message": "Your conversational reply. Be warm, specific. Use GHS for currency. Reference actual data from CURRENT SCHOOL STATE above.",

  "needs_clarification": false,

  "clarification_question": "",

  "actions": [

    { "type": "action_name", "params": {}, "description": "What you are about to do" }

  ],

  "plan_steps": [],

  "memory_updates": [

    { "key": "fact_key", "value": "fact_value", "type": "school_fact" }

  ],

  "follow_up_suggestions": ["Suggestion 1", "Suggestion 2", "Suggestion 3"],

  "data_response": null

}



RULES:

1. Always use real data from CURRENT SCHOOL STATE. Never invent numbers.

2. If a request is ambiguous, set needs_clarification=true and ask ONE specific question.

3. For bulk SMS or destructive actions, confirm before executing.

4. If you learn a preference (e.g. "we always remind classes with balance over GHS 200"), add it to memory_updates.

5. Be friendly and professional. Write as if speaking to a Ghanaian school headteacher.

6. For multi-step tasks, list all planned steps in plan_steps as description strings.

7. Respond ONLY with the JSON object. No markdown, no extra text outside the JSON.

PROMPT;

    }



    /**

     * Infer the current academic term from settings or the calendar month.

     */

    /**

     * Current academic term.

     *

     * Delegates to the canonical getCurrentTerm() in config.php. The local

     * copy this replaces read `if ($month >= 9 || $month <= 12)` — the second

     * clause is true for every month, so it always returned "First Term"

     * whenever the current_term setting was unset. It also disagreed with the

     * other two copies about which months map to which term.

     */

    private static function detectTerm(): string {

        if (function_exists('getCurrentTerm')) {

            return (string) getCurrentTerm();

        }

        $term = (string) (getSettingValue('current_term') ?? '');

        return $term !== '' ? $term : 'First Term';

    }

}

