<?php

namespace Kylin\Modules\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Str;
use Kylin\Modules\ModuleManager;

/**
 * 创建模块种子命令
 *
 * 用于为指定模块创建新的种子类
 */
class ModuleMakeSeederCommand extends Command
{
    /**
     * 命令名称和签名
     *
     * @var string
     * 
     * 命令参数说明：
     * 1. {module} - 模块名称（必填）
     *    - 数据类型：字符串
     *    - 用途：指定种子类所属的模块名称
     *    - 示例：php artisan module:make-seeder game UserSeeder
     * 
     * 2. {name} - 种子类名称（必填）
     *    - 数据类型：字符串
     *    - 用途：指定要创建的种子类名称
     *    - 示例：php artisan module:make-seeder game UserSeeder
     */
    protected $signature = 'module:make-seeder {module : 模块名称} {name : 种子类名称}';


    /**
     * 命令描述
     *
     * @var string
     */
    protected $description = '为模块创建新的种子类';

    /**
     * 创建新命令实例
     *
     * @param  Filesystem  $files  文件系统实例
     * @param  ModuleManager  $moduleManager  模块管理器实例
     */
    public function __construct(
        private readonly Filesystem $files,
        private readonly ModuleManager $moduleManager
    ) {
        parent::__construct();
    }

    /**
     * 执行控制台命令
     */
    public function handle(): int
    {
        $moduleName = (string) $this->argument('module');
        $seederName = (string) $this->argument('name');

        $module = $this->moduleManager->get($moduleName);

        if (!$module) {
            $this->error("模块 [{$moduleName}] 不存在。");
            return 1;
        }

        $seederPath = $this->getSeederPath($module, $seederName);
        $seederNamespace = $this->getSeederNamespace($module);
        $seederClass = $this->getSeederClass($seederName);

        if ($this->files->exists($seederPath)) {
            $this->error("种子 [{$seederClass}] 在模块 [{$moduleName}] 中已存在。");
            return 1;
        }

        if (!$this->files->isDirectory(dirname($seederPath))) {
            $this->files->makeDirectory(dirname($seederPath), 0755, true);
        }

        $stub = $this->getStub();
        $content = $this->replaceStubVariables($stub, $seederNamespace, $seederClass);

        $this->files->put($seederPath, $content);

        $this->info("种子 [{$seederClass}] 在模块 [{$moduleName}] 中创建成功！");
        $this->info("种子路径: {$seederPath}");

        return 0;
    }

    /**
     * 获取种子路径
     *
     * @param  \Kylin\Modules\Module  $module  模块实例
     * @param  string  $seederName  种子名称
     * @return string
     */
    protected function getSeederPath($module, string $seederName): string
    {
        return $module->getPath('database/seeders/' . $seederName . '.php');
    }

    /**
     * 获取种子命名空间
     *
     * @param  \Kylin\Modules\Module  $module  模块实例
     * @return string
     */
    protected function getSeederNamespace($module): string
    {
        return $module->getNamespace() . '\\Database\\Seeders';
    }

    /**
     * 获取种子类名
     *
     * @param  string  $seederName  种子名称
     * @return string
     */
    protected function getSeederClass(string $seederName): string
    {
        return $seederName;
    }

    /**
     * 获取模板文件
     *
     * @return string
     */
    protected function getStub(): string
    {
        $stubPath = __DIR__ . '/../../../stubs/seeder.stub';
        return $this->files->get($stubPath);
    }

    /**
     * 替换模板变量
     *
     * @param  string  $stub  模板内容
     * @param  string  $namespace  命名空间
     * @param  string  $class  类名
     * @return string
     */
    protected function replaceStubVariables(string $stub, string $namespace, string $class): string
    {
        $stub = str_replace('{{ namespace }}', $namespace, $stub);
        $stub = str_replace('{{ class }}', $class, $stub);

        return $stub;
    }
}