<?php

namespace XZD\AI\V5\Admin;

/**
 * 后台菜单注册 + Vue SPA 容器渲染
 *
 * 布局设计（参考 dashboard.html）：
 * - #xzd-ai-app 使用 position:fixed 锚定视口（top:32px, left:164px）
 * - Vue AdminShell 侧边栏使用 position:absolute 在此容器内固定
 * - 内容区 height:100%（继承 fixed 容器），overflow-y:auto 独立滚动
 * - 不依赖任何父元素高度链，避免内容溢出无法滚动
 * - body.folded 时容器 left 值调整为 40px
 */
class AdminPage
{
    private string $slug = 'xzdbk-ai';
    private string $capability = 'manage_options';

    /**
     * 初始化 — 注册 WP 钩子
     */
    public function init(): void
    {
        add_action('admin_menu', [$this, 'registerMenu']);
        add_action('admin_enqueue_scripts', [$this, 'enqueueAssets']);
    }

    /**
     * 注册后台菜单 — 仅1个主菜单，无子菜单展开
     */
    public function registerMenu(): void
    {
        add_menu_page(
            '小栈AI',
            '小栈AI',
            $this->capability,
            $this->slug,
            [$this, 'render'],
            'dashicons-superhero',
            30
        );
    }

    /**
     * 渲染 SPA 容器
     *
     * 注意：不做页面判断，所有菜单共享此容器。
     * Vue Router 根据 URL hash 切换页面组件。
     */
    public function render(): void
    {
        // V3.1.7 安全修复：渲染前检查 WP 权限（add_menu_page 只控制菜单显示，不阻止直接 URL 访问）
        if (!current_user_can($this->capability)) {
            wp_die(__('抱歉，您没有权限访问此页面。', 'xzd-ai'));
        }
        ?>
        <div id="xzd-ai-app" class="xzd-ai-admin-shell">
            <!-- Vue 3 SPA 挂载点 -->
            <div class="xzd-ai-loading">
                <div class="xzd-ai-loading-spinner"></div>
                <p>小栈AI 加载中...</p>
            </div>
        </div>
        <?php
    }

    /**
     * 加载资源
     */
    public function enqueueAssets(string $hook): void
    {
        // 仅在小栈AI页面加载
        if (strpos($hook, $this->slug) === false) {
            return;
        }

        // 内联 CSS — SPA 容器后备样式（Vue加载前使用）
        wp_add_inline_style('wp-admin', $this->getShellCSS());

        // 加载编译后的 Vue SPA
        $this->enqueueBuiltAssets();

        // 向 JS 注入配置
        wp_localize_script('xzd-ai-app', 'xzdConfig', $this->getJsConfig());

        // 加载 WordPress 原生脚本
        wp_enqueue_script('wp-api');
        wp_enqueue_media();  // 媒体库选择器（水印图片选择等）

        // ★ 关键：给 xzd-ai-app 添加 type="module"
        add_filter('script_loader_tag', [$this, 'addModuleAttribute'], 10, 2);
    }

    /**
     * 为 Vue SPA 脚本添加 type="module" 属性
     *
     * WordPress 默认输出 type='text/javascript'，必须替换为 type='module'
     * 否则浏览器按普通脚本执行，遇到 import 语句直接报错
     */
    public function addModuleAttribute(string $tag, string $handle): string
    {
        // ★ 所有 xzd-ai 相关脚本都需要 type="module"（含 vendor chunks）
        if ($handle === 'xzd-ai-app' || str_starts_with($handle, 'xzd-ai-')) {
            $tag = str_replace("type='text/javascript'", '', $tag);
            $tag = str_replace('type="text/javascript"', '', $tag);
            return str_replace('<script ', '<script type="module" crossorigin ', $tag);
        }
        return $tag;
    }

