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

namespace Core\CLI\Commands;

use Core\CLI\Command;
use Core\Database\SchemaBuilder; // For getTableNameFromSchemaName heuristic
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
use Exception;

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

    public function getDescription(): string
    {
        return 'Creates a new schema definition file in app/schemas/.';
    }

    public function execute(array $args): int
    {
        $schemaName = $args[0] ?? null;
        if (!$schemaName) {
            echo "Error: Please provide a schema name. Usage: php bin/coreflux make:schema users\n";
            return 1;
        }
        return $this->createSchemaFile($schemaName, true);
    }

    /**
     * Internal method to create a schema file.
     * Can be called externally by other commands (like make:migration).
     *
     * @param string $schemaName The base name of the schema (e.g., 'users', 'add_sku_to_products').
     * @param bool $isExternalCall If true, prints success/error messages.
     * @return int Exit code (0 for success, 1 for error).
     */
    public function createSchemaFile(string $schemaName, bool $isExternalCall = false): int
    {
        if (str_contains($schemaName, '/') || str_contains($schemaName, '\\')) {
            if ($isExternalCall) echo "Error: Schema name cannot contain directory separators.\n";
            return 1;
        }

        // Ensure APP_PATH is defined (from bootstrap.php). Fallback if not.
        if (!defined('APP_PATH')) {
            define('APP_PATH', dirname(dirname(dirname(dirname(__FILE__)))) . DIRECTORY_SEPARATOR . 'app');
        }
        $schemasDir = APP_PATH . DIRECTORY_SEPARATOR . 'schemas';

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

        $filePath = $schemasDir . DIRECTORY_SEPARATOR . $schemaName . '.php';

        if (file_exists($filePath)) {
            // If schema already exists, it's not an error for make:migration, so return 0.
            if ($isExternalCall) echo "Error: Schema '{$schemaName}.php' already exists at '{$filePath}'.\n";
            return 0;
        }

        $content = $this->getSchemaFileContent($schemaName);

        if (file_put_contents($filePath, $content) !== false) {
            if ($isExternalCall) echo "Success: Schema '{$schemaName}.php' created at '{$filePath}'.\n";
            return 0;
        } else {
            if ($isExternalCall) echo "Error: Failed to create schema file. Check permissions for '{$schemasDir}'.\n";
            return 1;
        }
    }

    /**
     * Generates the boilerplate content for a new schema definition file
     * based on the provided schema name.
     *
     * @param string $schemaName The base name of the schema (e.g., 'users', 'add_sku_to_products').
     * @return string The PHP closure content for the new schema.
     */
    private function getSchemaFileContent(string $schemaName): string
    {
        // The table name used in the schema definition should be the direct schemaName,
        // as SchemaBuilder methods now take the explicit table name.
        $tableNameForSchema = $schemaName;

        // Determine if it's an alter schema (e.g., add_column_to_users)
        $isAlterSchema = preg_match('/^(add|update|drop)_/', $schemaName);

        if ($schemaName === 'users') {
            // Comprehensive users table blueprint
            return <<<PHP
<?php
// app/schemas/{$schemaName}.php

use Doctrine\\DBAL\\Schema\\Schema;
use Doctrine\\DBAL\\Schema\\Table;

/**
 * Schema definition for the '{$tableNameForSchema}' table.
 * This is a comprehensive user table blueprint.
 */
return function (Schema \$schema, Table \$table) {
    // Primary Key
    \$table->addColumn("id", "bigint", ["autoincrement" => true, "notnull" => true, "unsigned" => true]);
    \$table->setPrimaryKey(["id"]);

    // Authentication
    \$table->addColumn("username", "string", ["length" => 50, "notnull" => false, "unique" => true]);
    \$table->addColumn("email", "string", ["length" => 100, "notnull" => true, "unique" => true]);
    \$table->addColumn("phone", "string", ["length" => 20, "notnull" => false, "unique" => true]);
    \$table->addColumn("password", "string", ["length" => 255, "notnull" => true]);
    \$table->addColumn("user_type", "string", ["length" => 10, "default" => "user", "notnull" => true]); // ENUM('admin', 'user')

    // Profile Information
    \$table->addColumn("first_name", "string", ["length" => 50, "notnull" => false]);
    \$table->addColumn("last_name", "string", ["length" => 50, "notnull" => false]);
    \$table->addColumn("avatar", "string", ["length" => 255, "notnull" => false]);
    \$table->addColumn("gender", "string", ["length" => 10, "notnull" => false]); // ENUM('male', 'female', 'other')
    \$table->addColumn("date_of_birth", "date_immutable", ["notnull" => false]);

    // Status
    \$table->addColumn("role", "string", ["length" => 15, "default" => "user", "notnull" => true]); // ENUM('user','admin','moderator')
    \$table->addColumn("is_active", "boolean", ["default" => true, "notnull" => true]);
    \$table->addColumn("email_verified_at", "datetime_immutable", ["notnull" => false, "default" => null]);
    \$table->addColumn("phone_verified_at", "datetime_immutable", ["notnull" => false, "default" => null]);

    // Timestamps
    \$table->addColumn("created_at", "datetime_immutable", ["default" => "CURRENT_TIMESTAMP", "notnull" => true]);
    \$table->addColumn("updated_at", "datetime_immutable", ["default" => "CURRENT_TIMESTAMP", "notnull" => true]);
    \$table->addColumn("deleted_at", "datetime_immutable", ["notnull" => false, "default" => null]);

    // Indexes
    \$table->addIndex(["email"], "IDX_USERS_EMAIL");
    \$table->addIndex(["phone"], "IDX_USERS_PHONE");
    \$table->addIndex(["username"], "IDX_USERS_USERNAME");
};
PHP;
        } elseif ($isAlterSchema) {
            // Blueprint for altering an existing table
            // The actualTableName is derived from the schemaName (e.g., 'users' from 'add_column_to_users')
            $schemaBuilder = new SchemaBuilder(Connection::getInstance(require FS_CONFIG_PATH . DIRECTORY_SEPARATOR . 'database.php'));
            $actualTableName = $schemaBuilder->getTableNameFromSchemaName($schemaName);

            return <<<PHP
<?php
// app/schemas/{$schemaName}.php

use Doctrine\\DBAL\\Schema\\Schema;
use Doctrine\\DBAL\\Schema\\Table;

/**
 * Schema definition for altering the '{$actualTableName}' table.
 * Use this to add, modify, or drop columns/indexes on an existing table.
 */
return function (Table \$table) { // Alter callback only receives Table object
    // Add new columns:
    // if (!\$table->hasColumn('new_column')) {
    //     \$table->addColumn('new_column', 'string', ['length' => 255, 'notnull' => false]);
    // }

    // Update existing columns:
    // if (\$table->hasColumn('description')) {
    //     \$table->getColumn('description')->setNotnull(true)->setDefault('No description');
    // }

    // Drop columns:
    // if (\$table->hasColumn('old_column')) {
    //     \$table->dropColumn('old_column');
    // }

    // Add indexes:
    // if (!\$table->hasIndex('IDX_NEW_COLUMN')) {
    //     \$table->addIndex(['new_column'], 'IDX_NEW_COLUMN');
    // }

    // Drop indexes:
    // if (\$table->hasIndex('OLD_INDEX')) {
    //     \$table->dropIndex('OLD_INDEX');
    // }
};
PHP;
        } else {
            // Default basic new table schema
            return <<<PHP
<?php
// app/schemas/{$schemaName}.php

use Doctrine\\DBAL\\Schema\\Schema;
use Doctrine\\DBAL\\Schema\\Table;

/**
 * Schema definition for the '{$tableNameForSchema}' table.
 * Define your table structure using Doctrine DBAL's fluent API.
 */
return function (Schema \$schema, Table \$table) {
    // Add your columns here. Example:
    \$table->addColumn("id", "integer", ["autoincrement" => true, "notnull" => true]);
    \$table->addColumn("name", "string", ["length" => 255, "notnull" => true]);
    \$table->addColumn("created_at", "datetime_immutable", ["default" => "CURRENT_TIMESTAMP", "notnull" => true]);
    \$table->addColumn("updated_at", "datetime_immutable", ["default" => "CURRENT_TIMESTAMP", "notnull" => true]);

    \$table->setPrimaryKey(["id"]);
    // \$table->addUniqueIndex(["email"], "UNIQ_EMAIL");
    // \$table->addIndex(["name"], "IDX_NAME");
    // \$table->addForeignKeyConstraint(...);
};
PHP;
        }
    }
}