<?php

require_once __DIR__ . '/../includes/api_bootstrap.php';
require_once __DIR__ . '/../includes/family_settings.php';
require_once __DIR__ . '/../includes/banking_helpers.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    sendJson(['success' => false, 'error' => 'Method not allowed'], 405);
}

$people = migrateAllPeople(normalizePeopleList(readJsonFile('people.json')));
$actor = requireActivePerson($people);
if (($actor['role'] ?? '') !== ROLE_HEAD || !isHohVerified()) {
    sendJson(['success' => false, 'error' => 'Only a verified Head of household can reverse transactions'], 403);
}
$settings = loadFamilySettings();
if (!bankingEnabled($settings)) {
    sendJson(['success' => false, 'error' => 'Banking mode is not enabled'], 400);
}
$people = bankingApplySavingsInterestToPeople($people, $settings);
$body = readJsonBody();
$transactionId = trim((string) ($body['transaction_id'] ?? ''));
$note = trim((string) ($body['note'] ?? ''));
if ($transactionId === '') {
    sendJson(['success' => false, 'error' => 'transaction_id is required'], 400);
}

$rows = readJsonFile('bank_transactions.json');
if (!is_array($rows)) {
    $rows = [];
}
$original = null;
foreach ($rows as $row) {
    if (is_array($row) && (($row['id'] ?? '') === $transactionId)) {
        $original = $row;
        break;
    }
}
if ($original === null) {
    sendJson(['success' => false, 'error' => 'Transaction not found'], 404);
}
if (!empty($original['reversed_by_transaction_id'])) {
    sendJson(['success' => false, 'error' => 'Transaction already reversed'], 400);
}
if (($original['type'] ?? '') === 'reversal') {
    sendJson(['success' => false, 'error' => 'Cannot reverse a reversal transaction'], 400);
}

$personId = (string) ($original['person_id'] ?? '');
$idx = null;
foreach ($people as $i => $p) {
    if (($p['id'] ?? '') === $personId) {
        $idx = $i;
        break;
    }
}
if ($idx === null) {
    sendJson(['success' => false, 'error' => 'Person for original transaction not found'], 404);
}

$type = (string) ($original['type'] ?? '');
$amount = bankingRoundMoney((float) ($original['amount'] ?? 0));
if ($amount <= 0) {
    sendJson(['success' => false, 'error' => 'Original transaction amount is invalid'], 400);
}

if ($type === 'manual_credit' || $type === 'income_chore') {
    $alloc = is_array($original['allocations'] ?? null) ? $original['allocations'] : [];
    $ck = (float) ($alloc['checking'] ?? 0);
    $sv = (float) ($alloc['savings'] ?? 0);
    $ch = (float) ($alloc['charity'] ?? 0);
    if ((float) $people[$idx]['checking_balance'] < $ck || (float) $people[$idx]['savings_balance'] < $sv || (float) $people[$idx]['charity_pending_balance'] < $ch) {
        sendJson(['success' => false, 'error' => 'Insufficient balances to reverse this credit'], 400);
    }
    $people[$idx]['checking_balance'] = bankingRoundMoney((float) $people[$idx]['checking_balance'] - $ck);
    $people[$idx]['savings_balance'] = bankingRoundMoney((float) $people[$idx]['savings_balance'] - $sv);
    $people[$idx]['charity_pending_balance'] = bankingRoundMoney((float) $people[$idx]['charity_pending_balance'] - $ch);
} elseif ($type === 'manual_debit') {
    $people[$idx]['checking_balance'] = bankingRoundMoney((float) $people[$idx]['checking_balance'] + $amount);
} elseif ($type === 'charity_outflow') {
    if ((float) $people[$idx]['charity_donated_total'] < $amount) {
        sendJson(['success' => false, 'error' => 'Insufficient donated total to reverse outflow'], 400);
    }
    $people[$idx]['charity_donated_total'] = bankingRoundMoney((float) $people[$idx]['charity_donated_total'] - $amount);
    $people[$idx]['charity_pending_balance'] = bankingRoundMoney((float) $people[$idx]['charity_pending_balance'] + $amount);
} elseif ($type === 'transfer') {
    $from = (string) ($original['from_account'] ?? '');
    $to = (string) ($original['to_account'] ?? '');
    $fieldMap = ['checking' => 'checking_balance', 'savings' => 'savings_balance', 'charity' => 'charity_pending_balance'];
    if (!isset($fieldMap[$from], $fieldMap[$to])) {
        sendJson(['success' => false, 'error' => 'Original transfer accounts are invalid'], 400);
    }
    $toField = $fieldMap[$to];
    $fromField = $fieldMap[$from];
    if ((float) $people[$idx][$toField] < $amount) {
        sendJson(['success' => false, 'error' => 'Insufficient balances to reverse this transfer'], 400);
    }
    $people[$idx][$toField] = bankingRoundMoney((float) $people[$idx][$toField] - $amount);
    $people[$idx][$fromField] = bankingRoundMoney((float) $people[$idx][$fromField] + $amount);
} else {
    sendJson(['success' => false, 'error' => 'This transaction type cannot be reversed'], 400);
}
$people[$idx]['currency_balance'] = (float) ($people[$idx]['checking_balance'] ?? 0);

if (!writeJsonFile('people.json', $people)) {
    sendJson(['success' => false, 'error' => 'Failed to save people balances'], 500);
}

$reversalId = bin2hex(random_bytes(8));
for ($i = 0; $i < count($rows); $i++) {
    if (($rows[$i]['id'] ?? '') === $transactionId) {
        $rows[$i]['reversed_by_transaction_id'] = $reversalId;
        $rows[$i]['reversed_at'] = gmdate('c');
        $rows[$i]['reversed_by'] = (string) ($actor['id'] ?? '');
    }
}
$reversal = [
    'id' => $reversalId,
    'type' => 'reversal',
    'person_id' => $personId,
    'amount' => $amount,
    'category' => 'reversal',
    'note' => $note,
    'reversal_of_transaction_id' => $transactionId,
    'created_at' => gmdate('c'),
    'created_by' => (string) ($actor['id'] ?? ''),
];
$rows[] = $reversal;
if (!writeJsonFile('bank_transactions.json', $rows)) {
    sendJson(['success' => false, 'error' => 'Failed to save transaction log'], 500);
}

sendJson(['success' => true, 'transaction' => $reversal, 'person' => $people[$idx]]);
