<?php

namespace XZD\AI\V5\UI;

/**
 * 全局 AI 对话弹窗 — 前/后台通用浮动组件
 *
 * 注入方式: wp_footer (前台) + admin_footer (后台)
 * 技术栈: Vanilla JS（零框架依赖）
 * 通信: REST API + SSE 流式
 * 持久化: localStorage 跨页面会话恢复
 *
 * 架构: PHP render() 输出纯 HTML 骨架（初始 display:none），
 *       floating-chat.js 负责事件绑定和 DOM 操作。
 *       面板/触发按钮默认隐藏，JS 初始化完成后显示触发按钮。
 */
class FloatingChat
{
    /** 防止同一页面重复渲染（某些主题 wp_footer + admin_footer 同时触发） */
    private static bool $rendered = false;

    /**
     * 初始化 — 注册 WordPress 钩子
     */
    public function init(): void
    {
        add_action('wp_footer', [$this, 'render']);
        add_action('admin_footer', [$this, 'render']);
        add_action('wp_enqueue_scripts', [$this, 'enqueueAssets']);
        add_action('admin_enqueue_scripts', [$this, 'enqueueAssets']);
    }

    /**
     * 加载 CSS / JS
     */
    public function enqueueAssets(): void
    {
        // 弹窗样式
        $cssFile = XZD_AI_DIR . 'assets/standalone/floating-chat.css';
        wp_enqueue_style(
            'xzd-floating-chat',
            XZD_AI_URL . 'assets/standalone/floating-chat.css',
            [],
            file_exists($cssFile) ? filemtime($cssFile) : XZD_AI_VERSION
        );

        // Vanilla JS 组件（零依赖）
        $jsFile = XZD_AI_DIR . 'assets/standalone/floating-chat.js';
        wp_enqueue_script(
            'xzd-floating-chat',
            XZD_AI_URL . 'assets/standalone/floating-chat.js',
            [],                        // 无依赖
            file_exists($jsFile) ? filemtime($jsFile) : XZD_AI_VERSION,
            true                       // footer
        );

        // 注入 CSS 变量（浮动按钮自定义）
        $this->injectButtonCSSVars();

        // 注入配置
        wp_localize_script('xzd-floating-chat', 'xzdChatConfig', $this->getJsConfig());
    }

