<?php
// CoreFlux/core/CLI/Commands/MakeCommandCommand.php

namespace Core\CLI\Commands;

use Core\CLI\Command;

class MakeCommandCommand implements Command
{
    public function getName(): string
    {
        return 'make:command';
    }

    public function getDescription(): string
    {
        return 'Creates a new CLI command file and registers it in the manifest.';
    }

    public function execute(array $args): int
    {
        $commandName = $args[0] ?? null;

        if (!$commandName) {
            echo "Error: Please provide a Command name. Usage: php bin/coreflux make:command MyNewCommand\n";
            return 1; // Indicate error
        }

        // Ensure the command name ends with 'Command' for convention
        if (!str_ends_with($commandName, 'Command')) {
            $commandName .= 'Command';
        }

        $filePath = FS_CORE_PATH . DIRECTORY_SEPARATOR . 'CLI' . DIRECTORY_SEPARATOR . 'Commands' . DIRECTORY_SEPARATOR . $commandName . '.php';

        if (file_exists($filePath)) {
            echo "Error: Command '{$commandName}' already exists at '{$filePath}'.\n";
            return 1;
        }

        // 1. Generate the content for the new command file
        $content = $this->getCommandFileContent($commandName);

        if (file_put_contents($filePath, $content) === false) {
            echo "Error: Failed to create command file. Check permissions for '" . FS_CORE_PATH . DIRECTORY_SEPARATOR . 'CLI' . DIRECTORY_SEPARATOR . 'Commands' . "'.\n";
            return 1;
        }
        echo "Success: Command '{$commandName}' created at '{$filePath}'.\n";

        // 2. Register the new command in the manifest file
        $registerResult = $this->registerCommandInManifest($commandName);
        if ($registerResult !== 0) {
            echo "Warning: Failed to automatically register '{$commandName}' in the CLI command manifest. Please add it manually.\n";
            return $registerResult;
        }

        // 3. Run composer dump-autoload to ensure the new class is discoverable
        echo "Running 'composer dump-autoload' to update autoloader...\n";
        $composerOutput = shell_exec('composer dump-autoload');
        echo $composerOutput;
        if (str_contains($composerOutput, 'Generating optimized autoload files') === false) {
             echo "Warning: Composer autoload might not have run successfully. Please run 'composer dump-autoload' manually.\n";
        }


        return 0; // Indicate overall success
    }

    /**
     * Generates the boilerplate content for a new CLI command file.
     *
     * @param string $className The name of the new command class (e.g., 'MyNewCommandCommand').
     * @return string The PHP code for the new command.
     */
    private function getCommandFileContent(string $className): string
    {
        $commandInternalName = strtolower(preg_replace('/(?<!^)[A-Z]/', ':$0', str_replace('Command', '', $className)));
        $commandInternalName = 'my:' . ltrim($commandInternalName, ':');

        return <<<PHP
<?php

namespace Core\\CLI\\Commands;

use Core\\CLI\\Command;

class {$className} implements Command
{
    public function getName(): string
    {
        return '{$commandInternalName}';
    }

    public function getDescription(): string
    {
        return 'A description for the {$className} command.';
    }

    public function execute(array \$args): int
    {
        echo "Executing {$className} command with arguments: " . implode(', ', \$args) . "\\n";
        // Your command logic goes here
        
        return 0;
    }
}
PHP;
    }

    /**
     * Appends the new command's class name to the CLI command manifest file.
     *
     * @param string $commandClassName The class name of the new command (e.g., 'MyNewCommandCommand').
     * @return int Exit code (0 for success, 1 for error).
     */
    private function registerCommandInManifest(string $commandClassName): int
    {
        $manifestPath = FS_APP_PATH . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'cli_commands.php';
        $fullCommandClass = '\\Core\\CLI\\Commands\\' . $commandClassName . '::class';

        if (!file_exists($manifestPath)) {
            echo "Error: CLI command manifest not found at '{$manifestPath}'. Cannot register command.\n";
            return 1;
        }

        $manifestContent = file_get_contents($manifestPath);
        if ($manifestContent === false) {
            echo "Error: Could not read CLI command manifest. Check permissions for '{$manifestPath}'.\n";
            return 1;
        }

        // Check if already registered (idempotence)
        if (str_contains($manifestContent, $fullCommandClass)) {
            echo "Info: Command '{$commandClassName}' already registered in manifest. Skipping.\n";
            return 0;
        }

        // Find the last '];' in the file to insert before it
        $pattern = '/^(\s*\];)$/m'; // Matches '];' at the end of the return array

        if (preg_match($pattern, $manifestContent, $matches, PREG_OFFSET_CAPTURE)) {
            $insertPosition = $matches[1][1]; // Position of the '];'
            $insertContent = "    " . $fullCommandClass . ",\n"; // New line to insert

            // Insert the new line before the '];'
            $newManifestContent = substr_replace($manifestContent, $insertContent, $insertPosition, 0);

            if (file_put_contents($manifestPath, $newManifestContent) !== false) {
                echo "Success: Command '{$commandClassName}' registered in '{$manifestPath}'.\n";
                return 0;
            } else {
                echo "Error: Failed to write to CLI command manifest. Check permissions for '{$manifestPath}'.\n";
                return 1;
            }
        } else {
            echo "Error: Could not find the closing array bracket in '{$manifestPath}'. Please ensure it returns an array.\n";
            return 1;
        }
    }
}