<?php
declare(strict_types=1);

if (PHP_SAPI !== 'cli') {
    http_response_code(404);
    exit;
}

require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'bootstrap.php';
app_bootstrap();

$cliTimezone = (string) (app_config('site')['timezone'] ?? 'UTC');
date_default_timezone_set(in_array($cliTimezone, DateTimeZone::listIdentifiers(), true) ? $cliTimezone : 'UTC');

use App\Database\Connection;
use App\Database\DatabaseUpgradeService;
use App\Database\Migrator;
use App\Database\SchemaHealthService;

try {
    $pdo = Connection::connect(app_config('database'));
    $migrator = new Migrator($pdo, app_root_path('database', 'migrations'));
    $before = $migrator->applied();
    $result = (new DatabaseUpgradeService($pdo, app_root_path('database', 'migrations')))->upgrade();
    $applied = $result['applied'] ?? [];
    $repaired = $result['repaired'] ?? [];
    $health = is_array($result['health'] ?? null) ? $result['health'] : (new SchemaHealthService($pdo, app_root_path('database', 'migrations')))->inspect();

    fwrite(STDOUT, 'Quaeriva ' . app_version() . PHP_EOL);
    fwrite(STDOUT, 'Previously applied migrations: ' . count($before) . PHP_EOL);
    if ($applied === []) {
        fwrite(STDOUT, "Database migrations are already up to date.\n");
    } else {
        fwrite(STDOUT, "Applied:\n- " . implode("\n- ", $applied) . PHP_EOL);
    }
    if ($repaired !== []) {
        fwrite(STDOUT, "Schema reconciliation replayed:\n- " . implode("\n- ", $repaired) . PHP_EOL);
    }

    if (!($health['healthy'] ?? false)) {
        fwrite(STDERR, "Schema integrity check failed after migration.\n");
        foreach (($health['pending'] ?? []) as $migration) fwrite(STDERR, '- Pending migration: ' . $migration . PHP_EOL);
        foreach (($health['issues'] ?? []) as $issue) fwrite(STDERR, '- ' . $issue . PHP_EOL);
        exit(3);
    }

    fwrite(STDOUT, "Schema integrity: OK\n");
    exit(0);
} catch (Throwable $throwable) {
    fwrite(STDERR, 'Migration failed: ' . $throwable->getMessage() . PHP_EOL);
    $previous = $throwable->getPrevious();
    if ($previous instanceof Throwable && trim($previous->getMessage()) !== '') {
        fwrite(STDERR, 'Database error: ' . $previous->getMessage() . PHP_EOL);
    }
    exit(1);
}