    /**
     * 渲染弹窗 HTML 骨架
     *
     * 全部元素默认隐藏，JS 初始化后显示触发按钮。
     */
    public function render(): void
    {
        if (self::$rendered) return;
        self::$rendered = true;

        $isAdmin   = current_user_can('manage_options');
        $isLoggedIn = is_user_logged_in();
        $licenseLevel = \XZD\AI\V5\Core\LicenseService::instance()->getLevel();
        $isPro = $licenseLevel !== 'free';
        $isUltimate = $licenseLevel === 'ultimate';

        // 智能欢迎卡片：按身份+等级动态生成
        $welcomeCards = [];
        $welcomeHints = [];
        $userName = $isLoggedIn ? wp_get_current_user()->display_name : '';

        if ($isAdmin) {
            $welcomeCards[] = ['hint' => '帮我写一篇新文章', 'icon' => 'edit', 'label' => '内容管理', 'desc' => '写文章、生成标签、SEO优化'];
            $welcomeCards[] = ['hint' => '查看站点统计数据', 'icon' => 'settings', 'label' => '站点管理', 'desc' => '查看统计、管理评论'];
            if ($isPro) {
                $welcomeCards[] = ['hint' => '执行一次批量文章处理', 'icon' => 'automation', 'label' => '自动化', 'desc' => '流水线、定时任务、批量操作'];
            }
            $welcomeHints = ['查看最近的5篇文章', '查看站点统计数据', '给最近发布的文章生成标签', '分析网站SEO状况'];
            if ($isPro) {
                $welcomeHints[] = '批量处理最近发布的文章';
            }
        } elseif ($isLoggedIn) {
            $welcomeCards[] = ['hint' => '查看我的积分余额', 'icon' => 'coins', 'label' => '我的积分', 'desc' => '查看积分余额和记录'];
            $welcomeCards[] = ['hint' => '帮我签到', 'icon' => 'checkin', 'label' => '每日签到', 'desc' => '签到领取积分奖励'];
            $welcomeCards[] = ['hint' => '查看我发布的文章', 'icon' => 'docs', 'label' => '我的文章', 'desc' => '查看文章列表和状态'];
            $welcomeCards[] = ['hint' => '查看我的VIP等级和到期时间', 'icon' => 'vip', 'label' => 'VIP状态', 'desc' => '查看会员等级和权益'];
            $welcomeHints = ['查看我的积分余额', '帮我签到', '查看我发布的文章', '查看VIP等级'];
        } else {
            $welcomeCards[] = ['hint' => '搜索关于WordPress的文章', 'icon' => 'search', 'label' => '浏览网站', 'desc' => '搜索文章、最新内容'];
            $welcomeCards[] = ['hint' => '介绍一下这个网站', 'icon' => 'info', 'label' => '了解本站', 'desc' => '站点介绍、热门文章'];
            $welcomeCards[] = ['hint' => '最近发布了什么热门文章', 'icon' => 'trending', 'label' => '热门内容', 'desc' => '最新发布、热门推荐'];
            $welcomeHints = ['搜索关于WordPress的文章', '介绍一下这个网站', '最近发布了什么文章', '热门文章有哪些'];
        }

        // SVG 图标映射
        $cardIcons = [
            'edit'    => '<path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/>',
            'settings'=> '<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>',
            'automation'=> '<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6h-2zm0 8h2v2h-2z"/>',
            'coins'   => '<circle cx="12" cy="12" r="10"/><path d="M8 14s1.5 2 4 2 4-2 4-2"/><line x1="9" y1="9" x2="15" y2="9"/><line x1="10" y1="6" x2="14" y2="6"/>',
            'checkin' => '<polyline points="20 6 9 17 4 12"/>',
            'docs'    => '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/>',
            'vip'     => '<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>',
            'search'  => '<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>',
            'info'    => '<circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/>',
            'trending'=> '<polyline points="23 6 13.5 15.5 8.5 10.5 1 18"/><polyline points="17 6 23 6 23 12"/>',
        ];
        $welcomeSubtitle = $isAdmin ? '管理员模式，可操作全部工具' : ($isLoggedIn ? "你好 {$userName}，我可以帮你查询数据" : '你好，我是AI助手，可以帮你浏览网站');

        $aiIdentity = \XZD\AI\V5\Core\Config::instance()->resolveAIIdentity();
        $aiName   = $aiIdentity['name'];
        $aiAvatar = $this->resolveAiAvatar($aiIdentity);
        $btnConfig = \XZD\AI\V5\Core\Config::instance()->get('floating_button', []);
        $tooltipText = $btnConfig['tooltip_text'] ?? '';
        $iconType  = $btnConfig['icon_type'] ?? 'preset';
        $iconImage = $btnConfig['custom_image_url'] ?? '';
        $avatarHtml = '<img src="' . $this->safeUrl($aiAvatar) . '" class="xzd-chat-logo" style="width:28px;height:28px;border-radius:50%;object-fit:cover" alt="" onerror="var f=this.getAttribute(\'data-fb\');if(this.src!==f)this.src=f" data-fb="' . esc_attr($this->defaultAvatarUrl()) . '">';
        $defaultAvt = $this->defaultAvatarUrl();
        $modelName = $this->getActiveModel() ?: 'AI 助手';
        ?>
        <!-- 小栈AI 全局对话弹窗 -->
        <div id="xzd-chat-root" style="position:fixed;inset:0;pointer-events:none;z-index:999999;">

            <!-- 触发按钮 -->
            <button id="xzd-chat-trigger" class="xzd-chat-trigger" title="<?php echo esc_attr($tooltipText ?: $aiName); ?>" aria-label="打开AI助手">
                <?php if ($iconType === 'image' && $iconImage): ?>
                    <img src="<?php echo esc_url($iconImage); ?>" alt="" style="width:100%;height:100%;border-radius:inherit;object-fit:cover">
                <?php elseif ($iconType === 'svg' && !empty($btnConfig['icon_custom'])):
                    // ★ 完整SVG（来自iconfont等）→ 直接输出原始SVG，保留多色
                    $parsed = $this->parseSvgIcon($btnConfig['icon_custom']);
                    if ($parsed['is_full']): ?>
                    <svg viewBox="<?php echo esc_attr($parsed['viewBox']); ?>" width="24" height="24" style="display:block"><?php echo $parsed['inner']; ?></svg>
                <?php else: ?>
                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <?php echo $parsed['inner']; ?>
                    </svg>
                <?php endif; else: ?>
                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
                    </svg>
                <?php endif; ?>
                <span id="xzd-chat-badge" class="xzd-chat-badge" style="display:none;"></span>
            </button>

            <!-- 面板 — 初始 display:none -->
            <div id="xzd-chat-panel" class="xzd-chat-panel">

                <!-- 冰晶折射Canvas背景 -->
                <canvas id="xzd-fx-canvas" class="xzd-fx-canvas"></canvas>

                <!-- 头部 -->
                <div id="xzd-chat-header" class="xzd-chat-header">
                    <div class="xzd-chat-header-left">
                        <span class="xzd-chat-logo"><?php echo $avatarHtml; ?><span class="xzd-online-dot"></span></span>
                        <span class="xzd-chat-header-titles">
                            <span class="xzd-chat-title"><?php echo esc_html($aiName); ?></span>
                            <span class="xzd-chat-subtitle"><?php echo esc_html($modelName); ?></span>
                        </span>
                        <?php if ($isAdmin): ?>
                        <span class="xzd-chat-admin-badge">管理员模式</span>
                        <?php endif; ?>
                    </div>
                    <div class="xzd-chat-header-right">
                        <button id="xzd-chat-new" class="xzd-chat-btn-icon" data-tooltip="新建对话" aria-label="新建对话">
                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
                        </button>
                        <button id="xzd-chat-sessions-btn" class="xzd-chat-btn-icon" data-tooltip="历史对话" aria-label="历史对话">
                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
                        </button>
                        <button id="xzd-chat-close" class="xzd-chat-btn-icon" data-tooltip="关闭" aria-label="关闭">
                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                        </button>
                    </div>
                </div>

                <!-- 会话列表 -->
                <div id="xzd-chat-sessions" class="xzd-chat-sessions" style="display:none;">
                    <div class="xzd-chat-sessions-header">
                        <span>历史对话</span>
                        <button id="xzd-chat-sessions-close" class="xzd-chat-btn-text">关闭</button>
                    </div>
                    <div class="xzd-chat-sessions-list">
                        <div id="xzd-chat-session-list"></div>
                    </div>
                </div>

                <!-- 消息区域 -->
                <div id="xzd-chat-messages" class="xzd-chat-messages">
                    <!-- 欢迎消息 — 智能适配用户身份和授权等级 -->
                    <div id="xzd-chat-welcome" class="xzd-chat-welcome">
                        <img src="<?php echo $this->safeUrl($aiAvatar); ?>" class="xzd-chat-avatar" style="width:52px;height:52px;border-radius:50%;object-fit:cover;margin-bottom:4px" alt="" onerror="var f=this.getAttribute('data-fb');if(this.src!==f)this.src=f" data-fb="<?php echo esc_attr($defaultAvt); ?>">
                        <h3>你好<?php echo $isLoggedIn ? '，' . esc_html($userName) : ''; ?></h3>
                        <p><?php echo esc_html($welcomeSubtitle); ?><br>试着输入你的需求吧。</p>
                        <div class="xzd-welcome-cards">
                            <?php foreach ($welcomeCards as $card): ?>
                            <button class="xzd-welcome-card" data-hint="<?php echo esc_attr($card['hint']); ?>">
                                <svg class="xzd-welcome-card-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><?php echo $cardIcons[$card['icon']] ?? ''; ?></svg>
                                <span class="xzd-welcome-card-label"><?php echo esc_html($card['label']); ?></span>
                                <span class="xzd-welcome-card-desc"><?php echo esc_html($card['desc']); ?></span>
                            </button>
                            <?php endforeach; ?>
                        </div>
                        <?php if (!empty($welcomeHints)): ?>
                        <div class="xzd-chat-welcome-hints" style="margin-top:12px;">
                            <?php foreach ($welcomeHints as $hint): ?>
                            <button class="xzd-chat-hint" data-hint="<?php echo esc_attr($hint); ?>"><?php echo esc_html($hint); ?></button>
                            <?php endforeach; ?>
                        </div>
                        <?php endif; ?>
                    </div>
                </div>

                <!-- 输入区 -->
                <div class="xzd-chat-input-area">
                    <textarea id="xzd-chat-input"
                              class="xzd-chat-input"
                              placeholder="输入消息... (Enter 发送, Shift+Enter 换行)"
                              rows="1"></textarea>
                    <button id="xzd-chat-send-btn" class="xzd-chat-send-btn" disabled aria-label="发送">
                        <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
                            <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
                        </svg>
                    </button>
                </div>

                <!-- 状态栏 -->
                <div id="xzd-chat-status-bar" class="xzd-chat-status-bar" style="display:none;">
                    <span>剩余配额: <strong id="xzd-chat-quota">—</strong></span>
                    <span>身份: <strong id="xzd-chat-identity">—</strong></span>
                </div>
            </div>
        </div>
        <?php
    }

