<?php

namespace Kylin\Modules\Console\Commands;

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

/**
 * 模块文档生成命令
 *
 * 生成模块的文档，包括模块的结构、API、使用方法等
 */
class ModuleDocCommand extends Command
{
    /**
     * 命令名称和签名
     *
     * @var string
     * 
     * 命令参数说明：
     * 1. {module} - 模块名称（必填）
     *    - 数据类型：字符串
     *    - 用途：指定要生成文档的模块名称
     *    - 示例：php artisan module:doc game
     * 
     * 命令选项说明：
     * 1. {--format=md} - 文档格式
     *    - 完整形式：--format
     *    - 数据类型：字符串
     *    - 用途：指定文档格式（md, html）
     *    - 默认值：md
     *    - 示例：php artisan module:doc game --format=html
     * 
     * 2. {--output=} - 输出路径
     *    - 完整形式：--output
     *    - 数据类型：字符串
     *    - 用途：指定文档输出路径
     *    - 示例：php artisan module:doc game --output=docs
     * 
     * 3. {--detailed} - 生成详细文档
     *    - 完整形式：--detailed
     *    - 用途：生成详细文档，包括更多的模块信息
     *    - 示例：php artisan module:doc game --detailed
     */
    protected $signature = 'module:doc {module : 模块名称} {--format=md : 文档格式（md, html）} {--output= : 输出路径} {--detailed : 生成详细文档}';

    /**
     * 命令描述
     *
     * @var string
     */
    protected $description = '生成模块的文档，包括模块的结构、API、使用方法等';

    /**
     * 文件系统实例
     *
     * @var Filesystem
     */
    private readonly Filesystem $files;

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

    /**
     * 执行控制台命令
     */
    public function handle(): int
    {
        $moduleName = (string) $this->argument('module');
        $format = $this->option('format') ?: 'md';
        $outputPath = $this->option('output');
        $detailed = $this->option('detailed');

        // 检查模块是否存在
        $module = $this->moduleManager->get($moduleName);
        if (!$module) {
            $this->error("模块 [{$moduleName}] 未找到");
            return 1;
        }

        $modulePath = $module->getPath();

        $this->info("正在生成模块 [{$moduleName}] 的文档...");

        // 生成文档内容
        $docContent = $this->generateDocContent($module, $format, $detailed);

        // 确定输出路径
        if (!$outputPath) {
            $outputPath = "{$modulePath}/docs";
            if (!$this->files->exists($outputPath)) {
                $this->files->makeDirectory($outputPath, 0755, true);
            }
            $outputPath .= "/README.{$format}";
        }

        // 写入文档文件
        $this->files->put($outputPath, $docContent);

        $this->info("模块 [{$moduleName}] 的文档已生成到: {$outputPath}");

        return 0;
    }

    /**
     * 生成文档内容
     *
     * @param  mixed  $module  模块实例
     * @param  string  $format  文档格式
     * @param  bool  $detailed  是否生成详细文档
     * @return string  文档内容
     */
    protected function generateDocContent($module, string $format, bool $detailed): string
    {
        $moduleName = $module->getName();
        $modulePath = $module->getPath();

        $content = '';

        switch ($format) {
            case 'md':
                $content = $this->generateMarkdownDoc($module, $detailed);
                break;
            case 'html':
                $content = $this->generateHtmlDoc($module, $detailed);
                break;
            default:
                $content = $this->generateMarkdownDoc($module, $detailed);
        }

        return $content;
    }

