<?php
/** Expenditure requests — create / list / detail. */
require_once __DIR__ . '/_boot.php';

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

switch ($action) {

    // Create a new expenditure request (optionally with receipt uploads).
    case 'create': {
        $expense_date = trim((string) fin_in('expense_date', ''));
        $category     = trim((string) fin_in('category', ''));
        $description  = 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'));
        $event_id     = (int) fin_in('event_id', 0) ?: null;

        if ($expense_date === '' || $category === '' || $description === '' || $amount <= 0) {
            fin_out(['success' => false, 'message' => 'Please complete date, category, description and a positive amount.']);
        }

        $request_no = finance_next_request_no($conn);
        $stmt = $conn->prepare("INSERT INTO expense_requests
            (request_no, requester_id, requester_name, expense_date, category, description, amount, vendor, payment_method, event_id, status, current_step)
            VALUES (?,?,?,?,?,?,?,?,?,?, 'pending', 0)");
        // types: request_no(s) id(i) name(s) date(s) category(s) description(s) amount(d) vendor(s) method(s) event_id(i)
        $stmt->bind_param('sissssdssi',
            $request_no, $actor['id'], $actor['name'], $expense_date, $category,
            $description, $amount, $vendor, $method, $event_id);
        if (!$stmt->execute()) {
            $err = $stmt->error; $stmt->close();
            fin_out(['success' => false, 'message' => 'Could not save request: ' . $err]);
        }
        $rid = $stmt->insert_id;
        $stmt->close();

        // Optional receipt files submitted with the form (name="receipts[]").
        $saved = 0;
        if (!empty($_FILES['receipts']) && is_array($_FILES['receipts']['name'])) {
            foreach ($_FILES['receipts']['name'] as $i => $name) {
                $file = [
                    'name'     => $_FILES['receipts']['name'][$i],
                    'type'     => $_FILES['receipts']['type'][$i],
                    'tmp_name' => $_FILES['receipts']['tmp_name'][$i],
                    'error'    => $_FILES['receipts']['error'][$i],
                    'size'     => $_FILES['receipts']['size'][$i],
                ];
                if (($file['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_NO_FILE) continue;
                $err = null;
                $path = finance_save_receipt($file, $err);
                if ($path) {
                    $orig = mb_substr((string) $file['name'], 0, 200);
                    $mime = (string) (new finfo(FILEINFO_MIME_TYPE))->file(($file['tmp_name']));
                    $size = (int) $file['size'];
                    $ins = $conn->prepare("INSERT INTO expense_attachments
                        (request_id, file_path, original_name, mime, size, uploaded_by, uploaded_by_name)
                        VALUES (?,?,?,?,?,?,?)");
                    $ins->bind_param('isssiis', $rid, $path, $orig, $mime, $size, $actor['id'], $actor['name']);
                    $ins->execute(); $ins->close();
                    $saved++;
                }
            }
        }

        // Notify the first approver's role holders (best-effort SMS).
        finance_notify_next_approver($conn, $rid);

        fin_out(['success' => true, 'message' => "Request {$request_no} submitted." . ($saved ? " {$saved} receipt(s) attached." : ''), 'id' => $rid, 'request_no' => $request_no]);
    }

    // List requests. Scope: 'mine' (default) or 'all' (finance managers).
    case 'list': {
        $scope = fin_in('scope', 'mine');
        $canSeeAll = in_array($actor['role'], ['admin', 'accountant', 'headteacher', 'supervisor', 'director'], true);
        if ($scope === 'all' && $canSeeAll) {
            $res = $conn->query("SELECT * FROM expense_requests ORDER BY id DESC LIMIT 300");
        } else {
            $stmt = $conn->prepare("SELECT * FROM expense_requests WHERE requester_id = ? ORDER BY id DESC LIMIT 300");
            $stmt->bind_param('i', $actor['id']);
            $stmt->execute();
            $res = $stmt->get_result();
        }
        $rows = [];
        while ($res && $row = $res->fetch_assoc()) {
            $row['step_label'] = finance_step_label($conn, $row);
            $rows[] = $row;
        }
        fin_out(['success' => true, 'data' => $rows, 'can_see_all' => $canSeeAll]);
    }

    // Full detail: request + approval trail + attachments + matrix progress.
    case 'get': {
        $id = (int) fin_in('id', 0);
        $stmt = $conn->prepare("SELECT * FROM expense_requests WHERE id = ?");
        $stmt->bind_param('i', $id);
        $stmt->execute();
        $req = $stmt->get_result()->fetch_assoc();
        $stmt->close();
        if (!$req) fin_out(['success' => false, 'message' => 'Request not found.']);

        $log = [];
        $lr = $conn->prepare("SELECT * FROM expense_approval_log WHERE request_id = ? ORDER BY id");
        $lr->bind_param('i', $id); $lr->execute();
        $res = $lr->get_result();
        while ($row = $res->fetch_assoc()) $log[] = $row;
        $lr->close();

        $att = [];
        $ar = $conn->prepare("SELECT id, file_path, original_name, mime, uploaded_by_name, created_at FROM expense_attachments WHERE request_id = ? ORDER BY id");
        $ar->bind_param('i', $id); $ar->execute();
        $res = $ar->get_result();
        while ($row = $res->fetch_assoc()) $att[] = $row;
        $ar->close();

        $required = finance_required_steps($conn, (float) $req['amount']);
        fin_out([
            'success'     => true,
            'request'     => $req,
            'log'         => $log,
            'attachments' => $att,
            'required'    => $required,
            'can_approve' => finance_can_approve($conn, $req, $actor['role']),
            'can_disburse'=> $req['status'] === 'approved' && in_array($actor['role'], ['admin','accountant'], true),
        ]);
    }

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

// ── local helpers ─────────────────────────────────────────────────────────

/** Short label for a request's current position in the workflow. */
function finance_step_label(mysqli $conn, array $req): string
{
    if ($req['status'] === 'approved')  return 'Approved';
    if ($req['status'] === 'rejected')  return 'Rejected';
    if ($req['status'] === 'disbursed') return 'Disbursed';
    $step = finance_current_required_step($conn, $req);
    return $step ? ('Awaiting ' . $step['label']) : 'Pending';
}

/** Best-effort SMS to the school line announcing the pending approval. */
function finance_notify_next_approver(mysqli $conn, int $rid): void
{
    $stmt = $conn->prepare("SELECT * FROM expense_requests WHERE id = ?");
    $stmt->bind_param('i', $rid); $stmt->execute();
    $req = $stmt->get_result()->fetch_assoc(); $stmt->close();
    if (!$req) return;
    $step = finance_current_required_step($conn, $req);
    if (!$step) return;
    if (!function_exists('sendSMS')) return;
    $school = function_exists('getSettingValue') ? (getSettingValue('school_name') ?: 'the school') : 'the school';
    $phone  = function_exists('getSettingValue') ? getSettingValue('school_phone') : '';
    if (!$phone) return;
    $amt = function_exists('formatCurrency') ? formatCurrency((float) $req['amount']) : $req['amount'];
    $msg = "New expenditure request {$req['request_no']} ({$amt} — {$req['category']}) awaits {$step['label']} approval. — {$school}";
    @sendSMS($phone, $msg);
}
