<?php
// ============================================================
//  MediCore — Accounts API (Expenses + Incomes)
//  File: api/accounts.php
//  Both tables sync automatically to cash_ledger
// ============================================================
require_once '../includes/db.php';
require_once '../includes/auth.php';
require_login();

header('Content-Type: application/json');

// ── Defensive migration: track which user recorded each expense ────
// Needed for the Reporting Engine's "who made this operation" fields
// (includes/reporting.php). Older databases won't have this column.
try {
    $hasCreatedBy = db_val(
        "SELECT COUNT(*) FROM information_schema.COLUMNS
          WHERE TABLE_SCHEMA = DATABASE()
            AND TABLE_NAME   = 'expenses'
            AND COLUMN_NAME  = 'created_by'"
    );
    if (!$hasCreatedBy) {
        db_run("ALTER TABLE expenses ADD COLUMN created_by INT UNSIGNED DEFAULT NULL AFTER ref");
    }
} catch (Throwable $e) { /* best-effort */ }

ensure_sync_tables();

$body   = json_decode(file_get_contents('php://input'), true) ?? [];
$action = trim($body['action'] ?? '');

try {
    match($action) {
        'list'   => api_list($body),
        'add'    => api_add($body),
        'delete' => api_delete($body),
        default  => fail('Unknown action')
    };
} catch (Throwable $e) {
    fail($e->getMessage());
}

// ── List ──────────────────────────────────────────────────────
function api_list(array $b): void {
    $type   = trim($b['type'] ?? 'exp');
    $table  = $type === 'exp' ? 'expenses' : 'incomes';
    $where  = ['1=1'];
    $params = [];

    $cat  = trim($b['cat']  ?? '');
    $from = trim($b['from'] ?? '');
    $to   = trim($b['to']   ?? '');
    $q    = trim($b['q']    ?? '');

    if ($cat)  { $where[] = "category = ?";     $params[] = $cat; }
    if ($from) { $where[] = "date >= ?";         $params[] = $from; }
    if ($to)   { $where[] = "date <= ?";         $params[] = $to; }
    if ($q)    {
        $where[]  = "(description LIKE ? OR category LIKE ?)";
        $params[] = "%$q%"; $params[] = "%$q%";
    }

    $wSql = implode(' AND ', $where);
    $rows = db_rows(
        "SELECT * FROM `$table` WHERE $wSql ORDER BY date DESC, id DESC",
        $params
    );
    ok(['data' => $rows]);
}

// ── Add ───────────────────────────────────────────────────────
function api_add(array $b): void {
    $type   = trim($b['type']    ?? 'exp');
    $cat    = trim($b['cat']     ?? 'Misc');
    $account= trim($b['account'] ?? 'Cash');
    $desc   = trim($b['desc']    ?? '');
    $amount = (float)($b['amount'] ?? 0);
    $date   = trim($b['date']    ?? date('Y-m-d'));

    $table  = $type === 'exp' ? 'expenses' : 'incomes';
    $ledgerType = $type === 'exp' ? 'out' : 'in';

    if (!$desc)       fail('Description is required');
    if ($amount <= 0) fail('Amount must be greater than zero');

    $validAccounts = ['Cash','Card','Bank','MFS'];
    if (!in_array($account, $validAccounts)) fail('Invalid account');

    // Validate category
    $expCats = ['Rent','Salary','Utilities','Marketing',
                'Transport','Maintenance','Misc'];
    $incCats = ['Sale Revenue','Due Collected','Investment','Refund','Other'];
    $allCats = array_merge($expCats, $incCats);
    if (!in_array($cat, $allCats)) fail('Invalid category');

    db()->beginTransaction();
    try {
        // 1. Insert into expenses or incomes table
        if ($type === 'exp') {
            $id = db_insert(
                "INSERT INTO expenses
                   (category, description, amount, account, date, created_by)
                 VALUES (?,?,?,?,?,?)",
                [$cat, $desc, $amount, $account, $date, current_user_id()]
            );
        } else {
            $id = db_insert(
                "INSERT INTO incomes
                   (category, description, amount, account, date)
                 VALUES (?,?,?,?,?)",
                [$cat, $desc, $amount, $account, $date]
            );
        }

        // 2. Sync to cash_ledger automatically
        $ref = ($type === 'exp' ? 'EXP' : 'INC') . '-' . $id;
        $ledgerId = db_insert(
            "INSERT INTO cash_ledger
               (date, description, account, type, amount, ref)
             VALUES (?, ?, ?, ?, ?, ?)",
            [$date, "$cat — $desc", $account, $ledgerType, $amount, $ref]
        );

        enqueue_sync($table, $id, 'INSERT', db_row("SELECT * FROM `$table` WHERE id = ?", [$id]));
        enqueue_sync('cash_ledger', $ledgerId, 'INSERT',
            db_row("SELECT * FROM cash_ledger WHERE id = ?", [$ledgerId]));

        db()->commit();
        ok(['id' => $id, 'msg' => ucfirst($type === 'exp' ? 'Expense' : 'Income') . ' added']);

    } catch (Throwable $e) {
        db()->rollBack();
        fail('Save failed: ' . $e->getMessage());
    }
}

// ── Delete ────────────────────────────────────────────────────
function api_delete(array $b): void {
    require_admin();
    $id   = (int)($b['id']   ?? 0);
    $type = trim($b['type']  ?? 'exp');
    if (!$id) fail('Missing id');

    $table  = $type === 'exp' ? 'expenses' : 'incomes';
    $prefix = $type === 'exp' ? 'EXP'      : 'INC';

    $row = db_row("SELECT * FROM `$table` WHERE id = ?", [$id]);
    if (!$row) fail('Entry not found');

    db()->beginTransaction();
    try {
        $ledgerRow = db_row("SELECT id FROM cash_ledger WHERE ref = ?", ["$prefix-$id"]);
        db_run("DELETE FROM `$table` WHERE id = ?", [$id]);
        db_run(
            "DELETE FROM cash_ledger WHERE ref = ?",
            ["$prefix-$id"]
        );
        enqueue_sync($table, $id, 'DELETE');
        if ($ledgerRow) enqueue_sync('cash_ledger', (int)$ledgerRow['id'], 'DELETE');
        db()->commit();
        ok(['msg' => 'Entry deleted']);
    } catch (Throwable $e) {
        db()->rollBack();
        fail('Delete failed: ' . $e->getMessage());
    }
}

function ok(array $extra = []): void {
    echo json_encode(array_merge(['success' => true], $extra));
    exit;
}
function fail(string $msg): never {
    echo json_encode(['success' => false, 'error' => $msg]);
    exit;
}
