<?php

namespace XZD\AI\V5\Admin;

/**
 * 后台菜单注册 + Vue SPA 容器渲染
 *
 * #xzd-ai-app 使用 position:fixed 锚定视口，Vue AdminShell 侧边栏 position:absolute 在此容器内固定。
 * 内容区不依赖父元素高度链，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
    {
        // 渲染前检查 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
    }

    /**
     * 加载资源 — 仅在小栈AI页面加载
     */
    public function enqueueAssets(string $hook): void
    {
        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 默认的 text/javascript
     */
    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/';

        // 加载 CSS — glob 匹配 hash 文件名
        $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);
            $cssVer  = filemtime($cssFile);
            wp_enqueue_style('xzd-ai-app', $cssUrl, [], $cssVer);
        }

        // 加载 JS 入口 — glob 匹配 index.{hash}.js（V3.2: 入口文件名带 hash）
        $entryFiles = glob($assetsDir . 'js/index.*.js');
        if (!empty($entryFiles)) {
            usort($entryFiles, fn($a, $b) => filemtime($b) - filemtime($a));
            $entryFile = $entryFiles[0];
            $entryUrl  = XZD_AI_URL . 'assets/js/' . basename($entryFile);
            $entryVer  = filemtime($entryFile);
            // V3.2: 不再手动加载 vendor chunk，ES module import 自动处理依赖
            wp_enqueue_script('xzd-ai-app', $entryUrl, [], $entryVer, 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 传递给 Vue AdminShell 侧边栏；内容区 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)} }

            /* 移动端（≤782px WP管理栏变46px）：全宽 + dvh + 防穿透滚动 */
            @media (max-width:782px) {
                #xzd-ai-app.xzd-ai-admin-shell {
                    top: 46px;
                    left:0; margin:0;
                    --xzd-offset-bottom: 0;
                    bottom: 0;
                }
                body.folded #xzd-ai-app.xzd-ai-admin-shell {
                    left:0;
                }
            }
            /* 小平板（768-782px）：WP管理栏已变46px但侧边栏还在 */
            @media (min-width:769px) and (max-width:782px) {
                #xzd-ai-app.xzd-ai-admin-shell {
                    top: 46px;
                }
            }

            /* 防止 iOS 输入框聚焦时自动缩放 */
            #xzd-ai-app input, #xzd-ai-app textarea, #xzd-ai-app select {
                font-size: 16px;
            }
        ';
    }

    /**
     * 注入到前端的配置数据
     */
    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;
    }
}
