<?php

declare(strict_types=1);

namespace Maestro\Core\Console\Commands;

use Illuminate\Console\Command;
use Maestro\Core\Services\HostIntegrityService;

class HostIntegrityCommand extends Command
{
    protected $signature = 'maestro:host-integrity
        {--json : Output machine-readable JSON}
        {--fail-on-warn : Exit with code 1 when any check is warn or fail}
        {--fix-managed : Reset managed stubs via core:install --force}';

    protected $description = 'Audit host scaffolding, link state, and custom-layer boundaries';

    public function handle(HostIntegrityService $integrity): int
    {
        if ($this->option('fix-managed')) {
            if (! $this->confirm('This will overwrite managed @maestro-core-managed shells. Continue?')) {
                return self::SUCCESS;
            }

            $this->call('core:install', ['--force' => true]);
        }

        $report = $integrity->report();

        if ($this->option('json')) {
            $this->line(json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));

            return $this->exitCode($report);
        }

        $this->info('Maestro host integrity — overall: '.$report['overall']);
        $this->newLine();

        foreach ($report['checks'] as $check) {
            $tag = strtoupper($check['status']);
            $this->line(sprintf('[%s] %s', $tag, $check['label']));
            $this->line('  '.$check['detail']);
            if ($check['fix_commands'] !== []) {
                foreach ($check['fix_commands'] as $cmd) {
                    $this->line('  → '.$cmd);
                }
            }
            $this->newLine();
        }

        return $this->exitCode($report);
    }

    /**
     * @param  array{overall: string}  $report
     */
    private function exitCode(array $report): int
    {
        if ($report['overall'] === 'fail') {
            return self::FAILURE;
        }

        if ($this->option('fail-on-warn') && $report['overall'] === 'warn') {
            return self::FAILURE;
        }

        return self::SUCCESS;
    }
}