    /**
     * 文章编辑页隐藏浮动聊天触发按钮（避免与编辑器面板冲突）
     */
    private function shouldHideTrigger(): bool
    {
        global $pagenow;
        return in_array($pagenow, ['post.php', 'post-new.php'], true);
    }

    /**
     * 注入浮动按钮 CSS 变量
     */
    public function injectButtonCSSVars(): void
    {
        $btn = \XZD\AI\V5\Core\Config::instance()->get('floating_button', []);

        $integrationMode = $btn['integration_mode'] ?? 'standalone';
        $tooltipText     = $btn['tooltip_text'] ?? '';

        $position  = $btn['position'] ?? 'right';
        $hOffset   = (int)($btn['h_offset'] ?? 24);
        $vPosition = $btn['v_position'] ?? 'bottom';
        $vOffset   = (int)($btn['v_offset'] ?? 24);
        $mobileH   = $btn['mobile_h_position'] ?? $position;
        $mobileHO  = (int)($btn['mobile_h_offset'] ?? 16);
        $mobileV   = $btn['mobile_v_position'] ?? $vPosition;
        $mobileVO  = (int)($btn['mobile_v_offset'] ?? 16);
        $mobileIndependent = !empty($btn['mobile_independent']);

        $shape  = $btn['shape'] ?? 'rounded';
        $size   = (int)($btn['size'] ?? 56);
        $bgColor = $btn['bg_color'] ?? '#0D9373';
        $gradient = $btn['gradient'] ?? 'gradient1';
        $shadow = $btn['shadow'] ?? 'medium';
        $opacity = (int)($btn['opacity'] ?? 100) / 100;

        $icon       = $btn['icon'] ?? 'chat';
        $iconCustom = $btn['icon_custom'] ?? '';
        $iconType   = $btn['icon_type'] ?? 'preset';
        $iconImage  = $btn['custom_image_url'] ?? '';
        $iconColor  = $btn['icon_color'] ?? 'white';

        $hoverEffect = $btn['hover_effect'] ?? 'scale';
        $fabAnimation = $btn['fab_animation'] ?? 'breath';
        $popupAnimation = $btn['popup_animation'] ?? 'scale';
        $breathing   = !isset($btn['breathing']) || $btn['breathing'];
        $breathSpeed = $btn['breath_speed'] ?? '4s';
        $showDelay   = (float)($btn['show_delay'] ?? 0);

        $showBadge    = !empty($btn['show_badge']);
        $badgeStyle   = $btn['badge_style'] ?? 'circle';

        $showFrontend = !isset($btn['show_frontend']) || $btn['show_frontend'];
        $showBackend  = !isset($btn['show_backend']) || $btn['show_backend'];
        $articleOnly  = !empty($btn['article_only']);
        $excludePaths = $btn['exclude_paths'] ?? '';
        $showMobile   = !isset($btn['show_mobile']) || $btn['show_mobile'];

        $welcomeTitle = $btn['welcome_title'] ?? '';
        $welcomeDesc  = $btn['welcome_desc'] ?? '';
        $hintPrompts  = $btn['hint_prompts'] ?? [];

        // 阴影映射
        $shadowMap = [
            'light'  => '0 2px 8px rgba(0,0,0,0.12)',
            'medium' => '0 2px 16px rgba(79,70,229,0.30)',
            'heavy'  => '0 4px 24px rgba(0,0,0,0.25)',
        ];
        $shadowVal = $shadowMap[$shadow] ?? $shadowMap['medium'];

        // 渐变映射
        $bgValue = $bgColor;
        if ($gradient === 'gradient1') $bgValue = "linear-gradient(135deg, {$bgColor}, #7c3aed)";
        elseif ($gradient === 'gradient2') $bgValue = "linear-gradient(135deg, {$bgColor}, #06b6d4)";

        // 图标预设映射
        $iconSVGs = [
            'chat'     => '<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>',
            'robot'    => '<rect x="4" y="4" width="16" height="16" rx="2"/><circle cx="9" cy="10" r="1.5"/><circle cx="15" cy="10" r="1.5"/><path d="M9 15c1.5 2 4.5 2 6 0"/>',
            'question' => '<circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/>',
            'settings' => '<circle cx="12" cy="12" r="3"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>',
            'search'   => '<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>',
            'star'     => '<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>',
            'heart'    => '<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>',
            'download' => '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/>',
            'book'     => '<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/>',
            'mail'     => '<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/>',
            'bell'     => '<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/>',
            'home'     => '<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/>',
            'user'     => '<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',
            'cart'     => '<circle cx="9" cy="21" r="1"/><circle cx="20" cy="21" r="1"/><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"/>',
            'headset'  => '<path d="M3 11a9 9 0 1 1 18 0v3a2 2 0 0 1-2 2h-1v-4h1a7 7 0 0 0-14 0h1v4H5a2 2 0 0 1-2-2v-3z"/>',
            'news'     => '<rect x="2" y="4" width="20" height="16" rx="2"/><line x1="6" y1="8" x2="10" y2="8"/><line x1="6" y1="12" x2="14" y2="12"/><line x1="6" y1="16" x2="18" y2="16"/><rect x="16" y="8" width="4" height="8"/>',
            'building' => '<rect x="4" y="2" width="16" height="20" rx="1"/><line x1="9" y1="6" x2="9" y2="6.01"/><line x1="15" y1="6" x2="15" y2="6.01"/><line x1="9" y1="10" x2="9" y2="10.01"/><line x1="15" y1="10" x2="15" y2="10.01"/><line x1="9" y1="14" x2="9" y2="14.01"/><line x1="15" y1="14" x2="15" y2="14.01"/><path d="M9 22v-4h6v4"/>',
            'palette'  => '<circle cx="13.5" cy="6.5" r="1.5"/><circle cx="17.5" cy="10.5" r="1.5"/><circle cx="8.5" cy="7.5" r="1.5"/><circle cx="6.5" cy="12.5" r="1.5"/><path d="M12 2C6.49 2 2 6.49 2 12s4.49 10 10 10c.42 0 .83-.04 1.24-.11a2 2 0 0 0 1.48-3.12l-.72-1.15a1 1 0 0 1 .86-1.52H16c4.43 0 8-3.58 8-8S17.51 2 12 2z"/>',
            'crown'    => '<path d="M2 4l3 12h14l3-12-6 4-4-6-4 6-6-4z"/><path d="M4 20h16"/><path d="M5 17h14"/>',
            'globe'    => '<circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/>',
        ];

        $iconSvg = $iconCustom ?: ($iconSVGs[$icon] ?? $iconSVGs['chat']);

        $css = ":root {";
        // 集成模式（JS 读取）
        $css .= "--xzd-integration-mode:{$integrationMode};";
        // 位置
        // 位置CSS变量：根据配置设置正确的top/bottom/left/right
        $css .= "--xzd-trigger-top:" . ($vPosition === 'top' ? "{$vOffset}px" : 'auto') . ";";
        $css .= "--xzd-trigger-bottom:" . ($vPosition === 'top' ? 'auto' : "{$vOffset}px") . ";";
        $css .= "--xzd-trigger-left:" . ($position === 'left' ? "{$hOffset}px" : 'auto') . ";";
        $css .= "--xzd-trigger-right:" . ($position === 'left' ? 'auto' : "{$hOffset}px") . ";";
        // 外观
        $css .= "--xzd-trigger-size:{$size}px;";
        $css .= "--xzd-trigger-bg:{$bgValue};";
        $css .= "--xzd-trigger-radius:" . ($shape === 'circle' ? '50%' : '16px') . ";";
        $css .= "--xzd-trigger-opacity:{$opacity};";
        $css .= "--xzd-trigger-shadow:{$shadowVal};";
        // 动画
        $css .= "--xzd-trigger-breath-speed:{$breathSpeed};";
        $css .= "--xzd-trigger-show-delay:{$showDelay}s;";
        if (!$breathing) $css .= "--xzd-trigger-breathing:none;";
        $css .= "--xzd-fab-animation:" . json_encode($fabAnimation, JSON_UNESCAPED_UNICODE) . ";";
        $css .= "--xzd-popup-animation:" . json_encode($popupAnimation, JSON_UNESCAPED_UNICODE) . ";";
        // 悬停效果
        $css .= "--xzd-trigger-hover:{$hoverEffect};";
        // 图标信息（供 JS 读取，用于主题按钮）
        $css .= "--xzd-trigger-icon:" . json_encode($icon, JSON_UNESCAPED_UNICODE) . ";";
        // V3.1.5 fix: base64 编码避免 SVG 属性双引号在 CSS 变量传输中被破坏
        $css .= "--xzd-trigger-icon-custom-b64:" . base64_encode($iconCustom) . ";";
        $css .= "--xzd-trigger-icon-type:" . json_encode($iconType, JSON_UNESCAPED_UNICODE) . ";";
        $css .= "--xzd-trigger-icon-image:" . json_encode($iconImage, JSON_UNESCAPED_UNICODE) . ";";
        $css .= "--xzd-trigger-icon-color:" . json_encode($iconColor, JSON_UNESCAPED_UNICODE) . ";";
        if ($iconColor === 'custom') $css .= "--xzd-trigger-icon-color-custom:" . json_encode($btn['icon_color_custom'] ?? '#ffffff', JSON_UNESCAPED_UNICODE) . ";";
        // 完整SVG 模式：传递 viewBox 和内部内容，供 JS Zibll 按钮渲染
        // V3.1.5 fix: 改用 base64 编码，防止 SVG 属性双引号在 CSS 变量→JS 传输链中被 json stringify/parse 破坏
        if ($iconType === 'svg' && $iconCustom) {
            $parsed = $this->parseSvgIcon($iconCustom);
            $css .= "--xzd-trigger-icon-viewbox-b64:" . base64_encode($parsed['viewBox']) . ";";
            $css .= "--xzd-trigger-icon-inner-b64:" . base64_encode($parsed['inner']) . ";";
            $css .= "--xzd-trigger-icon-full:" . ($parsed['is_full'] ? '1' : '0') . ";";
        }
        // 徽章
        $css .= "--xzd-trigger-badge:" . ($showBadge ? '1' : '0') . ";";
        $css .= "--xzd-trigger-badge-style:" . json_encode($badgeStyle, JSON_UNESCAPED_UNICODE) . ";";
        $css .= "--xzd-badge-radius:" . ($badgeStyle === 'label' ? '3px' : '50%') . ";";
        // 提示文字（V7修复：JSON_UNESCAPED_UNICODE 防止中文被转成 \uXXXX 导致乱码）
        $css .= "--xzd-trigger-tooltip:" . json_encode($tooltipText, JSON_UNESCAPED_UNICODE) . ";";
        // 移动端
        if ($mobileIndependent) {
            $css .= "--xzd-trigger-mobile-{$mobileV}:{$mobileVO}px;";
            $css .= "--xzd-trigger-mobile-{$mobileH}:{$mobileHO}px;";
        }
        $css .= "}";

        // 注入移动端覆盖
        $mobileCss = '';
        if ($mobileIndependent) {
            $mobileCss .= "@media (max-width:768px){.xzd-chat-trigger{";
            $mobileCss .= "{$mobileV}:var(--xzd-trigger-mobile-{$mobileV},{$mobileVO}px)!important;";
            $mobileCss .= "{$mobileH}:var(--xzd-trigger-mobile-{$mobileH},{$mobileHO}px)!important;";
            $mobileCss .= "}}";
        }

        wp_add_inline_style('xzd-floating-chat', $css . $mobileCss);

        // 注入自定义图标（替换触发按钮内的 SVG）
        // ★ 完整SVG已直接渲染在HTML中，不用CSS mask覆盖（保留多色）
        $svgParsed = $this->parseSvgIcon($iconCustom ?: '');
        if (($iconCustom || $icon !== 'chat') && !$svgParsed['is_full']) {
            $maskViewBox = $svgParsed['viewBox'];
            $maskInner  = $svgParsed['inner'];
            $maskAttrs  = " fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'";
            $svgData = str_replace(['<', '>'], ['%3C', '%3E'], "<svg xmlns='http://www.w3.org/2000/svg' viewBox='{$maskViewBox}'{$maskAttrs}>{$maskInner}</svg>");

            $iconCss = ".xzd-chat-trigger svg{display:none;}"
                     . ".xzd-chat-trigger::before{content:'';display:block;width:20px;height:20px;"
                     . "background:" . ($iconColor === 'dark' ? '#18181B' : ($iconColor === 'custom' ? ($btn['icon_color_custom'] ?? '#fff') : '#fff')) . ";"
                     . "-webkit-mask-image:url(\"data:image/svg+xml," . $svgData . "\");"
                     . "mask-image:url(\"data:image/svg+xml," . $svgData . "\");"
                     . "-webkit-mask-size:contain;mask-size:contain;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;"
                     . "-webkit-mask-position:center;mask-position:center;}";
            wp_add_inline_style('xzd-floating-chat', $iconCss);
        }

        // 注入欢迎语覆盖
        if ($welcomeTitle || $welcomeDesc || !empty($hintPrompts)) {
            $welcomeJs = "document.addEventListener('DOMContentLoaded',function(){";
            if ($welcomeTitle) $welcomeJs .= "var h=document.querySelector('#xzd-chat-welcome h3');if(h)h.textContent=" . json_encode($welcomeTitle) . ";";
            if ($welcomeDesc) $welcomeJs .= "var p=document.querySelector('#xzd-chat-welcome p');if(p)p.innerHTML=" . json_encode($welcomeDesc) . ";";
            if (!empty($hintPrompts)) {
                $hintsHtml = '';
                foreach ($hintPrompts as $hint) {
                    $hintsHtml .= '<button class=\"xzd-chat-hint\" data-hint=\"' . esc_attr($hint) . '\">' . esc_html($hint) . '</button>';
                }
                $welcomeJs .= "var c=document.querySelector('.xzd-chat-welcome-hints');if(c)c.innerHTML=" . json_encode($hintsHtml) . ";";
            }
            $welcomeJs .= "});";
            wp_add_inline_script('xzd-floating-chat', $welcomeJs);
        }

        // 显示控制
        if (!$showFrontend && !is_admin()) {
            $hideCss = "#xzd-chat-trigger{display:none!important;}";
            wp_add_inline_style('xzd-floating-chat', $hideCss);
        }
        if (!$showBackend && is_admin()) {
            $hideCss = "#xzd-chat-trigger{display:none!important;}";
            wp_add_inline_style('xzd-floating-chat', $hideCss);
        }
        if ($articleOnly && !is_singular('post') && !is_admin()) {
            $hideCss = "#xzd-chat-trigger{display:none!important;}";
            wp_add_inline_style('xzd-floating-chat', $hideCss);
        }
        if ($excludePaths && !is_admin()) {
            $paths = array_map('trim', explode(',', $excludePaths));
            $currentPath = $_SERVER['REQUEST_URI'] ?? '';
            foreach ($paths as $p) {
                if ($p && strpos($currentPath, $p) !== false) {
                    wp_add_inline_style('xzd-floating-chat', "#xzd-chat-trigger{display:none!important;}");
                    break;
                }
            }
        }
        if (!$showMobile) {
            wp_add_inline_style('xzd-floating-chat', "@media(max-width:768px){#xzd-chat-trigger{display:none!important;}}");
        }
    }

