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

namespace Core\CLI\Commands;

use Core\CLI\Command;

class MakeMigrationAutoCommand implements Command
{
    public function getName(): string
    {
        return 'make:migration:auto';
    }

    public function getDescription(): string
    {
        return 'Creates a new migration file with up/down methods auto-generated.';
    }

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

        if (!$migrationName) {
            echo "Error: Please provide a migration name. Usage: php bin/coreflux make:migration:auto create_users_table\n";
            return 1;
        }

        // Validate migration name format
        if (!preg_match('/^(create|add|update|drop)_[a-zA-Z0-9_]+(_table)?$/', $migrationName)) {
            echo "Error: Invalid migration name format. Use 'create_table_name', 'add_column_to_table', 'drop_table_name' etc.\n";
            return 1;
        }

        $timestamp = date('YmdHis');
        $fileName = "{$timestamp}_{$migrationName}.php";

        // Assuming FS_STORAGE_PATH is defined (e.g., in bin/coreflux)
        if (!defined('FS_STORAGE_PATH')) {
            // Path from core/CLI/Commands/ to storage/
            define('FS_STORAGE_PATH', dirname(dirname(dirname(dirname(__DIR__)))) . DIRECTORY_SEPARATOR . 'storage');
        }
        $migrationsDir = FS_STORAGE_PATH . DIRECTORY_SEPARATOR . 'migrations';

        if (!is_dir($migrationsDir)) {
            if (!mkdir($migrationsDir, 0775, true)) {
                echo "Error: Failed to create migrations directory: {$migrationsDir}. Check permissions.\n";
                return 1;
            }
            echo "Info: Created migrations directory: {$migrationsDir}\n";
        }

        $filePath = $migrationsDir . DIRECTORY_SEPARATOR . $fileName;

        if (file_exists($filePath)) {
            echo "Error: Migration file '{$fileName}' already exists.\n";
            return 1;
        }

        $content = $this->getMigrationFileContent($migrationName);

        if (file_put_contents($filePath, $content) !== false) {
            echo "Success: Migration '{$fileName}' created at '{$filePath}'.\n";
            return 0;
        } else {
            echo "Error: Failed to create migration file. Check permissions for '{$migrationsDir}'.\n";
            return 1;
        }
    }

    /**
     * Generates the content for a new migration file with auto-generated up/down methods.
     * @param string $migrationName The base name of the migration.
     * @return string The PHP class content for the migration.
     */
    private function getMigrationFileContent(string $migrationName): string
    {
        $upMethodContent = '// TODO: define your \'up\' migration for ' . $migrationName;
        $downMethodContent = '// TODO: define your \'down\' migration for ' . $migrationName;
        $tableName = $this->getTableNameFromMigrationName($migrationName);
        $columnName = $this->getColumnNameFromMigrationName($migrationName);
        $migrationType = $this->getMigrationType($migrationName);

        if ($migrationType === 'create') {
            $upMethodContent = <<<UP
        // Example for creating a table:
        // SchemaOperator::createTable('{$tableName}', [
        //     'id' => 'INT PRIMARY KEY AUTO_INCREMENT',
        //     'name' => 'VARCHAR(255) NOT NULL',
        //     'created_at' => 'DATETIME DEFAULT CURRENT_TIMESTAMP'
        // ]);
UP;
            $downMethodContent = <<<DOWN
Schema::dropTable('{$tableName}');
DOWN;
        } elseif ($migrationType === 'drop' && $tableName) {
            $upMethodContent = <<<UP
Schema::dropTable('{$tableName}');
UP;
            $downMethodContent = <<<DOWN
        // TODO: The down method for a 'drop' migration requires you to re-create the table.
        // Define your columns here to re-create the table.
        // SchemaOperator::createTable('{$tableName}', [
        //     'id' => 'INT PRIMARY KEY AUTO_INCREMENT',
        //     'name' => 'VARCHAR(255) NOT NULL',
        //     'created_at' => 'DATETIME DEFAULT CURRENT_TIMESTAMP'
        // ]);
DOWN;
        } elseif ($migrationType === 'add' && $tableName && $columnName) {
            $upMethodContent = <<<UP
        // TODO: Define the column type.
        // SchemaOperator::addColumn('{$tableName}', '{$columnName}', 'VARCHAR(255)');
UP;
            $downMethodContent = <<<DOWN
Schema::dropColumn('{$tableName}', '{$columnName}');
DOWN;
        } elseif ($migrationType === 'drop_column' && $tableName && $columnName) {
            $upMethodContent = <<<UP
Schema::dropColumn('{$tableName}', '{$columnName}');
UP;
            $downMethodContent = <<<DOWN
        // TODO: The down method for a 'drop column' migration requires you to re-add the column with its original definition.
        // SchemaOperator::addColumn('{$tableName}', '{$columnName}', 'VARCHAR(255)');
DOWN;
        }

        // --- The migration file content ---
        return <<<PHP
<?php

use Core\\Database\\SchemaOperator;
use Core\\Database\\Schema;
use Core\\Database\\MigrationOperation;

return new class implements MigrationOperation {

    public function up()
    {
        SchemaOperator::init('up');
        {$upMethodContent}
    }

    public function down()
    {
        SchemaOperator::init('down');
        {$downMethodContent}
    }
};
PHP;
    }
    
    /**
     * Extracts the base table name from a migration name.
     * @param string $migrationName
     * @return string
     */
    private function getTableNameFromMigrationName(string $migrationName): string
    {
        if (preg_match('/_to_([a-zA-Z0-9_]+)_table$/', $migrationName, $matches)) {
            return $matches[1];
        }
        if (preg_match('/^(create|drop)_(.*)_table$/', $migrationName, $matches)) {
            return $matches[2];
        }
        return $migrationName;
    }

    /**
     * Extracts a column name from a migration name.
     * @param string $migrationName
     * @return string|null
     */
    private function getColumnNameFromMigrationName(string $migrationName): ?string
    {
        if (preg_match('/^(add|drop)_(.*)_to_/', $migrationName, $matches)) {
            return $matches[2];
        }
        return null;
    }

    /**
     * Determines the type of migration based on the name.
     * @param string $migrationName
     * @return string
     */
    private function getMigrationType(string $migrationName): string
    {
        if (str_starts_with($migrationName, 'create_')) {
            return 'create';
        }
        if (str_starts_with($migrationName, 'drop_')) {
            if (preg_match('/_to_/', $migrationName)) {
                return 'drop_column';
            }
            return 'drop';
        }
        if (str_starts_with($migrationName, 'add_')) {
            return 'add';
        }
        return 'generic';
    }
}