<?php

declare(strict_types=1);

namespace Kylin\Scaffold\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

/**
 * 安装后验证命令
 *
 * 依据 GB/T 8566-2022 软件工程软件生存周期，
 * 安装完成后需验证各模块配置正确性。
 *
 * 验证项：
 *  - 数据库连接
 *  - 核心模块配置
 *  - 可选模块配置
 *  - 安全配置
 *
 * 使用方式：
 *   php artisan kylin:verify
 *   php artisan kylin:verify --module=rbac
 */
class PostInstallVerifyCommand extends Command
{
    protected $signature = 'kylin:verify
                            {--module= : 仅验证指定模块}
                            {--json : JSON 格式输出}';

    protected $description = '验证 Kylin 各模块安装后配置正确性';

    /** 验证结果 */
    private array $results = [];

    public function handle(): int
    {
        $this->info('Kylin 安装后验证');
        $this->line('法律依据：GB/T 8566-2022《软件工程 软件生存周期》');
        $this->newLine();

        $module = $this->option('module');

        $allPassed = true;

        // 1. 数据库连接验证
        if (! $module || $module === 'database') {
            $allPassed = $this->verifyDatabase() && $allPassed;
        }

        // 2. APP_KEY 验证
        if (! $module || $module === 'security') {
            $allPassed = $this->verifyAppKey() && $allPassed;
        }

        // 3. 核心模块验证
        if (! $module || in_array($module, ['core', 'licensing', 'rbac'], true)) {
            $allPassed = $this->verifyCoreModules($module) && $allPassed;
        }

        // 4. 可选模块配置验证
        $optionalModules = ['user', 'auth', 'settings', 'audit-log', 'dictionary', 'storage', 'adminlte', 'media', 'activity', 'world'];
        if (! $module || in_array($module, $optionalModules, true)) {
            $allPassed = $this->verifyOptionalModules($module) && $allPassed;
        }

        // 5. 安全配置验证
        if (! $module || $module === 'security') {
            $allPassed = $this->verifySecurityConfig() && $allPassed;
        }

        // 输出结果
        if ($this->option('json')) {
            $this->line(json_encode($this->results, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
        } else {
            $this->newLine();
            $this->line('──────────────────────────────────────────');
            $this->line('  验证结果汇总');
            $this->line('──────────────────────────────────────────');
            $this->newLine();

            foreach ($this->results as $result) {
                $icon = $result['status'] === 'pass' ? '✅' : '❌';
                $this->line("  {$icon} {$result['item']}：{$result['message']}");
            }

            $this->newLine();
            if ($allPassed) {
                $this->info('  所有验证项通过！');
            } else {
                $this->warn('  存在验证失败项，请检查上述 ❌ 标记项。');
            }
        }

        return $allPassed ? self::SUCCESS : self::FAILURE;
    }

    /**
     * 验证数据库连接
     */
    private function verifyDatabase(): bool
    {
        try {
            DB::connection()->getPdo();
            $this->results[] = ['item' => '数据库连接', 'status' => 'pass', 'message' => '连接正常'];
            return true;
        } catch (\Throwable $e) {
            $this->results[] = ['item' => '数据库连接', 'status' => 'fail', 'message' => $e->getMessage()];
            return false;
        }
    }

    /**
     * 验证 APP_KEY
     */
    private function verifyAppKey(): bool
    {
        if (config('app.key')) {
            $this->results[] = ['item' => 'APP_KEY', 'status' => 'pass', 'message' => '已配置'];
            return true;
        }
        $this->results[] = ['item' => 'APP_KEY', 'status' => 'fail', 'message' => '未配置，请运行 php artisan key:generate'];
        return false;
    }

    /**
     * 验证核心模块
     */
    private function verifyCoreModules(?string $module): bool
    {
        $allPassed = true;

        $coreModules = [
            'core' => 'Kylin\Core\CoreServiceProvider',
            'licensing' => 'Kylin\Licensing\LicensingServiceProvider',
            'rbac' => 'Kylin\Rbac\RbacServiceProvider',
        ];

        foreach ($coreModules as $name => $class) {
            if ($module && $module !== $name) {
                continue;
            }
            if (class_exists($class)) {
                $this->results[] = ['item' => "核心模块 [{$name}]", 'status' => 'pass', 'message' => '已加载'];
            } else {
                $this->results[] = ['item' => "核心模块 [{$name}]", 'status' => 'fail', 'message' => '未加载'];
                $allPassed = false;
            }
        }

        return $allPassed;
    }

    /**
     * 验证可选模块配置
     */
    private function verifyOptionalModules(?string $module): bool
    {
        $allPassed = true;

        $optionalModules = [
            'user' => ['config' => 'kylin-user', 'label' => '用户管理'],
            'auth' => ['config' => 'kylin-auth', 'label' => '认证授权'],
            'settings' => ['config' => 'kylin-settings', 'label' => '系统设置'],
            'audit-log' => ['config' => 'kylin-audit-log', 'label' => '审计日志'],
            'dictionary' => ['config' => 'kylin-dictionary', 'label' => '数据字典'],
            'storage' => ['config' => 'kylin-storage', 'label' => '多云存储'],
            'adminlte' => ['config' => 'kylin-adminlte', 'label' => 'AdminLTE'],
            'media' => ['config' => 'kylin-media', 'label' => '媒体管理'],
            'activity' => ['config' => 'kylin-activity', 'label' => '活动管理'],
            'world' => ['config' => 'kylin-world', 'label' => '地区数据'],
        ];

        foreach ($optionalModules as $name => $info) {
            if ($module && $module !== $name) {
                continue;
            }
            $config = config($info['config']);
            if ($config !== null) {
                $this->results[] = ['item' => "可选模块 [{$info['label']}]", 'status' => 'pass', 'message' => '配置已加载'];
            } else {
                $this->results[] = ['item' => "可选模块 [{$info['label']}]", 'status' => 'fail', 'message' => '配置未加载'];
                $allPassed = false;
            }
        }

        return $allPassed;
    }

    /**
     * 验证安全配置
     */
    private function verifySecurityConfig(): bool
    {
        $allPassed = true;

        // 环境检查
        if (app()->isProduction() && config('app.debug')) {
            $this->results[] = ['item' => 'APP_DEBUG', 'status' => 'fail', 'message' => '生产环境不应开启 DEBUG'];
            $allPassed = false;
        } else {
            $this->results[] = ['item' => 'APP_DEBUG', 'status' => 'pass', 'message' => '配置正确'];
        }

        // HTTPS 检查
        if (config('session.secure')) {
            $this->results[] = ['item' => 'HTTPS', 'status' => 'pass', 'message' => '会话安全 Cookie 已启用'];
        } else {
            $this->results[] = ['item' => 'HTTPS', 'status' => 'fail', 'message' => '生产环境建议启用 session.secure'];
            $allPassed = false;
        }

        return $allPassed;
    }
}