    /**
     * 注入到 JS 的配置
     */
    private function getJsConfig(): array
    {
        // V7.1性能优化：访客配置静态缓存（登录用户每次重新计算，确保用户信息正确）
        static $guestCached = null;
        $isLoggedIn = is_user_logged_in();
        if (!$isLoggedIn && $guestCached !== null) {
            return $guestCached;
        }

        $user  = wp_get_current_user();
        $theme = \XZD\AI\V5\Theme\AdapterRegistry::detect();
        $adapter = \XZD\AI\V5\Theme\AdapterRegistry::getCurrent();
        $config = \XZD\AI\V5\Core\Config::instance();

        // 用户头像（优先使用 WP 头像，Gravatar 不可用时回退本地默认图）
        $userAvatar = $this->resolveUserAvatar($user->ID);

        // AI 身份 — 统一解析（绑定用户则拉取WP资料）
        $aiIdentity = $config->resolveAIIdentity();
        $aiName   = $aiIdentity['name'];
        $aiAvatar = $this->resolveAiAvatar($aiIdentity);
        $aiUserId = $aiIdentity['user_id'];

        // 授权等级信息
        $licenseSvc  = \XZD\AI\V5\Core\LicenseService::instance();
        $licenseData = $licenseSvc->getLicenseData();

        $config_data = [
            'restUrl'       => rest_url(XZD_AI_REST_NAMESPACE),
            'restNonce'     => wp_create_nonce('wp_rest'),
            'isAdmin'       => current_user_can('manage_options'),
            'isLoggedIn'    => $isLoggedIn,
            'userId'        => get_current_user_id(),
            'userName'      => $isLoggedIn ? $user->display_name : '访客',
            'userAvatar'    => $userAvatar,
            'defaultAvatar' => $this->defaultAvatarUrl(),
            'userRole'     => current_user_can('manage_options') ? 'admin' : ($isLoggedIn ? 'user' : 'guest'),
            'userRoles'    => $isLoggedIn ? $user->roles : [],
            'homeUrl'      => home_url('/'),
            'siteName'     => get_bloginfo('name'),
            'ajaxUrl'      => admin_url('admin-ajax.php'),
            'defaultModel' => $this->getActiveModel(),
            'themeAdapter'  => $theme['adapter'],
            'themeName'     => $theme['name'],
            'themeTemplate' => $theme['template'],
            'themeColors'   => $theme['colors'] ?? [],
            'bubblePosition'=> $theme['bubble'] ?? [],
            'themeButtonSelector'      => $adapter->getButtonContainerSelector(),
            'themeHasIntegratedButton' => $adapter->hasIntegratedButton(),
            'pageContextRules'         => $adapter->getPageContextRules(),
            'isAdminPage'   => is_admin(),
            'hideTrigger'   => $this->shouldHideTrigger(),
            'aiName'        => $aiName,
            'aiAvatar'      => $aiAvatar,
            'licenseActive'  => true, // 三级权限：免费版也可对话
            'licenseLevel'   => $licenseData['level'] ?? 'free',
            'licenseFeatures'=> [
                'ai_chat'           => true,
                'automation'        => $licenseData['level'] !== 'free',
                'knowledge_base'    => $licenseData['level'] === 'ultimate',
                'full_pipeline'     => $licenseData['level'] !== 'free',
                'media_processing'  => $licenseData['level'] !== 'free',
                'wp_management'     => $licenseData['level'] !== 'free',
                'theme_integration' => $licenseData['level'] === 'ultimate',
            ],
            'floatingButton' => $config->get('floating_button', []),
        ];
        if (!$isLoggedIn) {
            $guestCached = $config_data;
        }
        return $config_data;
    }

