<?php
// POST /api/cashflow/expenses.php
// action: add | update | delete | toggle_paid | match_slip | unmatch_slip | accept_slip
require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/../config/auth.php';

$user    = requireAuth();
$db      = getDB();
$action  = post('action', 'add');

function assertActive(PDO $db, int $monthId): void {
    $s = $db->prepare("SELECT status FROM cashflow_months WHERE id = ? LIMIT 1");
    $s->execute([$monthId]);
    $m = $s->fetch();
    if (!$m || $m['status'] === 'closed') apiError('This month is closed and cannot be edited.', 403);
}

if ($action === 'add') {
    $monthId = (int)post('month_id', 0);
    assertActive($db, $monthId);
    $db->prepare("INSERT INTO cashflow_expenses (month_id, type, description, category, expected_amount, actual_amount, is_recurring, recur_end_month, is_payroll)
        VALUES (?,?,?,?,?,?,?,?,?)")
       ->execute([
           $monthId,
           post('type', 'planned'),
           post('description', ''),
           post('category') ?: null,
           post('expected_amount') ?: null,
           post('actual_amount') ?: null,
           post('is_recurring', 0),
           post('recur_end_month') ?: null,
           post('is_payroll', 0),
       ]);
    apiSuccess(['id' => (int)$db->lastInsertId()], 'Expense added.');
}

if ($action === 'update') {
    $id      = (int)post('id', 0);
    $monthId = (int)post('month_id', 0);
    assertActive($db, $monthId);
    $db->prepare("UPDATE cashflow_expenses SET type=?, description=?, category=?, expected_amount=?, actual_amount=?, is_recurring=?, recur_end_month=? WHERE id=? AND month_id=?")
       ->execute([
           post('type', 'planned'),
           post('description', ''),
           post('category') ?: null,
           post('expected_amount') ?: null,
           post('actual_amount') ?: null,
           post('is_recurring', 0),
           post('recur_end_month') ?: null,
           $id, $monthId
       ]);
    apiSuccess([], 'Updated.');
}

if ($action === 'delete') {
    $id      = (int)post('id', 0);
    $monthId = (int)post('month_id', 0);
    assertActive($db, $monthId);
    $db->prepare("DELETE FROM cashflow_expenses WHERE id=? AND month_id=? AND is_payroll=0")->execute([$id, $monthId]);
    apiSuccess([], 'Deleted.');
}

if ($action === 'toggle_paid') {
    $id      = (int)post('id', 0);
    $monthId = (int)post('month_id', 0);
    assertActive($db, $monthId);
    $cur = $db->prepare("SELECT is_paid FROM cashflow_expenses WHERE id=? LIMIT 1");
    $cur->execute([$id]);
    $row    = $cur->fetch();
    $newVal = $row ? ($row['is_paid'] ? 0 : 1) : 1;
    $db->prepare("UPDATE cashflow_expenses SET is_paid=?, paid_date=? WHERE id=? AND month_id=?")
       ->execute([$newVal, $newVal ? date('Y-m-d') : null, $id, $monthId]);
    apiSuccess(['is_paid' => $newVal], 'Toggled.');
}

// Match an existing expense line to a slip
if ($action === 'match_slip') {
    $id      = (int)post('id', 0);
    $slipId  = (int)post('slip_id', 0);
    $monthId = (int)post('month_id', 0);
    assertActive($db, $monthId);
    // Get slip amount to set as actual
    $slip = $db->prepare("SELECT amount FROM slips WHERE id=? LIMIT 1");
    $slip->execute([$slipId]);
    $slipRow = $slip->fetch();
    $db->prepare("UPDATE cashflow_expenses SET slip_id=?, actual_amount=?, is_paid=1, paid_date=? WHERE id=? AND month_id=?")
       ->execute([$slipId, $slipRow['amount'] ?? null, date('Y-m-d'), $id, $monthId]);
    apiSuccess([], 'Slip matched.');
}

if ($action === 'unmatch_slip') {
    $id      = (int)post('id', 0);
    $monthId = (int)post('month_id', 0);
    assertActive($db, $monthId);
    $db->prepare("UPDATE cashflow_expenses SET slip_id=NULL, actual_amount=NULL WHERE id=? AND month_id=?")
       ->execute([$id, $monthId]);
    apiSuccess([], 'Slip unmatched.');
}

// Accept an unmatched slip as a new actual expense line
if ($action === 'accept_slip') {
    $slipId  = (int)post('slip_id', 0);
    $monthId = (int)post('month_id', 0);
    assertActive($db, $monthId);
    $slip = $db->prepare("SELECT * FROM slips WHERE id=? LIMIT 1");
    $slip->execute([$slipId]);
    $s = $slip->fetch();
    if (!$s) apiError('Slip not found.', 404);
    $db->prepare("INSERT INTO cashflow_expenses (month_id, type, description, category, actual_amount, slip_id, is_paid, paid_date)
        VALUES (?,?,?,?,?,?,1,?)")
       ->execute([$monthId, 'actual', $s['merchant'] ?: $s['description'] ?: 'Slip',
                  $s['category'], $s['amount'], $slipId, $s['slip_date']]);
    apiSuccess(['id' => (int)$db->lastInsertId()], 'Slip accepted as expense.');
}

apiError('Unknown action.', 422);