<?php
/**
 * 芋头CMS
 * ============================================================================
 * 版权所有 2016-2028 沅陵县乌托邦网络服务有限公司，并保留所有权利。
 * 网站地址: http://www.yutoucms.cn
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 * Author: 芋头 <mxgsf@qq.com>
 * Date: 2026-6-10
 */

namespace Core\Lib;

require_once __DIR__ . '/license_guard.php';
require_once __DIR__ . '/safe_zip.php';

class ModuleLoader
{
    private static $registry = [
        'pro.order' => [
            'title' => '订单中心',
            'required_level' => License::LEVEL_PRO,
            'feature' => 'order_manage',
            'premium_path' => 'modules-premium/pro/order/index.php',
        ],
        'pro.pay_order' => [
            'title' => '支付订单',
            'required_level' => License::LEVEL_PRO,
            'feature' => 'order_manage',
            'premium_path' => 'modules-premium/pro/order/pay_order.php',
        ],
        'pro.payment' => [
            'title' => '支付设置',
            'required_level' => License::LEVEL_PRO,
            'feature' => 'payment_alipay',
            'premium_path' => 'modules-premium/pro/payment/index.php',
        ],
        'pro.recharge' => [
            'title' => '充值记录',
            'required_level' => License::LEVEL_PRO,
            'feature' => 'recharge',
            'premium_path' => 'modules-premium/pro/recharge/index.php',
        ],
        'pro.version' => [
            'title' => '在线升级',
            'required_level' => License::LEVEL_BASIC,
            'premium_path' => 'modules-premium/pro/version/index.php',
        ],
    ];

    private $license;

    public function __construct($license = null)
    {
        $this->license = LicenseGuard::getLicense($license);
    }

    public function includeModule($moduleKey)
    {
        $module = $this->getModuleConfig($moduleKey);
        $requiredLevel = intval($module['required_level'] ?? License::LEVEL_FREE);
        $feature = isset($module['feature']) ? trim((string) $module['feature']) : '';

        if ($this->license->getLevel() < $requiredLevel) {
            $this->renderUpgradeRequired($module, '当前授权级别不足，无法使用该功能');
            return false;
        }

        if ($feature !== '' && !LicenseGuard::hasFeature($feature, $this->license)) {
            $this->renderUpgradeRequired($module, LicenseGuard::getDeniedMessage($feature, $this->license));
            return false;
        }

        $moduleFile = $this->resolveExistingModuleFile($module);
        if ($moduleFile === null) {
            $syncResult = $this->syncAuthorizedModules();
            $moduleFile = $this->resolveExistingModuleFile($module);
            if ($moduleFile === null) {
                $extraMessage = is_array($syncResult) && !empty($syncResult['msg']) ? $syncResult['msg'] : '';
                $this->renderModuleMissing($module, $extraMessage);
                return false;
            }
        }

        require $moduleFile;
        return true;
    }