    /**
     * 生成 Markdown 格式的文档
     *
     * @param  mixed  $module  模块实例
     * @param  bool  $detailed  是否生成详细文档
     * @return string  Markdown 格式的文档内容
     */
    protected function generateMarkdownDoc($module, bool $detailed): string
    {
        $moduleName = $module->getName();
        $modulePath = $module->getPath();

        $content = "# {$moduleName} 模块文档\n\n";

        // 模块简介
        $content .= "## 模块简介\n\n";
        $content .= "本模块提供了 {$moduleName} 相关的功能。\n\n";

        // 模块结构
        $content .= "## 模块结构\n\n";
        $content .= "```\n";
        $content .= $this->generateDirectoryTree($modulePath);
        $content .= "```\n\n";

        // 安装和配置
        $content .= "## 安装和配置\n\n";
        $content .= "### 安装\n\n";
        $content .= "```bash\n";
        $content .= "php artisan module:install {$moduleName}\n";
        $content .= "```\n\n";

        $content .= "### 配置\n\n";
        $content .= "模块配置文件位于 `config/{$moduleName}.php`\n\n";

        // 路由
        $content .= "## 路由\n\n";
        $content .= $this->generateRoutesDoc($modulePath);

        // 控制器
        if ($detailed) {
            $content .= "## 控制器\n\n";
            $content .= $this->generateControllersDoc($modulePath);
        }

        // 模型
        if ($detailed) {
            $content .= "## 模型\n\n";
            $content .= $this->generateModelsDoc($modulePath);
        }

        // 中间件
        if ($detailed) {
            $content .= "## 中间件\n\n";
            $content .= $this->generateMiddlewareDoc($modulePath);
        }

        // 命令
        if ($detailed) {
            $content .= "## 命令\n\n";
            $content .= $this->generateCommandsDoc($modulePath);
        }

        // 依赖关系
        $content .= "## 依赖关系\n\n";
        $content .= $this->generateDependenciesDoc($module);

        // 使用示例
        $content .= "## 使用示例\n\n";
        $content .= "```php\n";
        $content .= "// 示例代码\n";
        $content .= "```\n\n";

        // 常见问题
        $content .= "## 常见问题\n\n";
        $content .= "- 问题1: 解决方案\n";
        $content .= "- 问题2: 解决方案\n";

        return $content;
    }

    /**
     * 生成 HTML 格式的文档
     *
     * @param  mixed  $module  模块实例
     * @param  bool  $detailed  是否生成详细文档
     * @return string  HTML 格式的文档内容
     */
    protected function generateHtmlDoc($module, bool $detailed): string
    {
        $moduleName = $module->getName();

        $content = "<!DOCTYPE html>\n";
        $content .= "<html>\n";
        $content .= "<head>\n";
        $content .= "    <title>{$moduleName} 模块文档</title>\n";
        $content .= "    <style>\n";
        $content .= "        body { font-family: Arial, sans-serif; margin: 20px; }\n";
        $content .= "        h1, h2, h3 { color: #333; }\n";
        $content .= "        pre { background: #f4f4f4; padding: 10px; border-radius: 5px; }\n";
        $content .= "        code { background: #f4f4f4; padding: 2px 4px; border-radius: 3px; }\n";
        $content .= "        ul { margin-left: 20px; }\n";
        $content .= "        .tree { font-family: monospace; white-space: pre; }\n";
        $content .= "    </style>\n";
        $content .= "</head>\n";
        $content .= "<body>\n";

        $content .= "<h1>{$moduleName} 模块文档</h1>\n";

        // 模块简介
        $content .= "<h2>模块简介</h2>\n";
        $content .= "<p>本模块提供了 {$moduleName} 相关的功能。</p>\n";

        // 模块结构
        $content .= "<h2>模块结构</h2>\n";
        $content .= "<pre class=\"tree\">\n";
        $content .= $this->generateDirectoryTree($module->getPath());
        $content .= "</pre>\n";

        // 安装和配置
        $content .= "<h2>安装和配置</h2>\n";
        $content .= "<h3>安装</h3>\n";
        $content .= "<pre>php artisan module:install {$moduleName}</pre>\n";

        $content .= "<h3>配置</h3>\n";
        $content .= "<p>模块配置文件位于 <code>config/{$moduleName}.php</code></p>\n";

        // 路由
        $content .= "<h2>路由</h2>\n";
        $content .= "<pre>\n";
        $content .= $this->generateRoutesDoc($module->getPath());
        $content .= "</pre>\n";

        // 依赖关系
        $content .= "<h2>依赖关系</h2>\n";
        $content .= "<pre>\n";
        $content .= $this->generateDependenciesDoc($module);
        $content .= "</pre>\n";

        // 使用示例
        $content .= "<h2>使用示例</h2>\n";
        $content .= "<pre>// 示例代码</pre>\n";

        // 常见问题
        $content .= "<h2>常见问题</h2>\n";
        $content .= "<ul>\n";
        $content .= "    <li>问题1: 解决方案</li>\n";
        $content .= "    <li>问题2: 解决方案</li>\n";
        $content .= "</ul>\n";

        $content .= "</body>\n";
        $content .= "</html>\n";

        return $content;
    }