    /**
     * 加载 Vite 构建产物
     */
    private function enqueueBuiltAssets(): void
    {
        $assetsDir = XZD_AI_DIR . 'assets/';

        // ★ 分包优化：加载所有构建产物 JS（index.js + naive-ui.[hash].js + vue-vendor.[hash].js 等）
        $allJsFiles = glob($assetsDir . 'js/*.js');
        $cssFiles   = glob($assetsDir . 'css/index*.css');

        if (!empty($cssFiles)) {
            usort($cssFiles, fn($a, $b) => filemtime($b) - filemtime($a));
            $cssFile = $cssFiles[0];
            $cssUrl = XZD_AI_URL . 'assets/css/' . basename($cssFile);
            wp_enqueue_style('xzd-ai-app', $cssUrl, [], XZD_AI_VERSION);
        }

        if (!empty($allJsFiles)) {
            // index.js 作为主入口最后加载，vendor chunk 优先加载
            $vendorFiles = [];
            $entryFile   = null;
            foreach ($allJsFiles as $f) {
                $bn = basename($f);
                if ($bn === 'index.js') {
                    $entryFile = $f;
                } elseif (str_starts_with($bn, 'vendor')) {
                    $vendorFiles[] = $f;
                }
            }

            // 先注册 vendor chunks（作为 xzd-ai-app 的依赖）
            foreach ($vendorFiles as $f) {
                $handle = 'xzd-ai-vendor';
                wp_enqueue_script($handle, XZD_AI_URL . 'assets/js/' . basename($f), [], XZD_AI_VERSION, true);
                break; // 只有一个 vendor chunk
            }

            // 主入口 index.js 依赖 vendor chunk
            if ($entryFile) {
                wp_enqueue_script('xzd-ai-app', XZD_AI_URL . 'assets/js/index.js', ['xzd-ai-vendor'], XZD_AI_VERSION, true);
            }
        }
    }

    /**
     * Shell CSS — 外层容器 + 隐藏通知
     */
    private function getShellCSS(): string
    {
        return '
            /* 隐藏 WP 通知和 Screen Options */
            .notice,.notice-error,.notice-warning,.notice-success,.notice-info,
            .update-nag,.updated,.error,#setting-error-tgmpa,#message,.wp-header-end,
            #screen-meta, #screen-meta-links { display:none!important }

            /*
             * 外层容器 — position:fixed 锚定视口
             * --xzd-offset-left CSS 变量传递给 Vue AdminShell 侧边栏（position:fixed）
             * 内容区不依赖父元素高度链，直接使用 calc(100vh - 32px)
             */
            #xzd-ai-app.xzd-ai-admin-shell {
                --xzd-offset-left: 164px;
                --xzd-offset-bottom: 32px;
                position: fixed;
                top: 32px;
                left: var(--xzd-offset-left);
                right: 0;
                bottom: var(--xzd-offset-bottom);
                overflow: hidden;
                padding: 0;
                box-sizing: border-box;
                background: #F4F4F5;
            }
            /* WP 侧边栏折叠时，左偏移跟随变化 */
            body.folded #xzd-ai-app.xzd-ai-admin-shell {
                --xzd-offset-left: 40px;
            }

            /* Vue SPA 加载前占位 */
            .xzd-ai-loading {
                display:flex;flex-direction:column;
                align-items:center;justify-content:center;
                height:100%;color:#71717A;font-size:14px;
                background:#F4F4F5;
            }
            .xzd-ai-loading-spinner {
                width:36px;height:36px;
                border:3px solid #E4E4E7;
                border-top-color:#18181B;
                border-radius:50%;
                animation:xzd-spin .8s linear infinite;
                margin-bottom:12px;
            }
            @keyframes xzd-spin { to{transform:rotate(360deg)} }

            /* 移动端：容器占满宽度，侧边栏 overlay */
            @media (max-width:768px) {
                #xzd-ai-app.xzd-ai-admin-shell {
                    left:0; margin:0;
                }
                body.folded #xzd-ai-app.xzd-ai-admin-shell {
                    left:0;
                }
            }
        ';
    }

    /**
     * 注入到前端的配置数据
     */
    private function getJsConfig(): array
    {
        $page = $_GET['page'] ?? $this->slug;
        $vueRoute = $this->mapPageToRoute($page);

        return [
            'restUrl'      => rest_url(XZD_AI_REST_NAMESPACE),
            'restNonce'    => wp_create_nonce('wp_rest'),
            'adminUrl'     => admin_url('admin.php'),
            'pluginUrl'    => XZD_AI_URL,
            'version'      => XZD_AI_VERSION,
            'currentUser'  => [
                'id'    => get_current_user_id(),
                'name'  => wp_get_current_user()->display_name,
                'role'  => 'admin',
            ],
            'nonce'        => wp_create_nonce('xzdbk_ai_admin'),
            'initialRoute'  => $vueRoute,
            'currentPage'   => $page,
        ];
    }

    /**
     * WP 页面 slug → Vue 路由映射
     */
    private function mapPageToRoute(string $page): string
    {
        // 从URL hash读取路由，默认仪表盘
        $hash = $_SERVER['REQUEST_URI'] ?? '';
        if (preg_match('/#(\/[a-z0-9_\/-]*)/', $hash, $m)) {
            return $m[1];
        }
        return '/';
    }

    /**
     * 获取当前页面的 slug
     */
    public static function getSlug(): string
    {
        return (new self())->slug;
    }
}
