<?php

declare(strict_types=1);

namespace NoahVet\Reef\Command\OpenAPI;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(
    name: 'reef:open-api:clear',
    description: 'Removes empty lines from YAML files',
)]
class ClearCommand extends Command implements ClearCommandInterface
{
    protected function configure(): void
    {
        $this
            ->addArgument(
                'path',
                InputArgument::REQUIRED,
                'File or directory to process (e.g., config/, config/routes.yaml)',
            )
            ->addOption(
                'dry-run',
                null,
                InputOption::VALUE_NONE,
                'Displays which files would be modified without writing them',
            )
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $path = $input->getArgument('path');
        $dryRun = $input->getOption('dry-run');

        if (!\file_exists($path)) {
            $output->writeln("<error>The path '{$path}' does not exist.</error>");

            return Command::FAILURE;
        }

        if (\is_file($path)) {
            $this->processFile($path, $dryRun, $output);
        } else {
            $this->processDirectory($path, $dryRun, $output);
        }

        return Command::SUCCESS;
    }

    private function processDirectory(string $directory, bool $dryRun, OutputInterface $output): void
    {
        $dirIterator = new \RecursiveDirectoryIterator($directory);
        $iterator = new \RecursiveIteratorIterator($dirIterator);
        $yamlFiles = new \RegexIterator($iterator, '/^.+\.(ya?ml)$/i', \RegexIterator::GET_MATCH);

        foreach ($yamlFiles as $files) {
            $file = $files[0];
            $this->processFile($file, $dryRun, $output);
        }
    }

    private function processFile(string $filePath, bool $dryRun, OutputInterface $output): void
    {
        $contents = \file_get_contents($filePath);

        if (false === $contents) {
            $output->writeln("<error>Unable to read file: {$filePath}</error>");

            return;
        }
        /** @var array<int, string> $lines */
        $lines = \preg_split("/\r\n|\n|\r/", $contents);

        $cleanedLines = [];
        foreach ($lines as $line) {
            if ('' === \trim($line)) {
                continue;
            }
            $cleanedLines[] = $line;
        }

        $cleanedContent = \implode("\n", $cleanedLines);

        if ($cleanedContent === $contents) {
            return;
        }

        if ($dryRun) {
            $output->writeln("<comment>[DRY-RUN]</comment> {$filePath} would be modified.");
        } else {
            \file_put_contents($filePath, $cleanedContent."\n");
            $output->writeln("<info>Cleaned:</info> {$filePath}");
        }
    }
}
