<?php
/** Bootstrap ringan untuk pengujian CLI. */
define('SIPIUTANG_ROOT', dirname(__DIR__));
spl_autoload_register(function (string $class): void {
    if (!str_starts_with($class, 'App\\')) return;
    $file = SIPIUTANG_ROOT . '/app/' . str_replace('\\', '/', substr($class, 4)) . '.php';
    if (is_file($file)) require $file;
});
require SIPIUTANG_ROOT . '/app/Helpers/functions.php';

use App\Core\Config;
use App\Core\Database;
use App\Core\Settings;

Config::set('app.timezone', 'Asia/Jakarta');
Config::set('app.key', 'test-key');
Config::set('paths.logs', SIPIUTANG_ROOT . '/storage/logs');
date_default_timezone_set('Asia/Jakarta');

if (getenv('SKIP_DB') !== '1') {
    Database::init([
        'host' => '127.0.0.1', 'port' => 3306,
        'database' => getenv('DB_NAME') ?: 'sipiutang',
        'username' => getenv('DB_USER') ?: 'sipiutang',
        'password' => getenv('DB_PASS') ?: 'sipiutang123',
        'charset' => 'utf8mb4',
    ]);
    Settings::load();
}

function ok($a, ?string $msg = null): void
{
    if ($msg !== null) { $a ? ok($msg) : bad($msg); return; }
    echo "  \033[32m✓\033[0m " . (string)$a . "\n";
}
function bad(string $msg): void  { echo "  \033[31m✗\033[0m $msg\n"; $GLOBALS['_fail'] = ($GLOBALS['_fail'] ?? 0) + 1; }
function head(string $msg): void { echo "\n\033[1;36m== $msg\033[0m\n"; }
function assertTrue($cond, string $msg): void { $cond ? ok($msg) : bad($msg); }
function assertEq($a, $b, string $msg): void
{
    if (is_float($a) || is_float($b)) { $same = abs((float)$a - (float)$b) < 0.02; }
    else { $same = ((string)$a === (string)$b); }
    $same ? ok("$msg  ($a)") : bad("$msg  — diharapkan: " . var_export($b, true) . ", diperoleh: " . var_export($a, true));
}
function summary(): void
{
    $f = $GLOBALS['_fail'] ?? 0;
    echo "\n" . ($f === 0 ? "\033[1;32mSEMUA PENGUJIAN LULUS\033[0m\n" : "\033[1;31m$f PENGUJIAN GAGAL\033[0m\n");
    exit($f === 0 ? 0 : 1);
}

/** Alias judul bagian (semantik Indonesia). */
function section(string $msg): void { head($msg); }
/** Assert dengan urutan (diharapkan, diperoleh). */
function eq($expected, $actual, string $msg): void
{
    if (is_float($expected) || is_float($actual)) { $same = abs((float)$expected - (float)$actual) < 0.02; }
    else { $same = ((string)$expected === (string)$actual); }
    $same ? ok("$msg  (" . (is_bool($actual) ? var_export($actual, true) : $actual) . ")")
          : bad("$msg  — diharapkan: " . var_export($expected, true) . ", diperoleh: " . var_export($actual, true));
}
