<?php

declare(strict_types=1);

use Budget\ExportService;

$databasePath = sys_get_temp_dir() . '/neon-ledger-self-test-' . getmypid() . '.sqlite';
putenv('BUDGET_SQLITE_PATH=' . $databasePath);

register_shutdown_function(static function () use ($databasePath): void {
    foreach ([$databasePath, $databasePath . '-shm', $databasePath . '-wal'] as $file) {
        if (is_file($file)) {
            unlink($file);
        }
    }
});

require __DIR__ . '/../app/bootstrap.php';

$assert = static function (bool $condition, string $message): void {
    if (!$condition) {
        throw new RuntimeException($message);
    }
};

$settings->set('dead.income_mode', 'percent');
$settings->set('dead.income_value', 10);
$settings->set('dead.transaction_mode', 'fixed');
$settings->set('dead.transaction_value', 1);

$budget->savePlan('2026-01', 1000, 0, true, 'Self-test');
$categoryId = $budget->addCategory('Utilities', '#49a8ff', 200);
$itemId = $budget->addBudgetItem('2026-01', $categoryId, 'Internet', 55, '2026-01-20', 'monthly', '');
$transactionId = $budget->addTransaction('2026-01', $itemId, null, 'Internet payment', 10, '2026-01-10', '');

$january = $budget->summary('2026-01');
$assert(abs($january['remaining'] - 889) < 0.001, 'January remaining balance is incorrect.');
$assert(abs($budget->budgetItems('2026-01')[0]['remaining_amount'] - 45) < 0.001, 'Target progress is incorrect.');

$budget->updateTransaction($transactionId, '2026-01', $itemId, null, 'Internet payment', 20, '2026-01-10', '');
$budget->moveDeadAccount('2026-01', 'restore', 50, '', 'item', $itemId);
$january = $budget->summary('2026-01');
$assert(abs($january['remaining'] - 929) < 0.001, 'Dormant restoration accounting is incorrect.');
$assert(abs($budget->deadBalance() - 51) < 0.001, 'Dormant balance is incorrect.');

$february = $budget->ensureMonth('2026-02');
$februaryItems = $budget->budgetItems('2026-02');
$assert(abs((float) $february['rollover_in'] - 929) < 0.001, 'Rolling budget did not carry the remainder forward.');
$assert(count($februaryItems) === 1 && $februaryItems[0]['name'] === 'Internet', 'Recurring target was not materialized.');

$year = $budget->yearlySummary(2026);
$assert(abs($year['totals']['fresh_income'] - 1000) < 0.001, 'Yearly income double-counted rollover.');

$exporter = new ExportService($pdo, $settings, $budget);
$package = json_decode($exporter->package(), true);
$assert(($package['format'] ?? null) === 'neon-ledger/budget-planner', 'JSON package format is invalid.');
$assert(str_contains($exporter->html('2026-01'), 'Internet'), 'HTML export is missing target data.');
$assert(str_starts_with($exporter->pdf('2026-01'), '%PDF-1.4'), 'PDF export is invalid.');

echo "Neon Ledger self-test passed.\n";
