#!/usr/bin/env php
<?php

declare(strict_types=1);

use App\Core\Database;
use App\Core\MigrationRunner;
use App\Core\SeederRunner;
use App\Core\LogArchiver;
use App\Core\ProductionHealth;
use App\Core\DemoDataSeeder;

$app = require __DIR__ . '/bootstrap/app.php';
$command = $argv[1] ?? 'help';

try {
    if (!in_array($command, ['migrate', 'migrate:rollback', 'migrate:status', 'seed', 'demo:seed', 'logs:archive', 'health:check', 'cron:heartbeat'], true)) {
        echo "PowerAMS CLI\n\nCommands:\n  migrate\n  migrate:rollback\n  migrate:status\n  seed\n  demo:seed [--airline=ID|CODE] [--confirm-production]\n  logs:archive [days]\n  health:check\n  cron:heartbeat\n";
        exit(0);
    }
    if ($command === 'health:check') {
        $failed = 0;
        foreach ((new ProductionHealth())->checks() as $name => $check) {
            printf("%-6s %-24s %s\n", strtoupper($check['status']), $name, $check['message']);
            if ($check['status'] === 'fail') { $failed++; }
        }
        exit($failed === 0 ? 0 : 1);
    }
    if ($command === 'cron:heartbeat') {
        (new ProductionHealth())->writeCronHeartbeat();
        echo 'Cron heartbeat recorded at ' . gmdate('c') . ".\n";
        exit(0);
    }
    if ($command === 'logs:archive') {
        $days = isset($argv[2]) && filter_var($argv[2], FILTER_VALIDATE_INT) !== false ? (int) $argv[2] : 30;
        $items = (new LogArchiver())->archive($days);
        echo $items === [] ? "No logs eligible for archive.\n" : "Archived:\n - " . implode("\n - ", $items) . "\n";
        exit(0);
    }
    if ($command === 'demo:seed' && (string) config('app.env', 'production') === 'production' && !in_array('--confirm-production', $argv, true)) {
        throw new RuntimeException('Demo data is disabled in production unless --confirm-production is provided. Back up the database first.');
    }
    $db = Database::connection();
    if ($command === 'demo:seed') {
        $airlineOption = null;
        foreach ($argv as $argument) {
            if (str_starts_with($argument, '--airline=')) { $airlineOption = trim(substr($argument, 10)); }
        }
        if ($airlineOption !== null && $airlineOption !== '') {
            $lookup = ctype_digit($airlineOption)
                ? $db->prepare('SELECT id FROM airlines WHERE id = :value AND deleted_at IS NULL')
                : $db->prepare('SELECT id FROM airlines WHERE UPPER(airline_code) = UPPER(:value) AND deleted_at IS NULL');
            $lookup->execute(['value' => $airlineOption]);
            $airlineId = (int) $lookup->fetchColumn();
        } else {
            $airlines = $db->query('SELECT id FROM airlines WHERE deleted_at IS NULL ORDER BY id')->fetchAll(PDO::FETCH_COLUMN);
            if (count($airlines) !== 1) { throw new RuntimeException('Specify the target airline using --airline=ID or --airline=CODE.'); }
            $airlineId = (int) $airlines[0];
        }
        if ($airlineId < 1) { throw new RuntimeException('The requested airline was not found.'); }
        (new SeederRunner($db, base_path('database/seeders')))->run();
        $counts = (new DemoDataSeeder($db))->seed($airlineId);
        echo "Demo data added for airline {$airlineId}:\n";
        foreach ($counts as $type => $count) { printf(" - %-16s %d\n", $type, $count); }
        exit(0);
    }
    $migrator = new MigrationRunner($db, base_path('database/migrations'));
    switch ($command) {
        case 'migrate':
            $items = $migrator->migrate();
            echo $items === [] ? "Nothing to migrate.\n" : "Migrated:\n - " . implode("\n - ", $items) . "\n";
            break;
        case 'migrate:rollback':
            $items = $migrator->rollback();
            echo $items === [] ? "Nothing to roll back.\n" : "Rolled back:\n - " . implode("\n - ", $items) . "\n";
            break;
        case 'migrate:status':
            foreach ($migrator->status() as $row) {
                printf("%-10s %-6s %s\n", $row['status'], $row['batch'] ?? '-', $row['name']);
            }
            break;
        case 'seed':
            $items = (new SeederRunner($db, base_path('database/seeders')))->run();
            echo "Seeded:\n - " . implode("\n - ", $items) . "\n";
            break;
    }
} catch (Throwable $exception) {
    fwrite(STDERR, 'Error: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
}