    /**
     * 获取用户头像 URL — 经 WordPress 全滤镜链过滤
     *
     * 使用 get_avatar()（触发所有 get_avatar 过滤器）提取真实 URL，
     * 确保兼容 Zibll 主题、Gravatar 镜像插件等所有头像方案。
     * 加载失败由前端 img onerror → data URI 兜底。
     */
    private function resolveUserAvatar(int $userId): string
    {
        return $this->getFilteredAvatarUrl($userId, 80);
    }

    /**
     * 获取 AI 身份头像 URL
     *
     * 基于 resolveAIIdentity() 的解析结果，仅对 Gravatar URL 做 get_avatar() 增强。
     * 其余情况（自定义 URL、空值回退）不动 AI 身份绑定的解析逻辑。
     */
    private function resolveAiAvatar(array $aiIdentity): string
    {
        $avatar = $aiIdentity['avatar'];

        // 空值 → 内置默认
        if (empty($avatar)) {
            return $this->defaultAvatarUrl();
        }

        // 绑定用户 + Gravatar URL → 尝试 get_avatar() 全滤镜（兼容 Zibll 本地头像）
        if (!empty($aiIdentity['user_id']) && strpos($avatar, 'gravatar.com') !== false) {
            $filtered = $this->getFilteredAvatarUrl((int) $aiIdentity['user_id'], 40);
            if ($filtered !== $this->defaultAvatarUrl()) {
                return $filtered;
            }
        }

        return $avatar;
    }