    public function syncAuthorizedModules()
    {
        $status = $this->license->getStatus();
        $licenseKey = trim((string) ($status['license_key'] ?? ''));
        $domain = trim((string) ($status['domain'] ?? ($_SERVER['HTTP_HOST'] ?? '')));
        $level = intval($status['level'] ?? License::LEVEL_FREE);

        if ($level <= License::LEVEL_FREE || $licenseKey === '' || strpos($licenseKey, 'FREE-') === 0) {
            return [
                'code' => 400,
                'msg' => '当前授权无需同步商业模块',
            ];
        }

        if (!class_exists('ZipArchive')) {
            return [
                'code' => 500,
                'msg' => '服务器未启用 ZipArchive，无法安装商业模块',
            ];
        }

        $licenseCenterUrl = defined('LICENSE_CENTER_URL') ? LICENSE_CENTER_URL : 'http://yutou.wtbidc.cn/license-center';
        $apiUrl = rtrim($licenseCenterUrl, '/') . '/api.php?action=module_package';
        $payload = json_encode([
            'license_key' => $licenseKey,
            'domain' => $domain,
        ]);

        $ch = curl_init($apiUrl);
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $payload,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 20,
            CURLOPT_CONNECTTIMEOUT => 8,
            CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        ]);
        $body = curl_exec($ch);
        $httpCode = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
        $curlErr = curl_error($ch);
        $curlErrno = curl_errno($ch);
        curl_close($ch);

        if ($body === false || $curlErrno) {
            return [
                'code' => 500,
                'msg' => $curlErr !== '' ? $curlErr : '无法连接授权平台下载商业模块',
            ];
        }

        if ($httpCode !== 200 || substr($body, 0, 2) !== 'PK') {
            $json = json_decode($body, true);
            if (is_array($json) && isset($json['msg'])) {
                return [
                    'code' => intval($json['code'] ?? 500),
                    'msg' => (string) $json['msg'],
                ];
            }

            return [
                'code' => 500,
                'msg' => '授权平台未返回有效的模块压缩包',
            ];
        }

        $tempZip = tempnam(sys_get_temp_dir(), 'modpkg_');
        if ($tempZip === false) {
            return [
                'code' => 500,
                'msg' => '无法创建临时文件',
            ];
        }

        file_put_contents($tempZip, $body);
        $zip = new \ZipArchive();
        $openResult = $zip->open($tempZip);
        if ($openResult !== true) {
            @unlink($tempZip);
            return [
                'code' => 500,
                'msg' => '商业模块压缩包无法解压',
            ];
        }

        $root = rtrim($this->rootPath(''), '/\\');
        try {
            $ok = SafeZip::extract($zip, $root);
        } catch (\Throwable $e) {
            $ok = false;
        } finally {
            $zip->close();
            @unlink($tempZip);
        }

        if (!$ok) {
            return [
                'code' => 500,
                'msg' => '商业模块写入失败',
            ];
        }

        return [
            'code' => 200,
            'msg' => '商业模块同步成功',
            'modules' => self::getModuleKeysForLevel($level),
        ];
    }

    public static function getModuleKeysForLevel($level)
    {
        $level = intval($level);
        if ($level >= License::LEVEL_PRO) {
            return ['pro.order', 'pro.pay_order', 'pro.payment', 'pro.recharge', 'pro.version'];
        }
        if ($level >= License::LEVEL_BASIC) {
            return ['pro.version'];
        }
        return [];
    }

    private function getModuleConfig($moduleKey)
    {
        if (!isset(self::$registry[$moduleKey])) {
            throw new \InvalidArgumentException('Unknown module key: ' . $moduleKey);
        }

        return self::$registry[$moduleKey];
    }

    private function resolveExistingModuleFile(array $module)
    {
        $candidates = [];
        if (!empty($module['premium_path'])) {
            $candidates[] = $this->rootPath($module['premium_path']);
        }
        if (!empty($module['legacy_path'])) {
            $candidates[] = $this->rootPath($module['legacy_path']);
        }

        foreach ($candidates as $file) {
            if (is_file($file)) {
                return $file;
            }
        }

        return null;
    }

    private function rootPath($relativePath)
    {
        $root = defined('ROOT_PATH') ? ROOT_PATH : dirname(__DIR__, 2) . DIRECTORY_SEPARATOR;
        return rtrim($root, '/\\') . DIRECTORY_SEPARATOR . str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $relativePath);
    }

    private function renderUpgradeRequired(array $module, $message)
    {
        $title = htmlspecialchars($module['title'], ENT_QUOTES, 'UTF-8');
        $message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');

        echo '<div style="padding:48px 24px;">';
        echo '<div style="max-width:760px;margin:0 auto;background:linear-gradient(135deg,#fff7ed 0%,#ffffff 100%);border:1px solid #fdba74;border-radius:20px;box-shadow:0 24px 60px rgba(249,115,22,0.12);padding:36px;">';
        echo '<div style="display:inline-flex;align-items:center;gap:8px;padding:6px 12px;border-radius:999px;background:#fff;color:#c2410c;border:1px solid #fdba74;font-size:12px;font-weight:700;">需升级授权</div>';
        echo '<h2 style="margin:18px 0 10px;font-size:30px;line-height:1.2;color:#111827;">' . $title . ' 未解锁</h2>';
        echo '<p style="margin:0;color:#6b7280;font-size:15px;line-height:1.8;">' . $message . '</p>';
        echo '<div style="margin-top:24px;display:flex;gap:12px;flex-wrap:wrap;">';
        echo '<a href="?act=auth" style="display:inline-flex;align-items:center;justify-content:center;padding:14px 24px;border-radius:12px;background:linear-gradient(135deg,#ea580c 0%,#dc2626 100%);color:#fff;text-decoration:none;font-weight:700;box-shadow:0 14px 30px rgba(220,38,38,0.22);">立即升级授权</a>';
        echo '<a href="?act=dashboard" style="display:inline-flex;align-items:center;justify-content:center;padding:14px 24px;border-radius:12px;background:#fff;color:#374151;text-decoration:none;border:1px solid #e5e7eb;font-weight:600;">返回首页</a>';
        echo '</div>';
        echo '</div>';
        echo '</div>';
    }

    private function renderModuleMissing(array $module, $extraMessage = '')
    {
        $title = htmlspecialchars($module['title'], ENT_QUOTES, 'UTF-8');
        $extra = $extraMessage !== '' ? '<p style="margin:14px 0 0;color:#b91c1c;font-size:13px;line-height:1.7;">同步失败原因：' . htmlspecialchars($extraMessage, ENT_QUOTES, 'UTF-8') . '</p>' : '';

        echo '<div style="padding:48px 24px;">';
        echo '<div style="max-width:760px;margin:0 auto;background:#ffffff;border:1px solid #e5e7eb;border-radius:20px;box-shadow:0 20px 50px rgba(15,23,42,0.08);padding:36px;">';
        echo '<div style="display:inline-flex;align-items:center;gap:8px;padding:6px 12px;border-radius:999px;background:#eff6ff;color:#1d4ed8;border:1px solid #bfdbfe;font-size:12px;font-weight:700;">模块未安装</div>';
        echo '<h2 style="margin:18px 0 10px;font-size:30px;line-height:1.2;color:#111827;">' . $title . ' 模块不存在</h2>';
        echo '<p style="margin:0;color:#6b7280;font-size:15px;line-height:1.8;">当前授权已允许此功能，但本地尚未安装对应商业模块文件。后续接入授权平台自动下发模块后，这里会优先从 <code>modules-premium</code> 加载。</p>';
        echo $extra;
        echo '<div style="margin-top:24px;display:flex;gap:12px;flex-wrap:wrap;">';
        echo '<a href="?act=auth" style="display:inline-flex;align-items:center;justify-content:center;padding:14px 24px;border-radius:12px;background:#2563eb;color:#fff;text-decoration:none;font-weight:700;">查看授权信息</a>';
        echo '<a href="?act=dashboard" style="display:inline-flex;align-items:center;justify-content:center;padding:14px 24px;border-radius:12px;background:#fff;color:#374151;text-decoration:none;border:1px solid #e5e7eb;font-weight:600;">返回首页</a>';
        echo '</div>';
        echo '</div>';
        echo '</div>';
    }
}
