<?php

namespace Kylin\Modules\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Database\Migrations\Migrator;
use Kylin\Modules\ModuleManager;

/**
 * 执行模块迁移命令
 *
 * 用于运行指定模块或所有模块的数据库迁移
 */
class ModuleMigrateCommand extends Command
{
    /**
     * 命令名称和签名
     *
     * @var string
     * 
     * 命令参数说明：
     * 1. {module?} - 模块名称（可选）
     *    - 数据类型：字符串
     *    - 用途：指定要执行迁移的模块名称，不指定则执行所有模块的迁移
     *    - 示例：php artisan module:migrate game
     * 
     * 命令选项说明：
     * 1. {--fresh} - 删除所有表并重新运行所有迁移
     *    - 完整形式：--fresh
     *    - 用途：删除所有表并重新运行所有迁移
     *    - 示例：php artisan module:migrate game --fresh
     * 
     * 2. {--seed} - 迁移后填充数据库
     *    - 完整形式：--seed
     *    - 用途：在迁移后自动填充数据库
     *    - 示例：php artisan module:migrate game --seed
     */
    protected $signature = 'module:migrate {module? : 模块名称} {--fresh : 删除所有表并重新运行所有迁移} {--seed : 迁移后填充数据库}';

    /**
     * 命令描述
     *
     * @var string
     */
    protected $description = '执行模块迁移';

    /**
     * 创建新命令实例
     *
     * @param  ModuleManager  $moduleManager  模块管理器实例
     * @param  Migrator  $migrator  迁移器实例
     */
    public function __construct(
        private readonly ModuleManager $moduleManager,
        private readonly Migrator $migrator
    ) {
        parent::__construct();
    }

    /**
     * 执行控制台命令
     */
    public function handle(): int
    {
        $module = $this->argument('module');
        $fresh = (bool) $this->option('fresh');
        $seed = (bool) $this->option('seed');

        if ($module) {
            $this->migrateModule((string) $module, $fresh, $seed);
        } else {
            $this->migrateAllModules($fresh, $seed);
        }

        return 0;
    }

    /**
     * 迁移指定模块
     *
     * @param  string  $moduleName  模块名称
     * @param  bool  $fresh  是否重新创建表
     * @param  bool  $seed  是否填充数据
     */
    protected function migrateModule(string $moduleName, bool $fresh, bool $seed): void
    {
        $module = $this->moduleManager->get($moduleName);

        if (!$module) {
            $this->error("模块 [{$moduleName}] 未找到。");
            return;
        }

        $this->info("正在迁移模块: {$moduleName}");

        $migrationPath = $module->getPath('database/migrations');

        if (!is_dir($migrationPath)) {
            $this->info("模块 {$moduleName} 未找到迁移文件");
            return;
        }

        if ($fresh) {
            $this->call('migrate:fresh', [
                '--path' => $migrationPath,
            ]);
        } else {
            $this->call('migrate', [
                '--path' => $migrationPath,
            ]);
        }

        if ($seed) {
            $this->call('module:seed', [
                'module' => $moduleName,
            ]);
        }

        $this->info("模块 [{$moduleName}] 迁移成功。");
    }

    /**
     * 迁移所有模块
     *
     * @param  bool  $fresh  是否重新创建表
     * @param  bool  $seed  是否填充数据
     */
    protected function migrateAllModules(bool $fresh, bool $seed): void
    {
        $modules = $this->moduleManager->all();

        foreach ($modules as $module) {
            $this->migrateModule($module->getName(), $fresh, $seed);
        }
    }
}