    /**
     * 获取经过 WordPress 全滤镜链的头像 URL
     *
     * get_avatar() 会经过 get_avatar / get_avatar_data / get_avatar_url 三级过滤，
     * Zibll 等主题通过 get_avatar 过滤器替换 Gravatar 为本地 URL。
     */
    private function getFilteredAvatarUrl(int $userId, int $size): string
    {
        if (!$userId) {
            return $this->defaultAvatarUrl();
        }

        $html = get_avatar($userId, $size, '', '', ['extra_attr' => '']);
        if ($html && preg_match('/src=[\'"]([^\'"]+)[\'"]/', $html, $m) && !empty($m[1])) {
            return $m[1];
        }

        return $this->defaultAvatarUrl();
    }

    /**
     * 插件内置默认头像 — 内联 SVG data URI
     */
    private function defaultAvatarUrl(): string
    {
        $svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">'
             . '<circle cx="50" cy="50" r="50" fill="#E4E4E7"/>'
             . '<circle cx="50" cy="38" r="16" fill="#A1A1AA"/>'
             . '<ellipse cx="50" cy="80" rx="28" ry="22" fill="#A1A1AA"/>'
             . '</svg>';
        return 'data:image/svg+xml;base64,' . base64_encode($svg);
    }

    /**
     * 安全转义 URL（兼容 http/https 和 data: URI）
     */
    private function safeUrl(string $url): string
    {
        return str_starts_with($url, 'data:') ? esc_attr($url) : esc_url($url);
    }

