<?php

namespace MintyPHP\Console\Commands\Scheduler;

use MintyPHP\Console\Command;
use MintyPHP\DB;
use MintyPHP\Service\Audit\AuditRecorderInterface;
use MintyPHP\Service\Scheduler\SchedulerServicesFactory;

final class RunCommand extends Command
{
    public function name(): string
    {
        return 'scheduler:run';
    }

    public function description(): string
    {
        return 'Execute due scheduled jobs';
    }

    public function execute(array $args, array $options): int
    {
        $this->bootstrapApp('scheduler');

        $exitCode = 0;
        $startedAt = microtime(true);
        try {
            $factory = app(SchedulerServicesFactory::class);
            $result = $factory->createSchedulerRunService()->runDueJobs();
            if (!($result['ok'] ?? false)) {
                $error = (string) ($result['error'] ?? 'unexpected_error');
                fwrite(STDERR, sprintf("scheduler run failed: %s\n", $error));
                $exitCode = 1;
            } else {
                fwrite(STDOUT, sprintf(
                    "scheduler completed: processed=%d success=%d failed=%d skipped=%d duration_ms=%d\n",
                    (int) ($result['processed'] ?? 0),
                    (int) ($result['success'] ?? 0),
                    (int) ($result['failed'] ?? 0),
                    (int) ($result['skipped'] ?? 0),
                    (int) ($result['duration_ms'] ?? 0)
                ));
            }
        } catch (\Throwable $exception) {
            try {
                app(AuditRecorderInterface::class)->record('scheduler.run', 'failed', [
                    'error_code' => 'unexpected_error',
                    'metadata' => [
                        'trigger_type' => 'scheduler',
                        'run_status' => 'failed',
                        'processed' => 0,
                        'success_count' => 0,
                        'failed_count' => 0,
                        'skipped_count' => 0,
                        'duration_ms' => max(0, (int) round((microtime(true) - $startedAt) * 1000)),
                        'bootstrap_error' => true,
                    ],
                ]);
            } catch (\Throwable) {
                // fail-open
            }

            fwrite(STDERR, sprintf("scheduler run failed: unexpected_error: %s\n", $exception->getMessage()));
            $exitCode = 1;
        } finally {
            DB::close();
        }

        return $exitCode;
    }
}
