<?php

declare(strict_types=1);

namespace App\Command;

use App\Config\CorePatternAuditProvider;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
    name: 'mto:agent:config:audit-patterns',
    description: 'Audit remaining core pattern and token usage for developer-policy review'
)]
final class ConfigPatternAuditCommand extends Command
{
    public function __construct(private readonly CorePatternAuditProvider $provider)
    {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->addOption('json', null, InputOption::VALUE_NONE, 'Render the full audit result as JSON.')
            ->addOption('details', null, InputOption::VALUE_NONE, 'Render detailed warning rows in the console summary.')
            ->addOption('all', null, InputOption::VALUE_NONE, 'Also include lower-priority REVIEW findings.');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $result = $this->provider->audit((bool) $input->getOption('all'));

        if ((bool) $input->getOption('json')) {
            $json = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
            $output->writeln(is_string($json) ? $json : '{}');

            return Command::SUCCESS;
        }

        $this->renderSummary(
            new SymfonyStyle($input, $output),
            $result,
            (bool) $input->getOption('details'),
            (bool) $input->getOption('all')
        );

        return Command::SUCCESS;
    }

    /** @param array<string, mixed> $result */
    private function renderSummary(SymfonyStyle $io, array $result, bool $details, bool $includeAll): void
    {
        $io->title('RetrieX core pattern audit');

        $summary = is_array($result['summary'] ?? null) ? $result['summary'] : [];
        $io->definitionList(
            ['status' => (string) ($result['status'] ?? 'UNKNOWN')],
            ['source_files' => (string) ($summary['source_files'] ?? 0)],
            ['scanned_files' => (string) ($summary['scanned_files'] ?? 0)],
            ['skipped_files' => (string) ($summary['skipped_files'] ?? 0)],
            ['warning_findings' => (string) ($summary['warning_findings'] ?? 0)],
            ['review_findings' => (string) ($summary['review_findings'] ?? 0)],
            ['total_reported_findings' => (string) ($summary['total_reported_findings'] ?? 0)]
        );

        $warnings = is_array($result['warnings'] ?? null) ? $result['warnings'] : [];
        if ($warnings !== []) {
            $io->section('Warnings');
            foreach ($warnings as $warning) {
                $io->writeln('- ' . (string) $warning);
            }
        }

        if (!$details) {
            $note = 'Use --details for warning rows or --json for the complete machine-readable audit.';
            if (!$includeAll) {
                $note .= ' Add --all to include lower-priority REVIEW findings.';
            }
            $io->note($note);
            return;
        }

        $this->renderFindingTable($io, 'Warning findings', $result['warning_findings'] ?? []);

        if ($includeAll) {
            $this->renderFindingTable($io, 'Review findings', $result['review_findings'] ?? []);
        }
    }

    /** @param mixed $findings */
    private function renderFindingTable(SymfonyStyle $io, string $title, mixed $findings): void
    {
        if (!is_array($findings) || $findings === []) {
            return;
        }

        $rows = [];
        foreach ($findings as $finding) {
            if (!is_array($finding)) {
                continue;
            }

            $rows[] = [
                (string) ($finding['severity'] ?? ''),
                (string) ($finding['path'] ?? ''),
                (string) ($finding['line'] ?? ''),
                implode(', ', is_array($finding['calls'] ?? null) ? $finding['calls'] : []),
                implode(', ', is_array($finding['markers'] ?? null) ? $finding['markers'] : []),
                (string) ($finding['snippet'] ?? ''),
            ];
        }

        if ($rows === []) {
            return;
        }

        $io->section($title);
        $io->table(['Severity', 'Path', 'Line', 'Calls', 'Markers', 'Snippet'], $rows);
    }
}
