<?php
/**
 * PettyCashBoxController — Slice 8Z-e · Batch 3
 *
 * Single-box surface for Accountant + FM. Path A of the cash disbursement fork —
 * small APPROVED internal-cash LPOs get paid straight from the tin instead of
 * drafting a PV. Every movement is logged; low-water breaches ping FM.
 *
 * Endpoints:
 *   /PettyCashBox                       GET  — box card (balance, float, config summary)
 *   /PettyCashBox/movements             GET  — paged movement log (filter by type)
 *   /PettyCashBox/disburseAj            POST — disburse an APPROVED LPO from the box
 *   /PettyCashBox/replenishAj           POST — top-up (bank → tin)
 *   /PettyCashBox/adjustmentAj          POST — manual over/short correction (FM)
 *   /PettyCashBox/configAj              POST — edit float / max disbursement / threshold (FM)
 */
class PettyCashBoxController extends Controller
{
    public function indexAction()
    {
        $m   = new PettyCashBox();
        $box = $m->primary();
        $recent = $m->movements(20);

        $this->view->setLayout($this->roleLayout());
        $this->view->render('PettyCashBox/index', [
            'page_title' => 'Petty Cash Box',
            'box'        => $box,
            'recent'     => $recent,
            'can_config' => in_array(strtolower($this->currentUserGroup()), ['finance manager','administrator'], true),
        ]);
    }

    public function movementsAction()
    {
        $type = (string)($_GET['type'] ?? '');
        $rows = (new PettyCashBox())->movements(500, 0, $type);
        $box  = (new PettyCashBox())->primary();

        $this->view->setLayout($this->roleLayout());
        $this->view->render('PettyCashBox/movements', [
            'page_title'  => 'Petty Cash · Movements',
            'rows'        => $rows,
            'box'         => $box,
            'filter_type' => $type,
        ]);
    }

    public function disburseAjAction()
    {
        header('Content-Type: application/json');
        try {
            $lpoId = (int)($_POST['lpo_id'] ?? 0);
            if ($lpoId <= 0) throw new InvalidArgumentException('lpo_id required.');
            $r = (new PettyCashBox())->disburse($lpoId, $this->currentUserId(), $_SESSION['full_name'] ?? '');
            echo json_encode($r);
        } catch (\Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    public function replenishAjAction()
    {
        header('Content-Type: application/json');
        try {
            $amount = (float)($_POST['amount'] ?? 0);
            $narr   = (string)($_POST['narrative'] ?? '');
            if ($amount <= 0) throw new InvalidArgumentException('Amount must be > 0.');
            $r = (new PettyCashBox())->replenish($amount, $narr, $this->currentUserId(), $_SESSION['full_name'] ?? '');
            echo json_encode($r);
        } catch (\Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    public function adjustmentAjAction()
    {
        header('Content-Type: application/json');
        try {
            // Signed amount: negative for a shortage, positive for an overage.
            $amount = (float)($_POST['amount'] ?? 0);
            $narr   = (string)($_POST['narrative'] ?? '');
            $r = (new PettyCashBox())->adjustment($amount, $narr, $this->currentUserId(), $_SESSION['full_name'] ?? '');
            echo json_encode($r);
        } catch (\Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    public function configAjAction()
    {
        header('Content-Type: application/json');
        try {
            $d = [
                'name'             => $_POST['name']             ?? null,
                'custodian_id'     => $_POST['custodian_id']     ?? null,
                'custodian_name'   => $_POST['custodian_name']   ?? null,
                'float_amount'     => $_POST['float_amount']     ?? null,
                'max_disbursement' => $_POST['max_disbursement'] ?? null,
                'low_water_pct'    => $_POST['low_water_pct']    ?? null,
            ];
            $r = (new PettyCashBox())->updateConfig($d, $this->currentUserId());
            echo json_encode($r);
        } catch (\Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }
}