    /**
     * 获取当前激活的主用文本模型名称
     */
    private function getActiveModel(): string
    {
        $conns = \XZD\AI\V5\Core\Config::instance()->get('connections.text', []);
        if (!is_array($conns)) return '';
        foreach ($conns as $c) {
            if (!empty($c['enabled']) && !empty($c['model'])) {
                return $c['model'];
            }
        }
        return '';
    }

    /**
     * 解析自定义SVG图标 — 智能识别完整SVG vs 裸path片段
     *
     * @return array{is_full:bool, viewBox:string, inner:string}
     */
    private function parseSvgIcon(string $raw): array
    {
        $trimmed = trim($raw);
        // 完整 SVG 格式：以 <svg 开头
        if (stripos($trimmed, '<svg') === 0) {
            // 提取 viewBox
            $viewBox = '0 0 24 24';
            if (preg_match('/viewBox\s*=\s*["\']([^"\']+)["\']/i', $trimmed, $m)) {
                $viewBox = $m[1];
            }
            // 提取 <svg> 内部所有内容（去掉外层 <svg...> 和 </svg>）
            $inner = '';
            if (preg_match('/<svg[^>]*>(.*)<\/svg>/is', $trimmed, $m)) {
                $inner = trim($m[1]);
            }
            return ['is_full' => true, 'viewBox' => $viewBox, 'inner' => $inner];
        }
        // 裸 path 片段（旧格式）
        return ['is_full' => false, 'viewBox' => '0 0 24 24', 'inner' => $trimmed];
    }
}