    /**
     * 生成目录树
     *
     * @param  string  $directory  目录路径
     * @param  string  $prefix  前缀
     * @return string  目录树
     */
    protected function generateDirectoryTree(string $directory, string $prefix = ''): string
    {
        $tree = '';
        $files = $this->files->files($directory);
        $directories = $this->files->directories($directory);

        // 处理文件
        foreach ($files as $file) {
            $tree .= "{$prefix}├── " . $file->getFilename() . "\n";
        }

        // 处理目录
        foreach ($directories as $i => $dir) {
            $isLast = $i === count($directories) - 1;
            $dirName = basename($dir);
            $tree .= "{$prefix}├── {$dirName}\n";
            
            $newPrefix = $prefix . ($isLast ? "    " : "│   ");
            $tree .= $this->generateDirectoryTree($dir, $newPrefix);
        }

        return $tree;
    }

    /**
     * 生成路由文档
     *
     * @param  string  $modulePath  模块路径
     * @return string  路由文档
     */
    protected function generateRoutesDoc(string $modulePath): string
    {
        $routesPath = "{$modulePath}/routes/web.php";
        if (!$this->files->exists($routesPath)) {
            return "无路由定义\n\n";
        }

        $routesContent = $this->files->get($routesPath);
        return $routesContent . "\n";
    }

    /**
     * 生成控制器文档
     *
     * @param  string  $modulePath  模块路径
     * @return string  控制器文档
     */
    protected function generateControllersDoc(string $modulePath): string
    {
        $controllersPath = "{$modulePath}/app/Http/Controllers";
        if (!$this->files->exists($controllersPath)) {
            return "无控制器定义\n\n";
        }

        $controllers = $this->files->files($controllersPath);
        $content = '';

        foreach ($controllers as $controller) {
            $content .= "### " . $controller->getFilename() . "\n\n";
            $content .= "```php\n";
            $content .= $this->files->get($controller);
            $content .= "```\n\n";
        }

        return $content;
    }

    /**
     * 生成模型文档
     *
     * @param  string  $modulePath  模块路径
     * @return string  模型文档
     */
    protected function generateModelsDoc(string $modulePath): string
    {
        $modelsPath = "{$modulePath}/app/Models";
        if (!$this->files->exists($modelsPath)) {
            return "无模型定义\n\n";
        }

        $models = $this->files->files($modelsPath);
        $content = '';

        foreach ($models as $model) {
            $content .= "### " . $model->getFilename() . "\n\n";
            $content .= "```php\n";
            $content .= $this->files->get($model);
            $content .= "```\n\n";
        }

        return $content;
    }

    /**
     * 生成中间件文档
     *
     * @param  string  $modulePath  模块路径
     * @return string  中间件文档
     */
    protected function generateMiddlewareDoc(string $modulePath): string
    {
        $middlewarePath = "{$modulePath}/app/Http/Middleware";
        if (!$this->files->exists($middlewarePath)) {
            return "无中间件定义\n\n";
        }

        $middleware = $this->files->files($middlewarePath);
        $content = '';

        foreach ($middleware as $item) {
            $content .= "### " . $item->getFilename() . "\n\n";
            $content .= "```php\n";
            $content .= $this->files->get($item);
            $content .= "```\n\n";
        }

        return $content;
    }

    /**
     * 生成命令文档
     *
     * @param  string  $modulePath  模块路径
     * @return string  命令文档
     */
    protected function generateCommandsDoc(string $modulePath): string
    {
        $commandsPath = "{$modulePath}/app/Console/Commands";
        if (!$this->files->exists($commandsPath)) {
            return "无命令定义\n\n";
        }

        $commands = $this->files->files($commandsPath);
        $content = '';

        foreach ($commands as $command) {
            $content .= "### " . $command->getFilename() . "\n\n";
            $content .= "```php\n";
            $content .= $this->files->get($command);
            $content .= "```\n\n";
        }

        return $content;
    }

    /**
     * 生成依赖关系文档
     *
     * @param  mixed  $module  模块实例
     * @return string  依赖关系文档
     */
    protected function generateDependenciesDoc($module): string
    {
        try {
            $composerPath = "{$module->getPath()}/composer.json";
            if (!file_exists($composerPath)) {
                return "无依赖关系定义\n\n";
            }

            $composer = json_decode($this->files->get($composerPath), true);
            $dependencies = $composer['require'] ?? [];

            if (empty($dependencies)) {
                return "无依赖关系\n\n";
            }

            $content = '';
            foreach ($dependencies as $package => $version) {
                $content .= "- {$package}: {$version}\n";
            }

            return $content . "\n";
        } catch (\Exception $e) {
            return "无法读取依赖关系: {$e->getMessage()}\n\n";
        }
    }
}
