<?php
/** Event / excursion accounts — CRUD, costs, participants and per-student billing. */
require_once __DIR__ . '/_boot.php';

$action = fin_in('action', '');

/** Recompute an event's rollups (spend, budget, participant charges/paid). */
function finance_event_summary(mysqli $conn, int $eventId): array
{
    $spend = 0.0;
    $r = $conn->query("SELECT COALESCE(SUM(amount),0) s FROM event_expenses WHERE event_id=" . $eventId);
    if ($r) $spend = (float) $r->fetch_assoc()['s'];
    $charged = 0.0; $paid = 0.0; $pcount = 0;
    $r = $conn->query("SELECT COALESCE(SUM(amount_charged),0) c, COALESCE(SUM(amount_paid),0) p, COUNT(*) n FROM event_participants WHERE event_id=" . $eventId);
    if ($r) { $row = $r->fetch_assoc(); $charged = (float) $row['c']; $paid = (float) $row['p']; $pcount = (int) $row['n']; }
    return ['spend' => $spend, 'charged' => $charged, 'paid' => $paid, 'participants' => $pcount];
}

switch ($action) {

    case 'list': {
        $rows = [];
        $res = $conn->query("SELECT * FROM event_accounts ORDER BY id DESC");
        while ($res && $row = $res->fetch_assoc()) {
            $row = array_merge($row, finance_event_summary($conn, (int) $row['id']));
            $rows[] = $row;
        }
        fin_out(['success' => true, 'data' => $rows]);
    }

    case 'save': {
        if (!in_array($actor['role'], ['admin', 'accountant', 'headteacher', 'supervisor', 'director'], true)) {
            fin_out(['success' => false, 'message' => 'Not permitted.']);
        }
        $id     = (int) fin_in('id', 0);
        $name   = trim((string) fin_in('name', ''));
        $date   = trim((string) fin_in('event_date', '')) ?: null;
        $loc    = trim((string) fin_in('location', ''));
        $desc   = trim((string) fin_in('description', ''));
        $budget = (float) fin_in('budget', 0);
        $status = fin_in('status', 'planning');
        if ($name === '') fin_out(['success' => false, 'message' => 'Event name is required.']);
        if (!in_array($status, ['planning', 'active', 'closed'], true)) $status = 'planning';

        if ($id > 0) {
            $stmt = $conn->prepare("UPDATE event_accounts SET name=?, event_date=?, location=?, description=?, budget=?, status=? WHERE id=?");
            $stmt->bind_param('ssssdsi', $name, $date, $loc, $desc, $budget, $status, $id);
            $stmt->execute(); $stmt->close();
            fin_out(['success' => true, 'id' => $id, 'message' => 'Event updated.']);
        }
        $stmt = $conn->prepare("INSERT INTO event_accounts (name, event_date, location, description, budget, status, created_by) VALUES (?,?,?,?,?,?,?)");
        $stmt->bind_param('ssssdsi', $name, $date, $loc, $desc, $budget, $status, $actor['id']);
        $stmt->execute();
        $newId = $stmt->insert_id; $stmt->close();
        fin_out(['success' => true, 'id' => $newId, 'message' => 'Event created.']);
    }

    case 'get': {
        $id = (int) fin_in('id', 0);
        $stmt = $conn->prepare("SELECT * FROM event_accounts WHERE id=?");
        $stmt->bind_param('i', $id); $stmt->execute();
        $ev = $stmt->get_result()->fetch_assoc(); $stmt->close();
        if (!$ev) fin_out(['success' => false, 'message' => 'Event not found.']);

        $expenses = [];
        $r = $conn->query("SELECT * FROM event_expenses WHERE event_id=$id ORDER BY expense_date DESC, id DESC");
        while ($r && $row = $r->fetch_assoc()) $expenses[] = $row;

        $parts = [];
        $r = $conn->query("SELECT * FROM event_participants WHERE event_id=$id ORDER BY student_name");
        while ($r && $row = $r->fetch_assoc()) $parts[] = $row;

        fin_out([
            'success' => true, 'event' => $ev, 'expenses' => $expenses,
            'participants' => $parts, 'summary' => finance_event_summary($conn, $id),
        ]);
    }

    case 'add_expense': {
        $eventId = (int) fin_in('event_id', 0);
        $date    = trim((string) fin_in('expense_date', ''));
        $cat     = trim((string) fin_in('category', ''));
        $desc    = trim((string) fin_in('description', ''));
        $amount  = (float) fin_in('amount', 0);
        $vendor  = trim((string) fin_in('vendor', ''));
        $method  = trim((string) fin_in('payment_method', 'cash'));
        if (!$eventId || $date === '' || $cat === '' || $desc === '' || $amount <= 0) {
            fin_out(['success' => false, 'message' => 'Complete all cost fields.']);
        }
        $stmt = $conn->prepare("INSERT INTO event_expenses (event_id, expense_date, category, description, amount, vendor, payment_method, created_by) VALUES (?,?,?,?,?,?,?,?)");
        $stmt->bind_param('isssdssi', $eventId, $date, $cat, $desc, $amount, $vendor, $method, $actor['id']);
        $stmt->execute(); $stmt->close();
        fin_out(['success' => true, 'message' => 'Cost added.', 'summary' => finance_event_summary($conn, $eventId)]);
    }

    // Search active students to add as participants.
    case 'search_students': {
        $q = trim((string) fin_in('q', ''));
        $like = '%' . $q . '%';
        $stmt = $conn->prepare("SELECT id, student_id, first_name, last_name, class
            FROM students WHERE status='active' AND (CONCAT(first_name,' ',last_name) LIKE ? OR student_id LIKE ? OR class LIKE ?)
            ORDER BY first_name, last_name LIMIT 25");
        $stmt->bind_param('sss', $like, $like, $like);
        $stmt->execute();
        $res = $stmt->get_result();
        $rows = [];
        while ($row = $res->fetch_assoc()) {
            $rows[] = [
                'id' => $row['id'],
                'label' => $row['first_name'] . ' ' . $row['last_name'] . ' (' . $row['class'] . ')',
                'class' => $row['class'],
                'name' => $row['first_name'] . ' ' . $row['last_name'],
            ];
        }
        $stmt->close();
        fin_out(['success' => true, 'data' => $rows]);
    }

    // Bill one or more students (adds/updates participant charge on their event ledger).
    case 'add_participants': {
        $eventId  = (int) fin_in('event_id', 0);
        $ids      = fin_in('student_ids', '');   // comma-separated
        $charge   = (float) fin_in('amount_charged', 0);
        $idList   = array_filter(array_map('intval', explode(',', (string) $ids)));
        if (!$eventId || empty($idList)) fin_out(['success' => false, 'message' => 'Select at least one student.']);

        $added = 0;
        foreach ($idList as $sid) {
            $s = $conn->prepare("SELECT first_name, last_name, class FROM students WHERE id=?");
            $s->bind_param('i', $sid); $s->execute();
            $stu = $s->get_result()->fetch_assoc(); $s->close();
            if (!$stu) continue;
            $name = $stu['first_name'] . ' ' . $stu['last_name'];
            $cls  = $stu['class'];
            $ins = $conn->prepare("INSERT INTO event_participants (event_id, student_id, student_name, class_name, amount_charged)
                VALUES (?,?,?,?,?)
                ON DUPLICATE KEY UPDATE amount_charged = VALUES(amount_charged), student_name = VALUES(student_name), class_name = VALUES(class_name)");
            $ins->bind_param('iissd', $eventId, $sid, $name, $cls, $charge);
            $ins->execute(); $ins->close();
            $added++;
        }
        fin_out(['success' => true, 'message' => "$added participant(s) billed.", 'summary' => finance_event_summary($conn, $eventId)]);
    }

    // Record a participant payment against their event charge.
    case 'record_payment': {
        $pid    = (int) fin_in('participant_id', 0);
        $amount = (float) fin_in('amount', 0);
        if (!$pid || $amount <= 0) fin_out(['success' => false, 'message' => 'Enter a positive amount.']);
        $stmt = $conn->prepare("SELECT event_id, amount_charged, amount_paid FROM event_participants WHERE id=?");
        $stmt->bind_param('i', $pid); $stmt->execute();
        $p = $stmt->get_result()->fetch_assoc(); $stmt->close();
        if (!$p) fin_out(['success' => false, 'message' => 'Participant not found.']);
        $newPaid = (float) $p['amount_paid'] + $amount;
        $stmt = $conn->prepare("UPDATE event_participants SET amount_paid=? WHERE id=?");
        $stmt->bind_param('di', $newPaid, $pid); $stmt->execute(); $stmt->close();
        fin_out(['success' => true, 'message' => 'Payment recorded.', 'summary' => finance_event_summary($conn, (int) $p['event_id'])]);
    }

    case 'remove_participant': {
        $pid = (int) fin_in('participant_id', 0);
        $stmt = $conn->prepare("SELECT event_id FROM event_participants WHERE id=?");
        $stmt->bind_param('i', $pid); $stmt->execute();
        $p = $stmt->get_result()->fetch_assoc(); $stmt->close();
        if ($p) $conn->query("DELETE FROM event_participants WHERE id=" . $pid);
        fin_out(['success' => true, 'message' => 'Removed.', 'summary' => $p ? finance_event_summary($conn, (int) $p['event_id']) : null]);
    }

    default:
        fin_out(['success' => false, 'message' => 'Unknown action.']);
}
