<?php

declare(strict_types=1);

namespace App\Console\Commands;

use App\Models\HostSystemUpdateExecution;
use App\Services\SupportCenter\HostSystemUpdateMigrationBatchRunner;
use App\Services\SupportCenter\HostSystemUpdatePostUpdateHealthCheckService;
use App\Services\SupportCenter\HostSystemUpdateRuntimeReadinessProcessService;
use App\Services\SupportCenter\HostSystemUpdateRuntimeReadinessService;
use Illuminate\Console\Command;
use Throwable;

final class DberpSystemUpdateHealthCheckCommand extends Command
{
    protected $signature = 'dberp:update-health
                            {--execution= : 系统更新执行编号}
                            {--runtime-only : 仅验证代码与 Composer 运行时，不检查待执行迁移}';

    protected $description = '在新 PHP CLI 运行时中执行系统更新完成前健康检查';

    public function handle(
        HostSystemUpdateRuntimeReadinessService $readiness,
        HostSystemUpdateMigrationBatchRunner $migrationRunner,
    ): int {
        $execution = HostSystemUpdateExecution::query()
            ->where('execution_no', trim((string) $this->option('execution')))
            ->first();

        if (! $execution instanceof HostSystemUpdateExecution) {
            return self::FAILURE;
        }

        try {
            if (! method_exists($readiness, 'check')) {
                $this->error('Runtime readiness service is not ready yet.');

                return self::FAILURE;
            }

            $runtime = $readiness->check($execution->fresh(['package']) ?? $execution);

            if ((bool) $this->option('runtime-only')) {
                $this->line(HostSystemUpdateRuntimeReadinessProcessService::RESULT_PREFIX.json_encode(
                    $runtime,
                    JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE,
                ));

                return self::SUCCESS;
            }

            $migration = $migrationRunner->snapshotProgress($execution->fresh(['package']) ?? $execution);

            if ($migration->pending > 0) {
                $this->error('Pending migrations remain.');

                return self::FAILURE;
            }

            $this->line(HostSystemUpdatePostUpdateHealthCheckService::RESULT_PREFIX.json_encode([
                'runtime' => $runtime,
                'migration' => $migration->toArray(),
            ], JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE));

            return self::SUCCESS;
        } catch (Throwable $throwable) {
            report($throwable);
            $this->error($throwable->getMessage());

            return self::FAILURE;
        }
    }
}
