<?php

namespace XZD\AI\V5\Agents;

use XZD\AI\V5\Core\Logger;
use XZD\AI\V5\Tools\SiteTypeDetector;

/**
 * Monitor Agent — 主动智能引擎
 */
class MonitorAgent extends BaseAgent
{
    /** @var array|null 真实站点上下文缓存 */
    private ?array $realCtx = null;

    // 冷却常量（秒）
    private const COOLDOWN_IMMEDIATE  = 0;
    private const COOLDOWN_SHORT      = 300;
    private const COOLDOWN_MEDIUM     = 1800;
    private const COOLDOWN_LONG       = 3600;
    private const COOLDOWN_VERY_LONG  = 7200;
    private const COOLDOWN_DAILY      = 86400;

    public function getId(): string
    {
        return 'monitor';
    }

    public function getName(): string
    {
        return '监控 Agent';
    }

    public function getDescription(): string
    {
        return '分析用户行为和系统状态，主动提供AI建议';
    }

    public function getToolCategories(): array
    {
        return ['content', 'wp', 'seo'];
    }

    public function getMinRole(): string
    {
        return 'admin';
    }

    /**
     * 从知识库查询预生成的主动消息模板
     */
    private function getProactiveTemplate(string $sceneTag, string $role, array $vars = []): ?array
    {
        global $wpdb;
        $table = $wpdb->prefix . 'xzd_ai_knowledge';

        // 按scene标签匹配
        $row = $wpdb->get_row($wpdb->prepare(
            "SELECT title, content FROM {$table}
             WHERE title LIKE %s AND source_type = 'proactive_template' AND status = 'active'
             LIMIT 1",
            $sceneTag . '%'
        ), ARRAY_A);

        if (!$row) return null;

        // 解析模板内容（格式：角色:xxx\n消息:xxx）
        $content = $row['content'] ?? '';
        $message = '';
        if (preg_match('/消息:(.+)/s', $content, $m)) {
            $message = trim($m[1]);
        }

        // 填入动态变量
        if (!empty($vars)) {
            foreach ($vars as $key => $val) {
                $message = str_replace('{' . $key . '}', $val, $message);
            }
        }

        return [
            'message'     => $message,
            'template_id' => $row['title'],
        ];
    }

    /**
     * 从知识库查询内容
     */
    private function getKbContent(string $topic, int $limit = 3): array
    {
        global $wpdb;
        $table = $wpdb->prefix . 'xzd_ai_knowledge';
        $like = '%' . $wpdb->esc_like($topic) . '%';
        $rows = $wpdb->get_results($wpdb->prepare(
            "SELECT id, title, LEFT(content, 200) AS excerpt, source_url, access_level
             FROM {$table} WHERE status='active' AND (title LIKE %s OR content LIKE %s)
             ORDER BY created_at DESC LIMIT %d",
            $like, $like, $limit
        ), ARRAY_A);

        if (!$rows) return [];

        return array_map(fn($r) => [
            'id'    => (int) $r['id'],
            'title' => $r['title'],
            'desc'  => wp_strip_all_tags($r['excerpt'] ?? ''),
            'url'   => $r['source_url'] ?? '',
        ], $rows);
    }

    /**
     * 获取真实站点上下文
     */
    private function getRealContext(): array
    {
        if ($this->realCtx !== null) return $this->realCtx;

        global $wpdb;

        // 实际产品数
        $productCount = (int) $wpdb->get_var(
            "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type IN ('shop_product','product') AND post_status='publish'"
        );

        // 实际论坛帖子数
        $forumCount = (int) $wpdb->get_var(
            "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type IN ('forum_post','topic','reply') AND post_status='publish'"
        );

        // 实际文章数
        $postCount = (int) $wpdb->get_var(
            "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type='post' AND post_status='publish'"
        );

        // 知识库条目数
        $knowledgeCount = (int) $wpdb->get_var(
            "SELECT COUNT(*) FROM {$wpdb->prefix}xzd_ai_knowledge WHERE status='active'"
        );

        // 站点类型标签
        $siteType = $this->getSiteType();
        $types = $siteType['types'] ?? ['general'];

        // 对 shop/forum 标签做真实性校验
        $verifiedTypes = $types;
        if (in_array('shop', $verifiedTypes) && $productCount === 0) {
            $verifiedTypes = array_values(array_diff($verifiedTypes, ['shop']));
        }
        if (in_array('forum', $verifiedTypes) && $forumCount === 0) {
            $verifiedTypes = array_values(array_diff($verifiedTypes, ['forum']));
        }
        if (empty($verifiedTypes)) $verifiedTypes = ['blog'];

        $this->realCtx = [
            'product_count'   => $productCount,
            'forum_count'     => $forumCount,
            'post_count'      => $postCount,
            'knowledge_count' => $knowledgeCount,
            'types'           => $verifiedTypes,
            'primary'         => $verifiedTypes[0] ?? 'blog',
        ];

        return $this->realCtx;
    }

    /**
     * 获取缓存站点类型
     */
    private function getSiteType(): array
    {
        $cached = get_transient('xzd_site_type_cache');
        if ($cached && is_array($cached)) return $cached;
        try {
            $detector = SiteTypeDetector::instance();
            $result = $detector->detect();
            set_transient('xzd_site_type_cache', $result, HOUR_IN_SECONDS);
            return $result;
        } catch (\Throwable $e) {
            return ['primary' => 'general', 'types' => ['general']];
        }
    }

    /**
     * 获取真实相关文章
     */
    private function getRealRelatedPosts(int $postId, int $limit = 3): array
    {
        if (!$postId) return $this->getRecentPosts($limit);

        $posts = get_posts([
            'post_type'      => 'post',
            'post_status'    => 'publish',
            'posts_per_page' => $limit,
            'post__not_in'   => [$postId],
            'orderby'        => 'rand',
        ]);

        if (empty($posts)) return [];

        return array_map(fn($p) => [
            'id'    => $p->ID,
            'title' => $p->post_title,
            'url'   => get_permalink($p->ID),
        ], $posts);
    }

    /**
     * 获取最近文章
     */
    private function getRecentPosts(int $limit = 3): array
    {
        $posts = get_posts([
            'post_type'      => 'post',
            'post_status'    => 'publish',
            'posts_per_page' => $limit,
            'orderby'        => 'date',
            'order'          => 'DESC',
        ]);
        return array_map(fn($p) => [
            'id'    => $p->ID,
            'title' => $p->post_title,
            'url'   => get_permalink($p->ID),
        ], $posts);
    }

    /**
     * 检查用户是否有真实未支付订单
     */
    private function userHasPendingOrder(int $userId): bool
    {
        if (!$userId) return false;
        try {
            $adapter = \XZD\AI\V5\Theme\AdapterRegistry::getCurrent();
            $orders = $adapter->getOrders($userId, 50);
            $pendingCount = count(array_filter($orders, fn($o) => !in_array($o['status'] ?? '', ['paid','cancelled','refunded'])));
            return $pendingCount > 0;
        } catch (\Throwable $e) {
            return false;
        }
    }

    // 事件评估入口

    public function evaluate(string $event, array $context): array
    {
        $ctx = $this->getRealContext();
        $context['_real_ctx'] = $ctx;

        return match ($event) {
            'stay_120s'        => $this->handleStay($context, $ctx),
            'scroll_depth_80'  => $this->handleScrollDepth($context, $ctx),
            'idle_60s'         => $this->handleIdle($context, $ctx),
            'exit_intent'      => $this->handleExitIntent($context, $ctx),
            'return_visitor'   => $this->handleReturnVisitor($context, $ctx),
            'multi_page_view'  => $this->handleMultiPage($context, $ctx),
            'search_no_result' => $this->handleSearchNoResult($context, $ctx),
            'product_browse_3' => $this->handleProductBrowse($context, $ctx),
            'cart_abandon'     => $this->handleCartAbandon($context, $ctx),
            'forum_browse_3'   => $this->handleForumBrowse($context, $ctx),
            'forum_no_post'    => $this->handleForumNoPost($context, $ctx),
            'article_reading'  => $this->handleArticleReading($context, $ctx),
            'first_visit'      => $this->handleFirstVisit($context, $ctx),
            'page_404'         => $this->handlePage404($context, $ctx),
            'content_copied'   => $this->handleContentCopied($context, $ctx),
            default            => ['should_engage' => false, 'reason' => 'unknown_event'],
        };
    }

    // 事件处理器

    private function handleStay(array $ctx, array $real): array
    {
        $title = $ctx["page_title"] ?? "";
        $postId = $ctx["post_id"] ?? 0;

        // 知识库模板优先
        if ($title) {
            $template = $this->getProactiveTemplate("scene:stay_120s", "guest",
                ["title" => $title]);
            if ($template) return [
                "should_engage" => true, "message" => $template["message"],
                "cooldown_seconds" => self::COOLDOWN_LONG,
            ];
        }

        // KB推荐
        if ($postId && $real["post_count"] > 0) {
            $related = $this->getKbContent(mb_substr($title, 0, 20), 2);
            if (empty($related)) $related = $this->getRealRelatedPosts($postId, 2);
            $titles = implode("、", array_column($related, "title"));
            $prefix = $title ? "看了这么久「{$title}」" : "看了这么久";
            return [
                "should_engage" => true,
                "message" => $titles ? "{$prefix}，推荐你看看 👇" : "{$prefix}，需要我帮你总结这篇文章吗？",
                "suggestions" => $related,
                "cooldown_seconds" => self::COOLDOWN_LONG,
            ];
        }

        return ["should_engage" => false, "reason" => "no_content"];
    }

    private function handleScrollDepth(array $ctx, array $real): array
    {
        $postId = $ctx["post_id"] ?? 0;
        $title = $ctx["page_title"] ?? "";

        // KB模板优先
        $template = $this->getProactiveTemplate("scene:scroll_depth_80:post", "guest",
            ["title" => $title]);
        if ($template) return [
            "should_engage" => true, "message" => $template["message"],
            "cooldown_seconds" => self::COOLDOWN_MEDIUM,
        ];

        // KB推荐相关文章
        if ($postId) {
            $related = $this->getKbContent($title, 3);
            if (empty($related)) $related = $this->getRealRelatedPosts($postId, 3);
            if (!empty($related)) {
                return [
                    "should_engage" => true,
                    "message" => "快看完了！给你推荐几篇相关文章 👇",
                    "suggestions" => $related,
                    "cooldown_seconds" => self::COOLDOWN_MEDIUM,
                ];
            }
        }

        return [
            "should_engage" => true,
            "message" => "快看完了！有什么想了解的吗？试试问我吧~",
            "cooldown_seconds" => self::COOLDOWN_MEDIUM,
        ];
    }

    private function handleIdle(array $ctx, array $real): array
    {
        // KB模板优先
        $template = $this->getProactiveTemplate("scene:idle_60s:general", "user");
        if ($template) return [
            "should_engage" => true, "message" => $template["message"],
            "cooldown_seconds" => self::COOLDOWN_MEDIUM,
        ];

        // KB热门内容
        $kbFaqs = $this->getKbContent("", 3);
        if (!empty($kbFaqs)) {
            return [
                "should_engage" => true,
                "message" => "还在吗？试试这些热门问题 👇",
                "suggestions" => $kbFaqs,
                "cooldown_seconds" => self::COOLDOWN_MEDIUM,
            ];
        }

        return [
            "should_engage" => true,
            "message" => "还在吗？有什么可以帮你的？试试搜索你感兴趣的内容~",
            "cooldown_seconds" => self::COOLDOWN_MEDIUM,
        ];
    }

    private function handleExitIntent(array $ctx, array $real): array
    {
        $userId = $ctx["user_id"] ?? 0;

        // 购物车逻辑
        if ($real["product_count"] > 0 && $userId > 0 && $this->userHasPendingOrder($userId)) {
            return [
                "should_engage" => true,
                "message" => "购物车还有未结算的商品哦，现在下单享优惠！",
                "cooldown_seconds" => self::COOLDOWN_DAILY,
            ];
        }

        // KB模板优先
        $template = $this->getProactiveTemplate("scene:exit_intent:guest", "guest");
        if ($template) return [
            "should_engage" => true, "message" => $template["message"],
            "cooldown_seconds" => self::COOLDOWN_DAILY,
        ];

        // KB挽留内容
        $retentionKb = $this->getKbContent("注册 会员 权益", 2);
        $recentPosts = $this->getRecentPosts(2);
        return [
            "should_engage" => true,
            "message" => "别急着走！" . (!empty($retentionKb) ? "注册会员可以获得专属权益 👇" : "最近有这些精彩内容 👇"),
            "suggestions" => !empty($retentionKb) ? $retentionKb : $recentPosts,
            "cooldown_seconds" => self::COOLDOWN_DAILY,
        ];
    }

    private function handleReturnVisitor(array $ctx, array $real): array
    {
        $days = $ctx["days_since"] ?? 3;

        // KB模板优先
        $template = $this->getProactiveTemplate("scene:return_visitor:blog", "guest",
            ["days" => (string)$days]);
        if ($template) return [
            "should_engage" => true, "message" => $template["message"],
            "cooldown_seconds" => self::COOLDOWN_DAILY,
        ];

        $newPosts = $this->countNewPosts($days);
        $recentPosts = $this->getRecentPosts(2);
        return [
            "should_engage" => true,
            "message" => $newPosts > 0
                ? "欢迎回来！这{$days}天发布了{$newPosts}篇新文章，快来看看 👇"
                : "欢迎回来！有什么可以帮你的吗？",
            "suggestions" => $recentPosts ?: null,
            "cooldown_seconds" => self::COOLDOWN_DAILY,
        ];
    }

    private function handleMultiPage(array $ctx, array $real): array
    {
        $count = $ctx["page_count"] ?? 5;

        // KB模板优先
        $template = $this->getProactiveTemplate("scene:multi_page_view:general", "guest",
            ["count" => (string)$count]);
        if ($template) return [
            "should_engage" => true, "message" => $template["message"],
            "cooldown_seconds" => self::COOLDOWN_MEDIUM,
        ];

        return [
            "should_engage" => true,
            "message" => "浏览了{$count}个页面，需要我帮你整理一下今天看过的内容吗？",
            "cooldown_seconds" => self::COOLDOWN_VERY_LONG,
        ];
    }

    private function handleArticleReading(array $ctx, array $real): array
    {
        $length = $ctx["content_length"] ?? 0;
        if ($length < 2000) return ["should_engage" => false, "reason" => "short_article"];

        $title = $ctx["page_title"] ?? "";

        // KB模板优先
        $template = $this->getProactiveTemplate("scene:article_reading:long", "user",
            ["title" => $title]);
        if ($template) return [
            "should_engage" => true, "message" => $template["message"],
            "cooldown_seconds" => self::COOLDOWN_LONG,
        ];

        return [
            "should_engage" => true,
            "message" => "这篇长文内容不少，需要我帮你提取要点吗？",
            "cooldown_seconds" => self::COOLDOWN_LONG,
        ];
    }

    private function handleFirstVisit(array $ctx, array $real): array
    {
        $siteName = get_bloginfo("name");

        // KB模板优先
        $template = $this->getProactiveTemplate("scene:first_visit:blog", "guest",
            ["siteName" => $siteName]);
        if ($template) return [
            "should_engage" => true, "message" => $template["message"],
            "cooldown_seconds" => self::COOLDOWN_IMMEDIATE,
        ];

        $recentPosts = $this->getRecentPosts(2);
        if (!empty($recentPosts)) {
            return [
                "should_engage" => true,
                "message" => "欢迎来到{$siteName}！我是AI助手，最近有这些精彩内容 👇",
                "suggestions" => $recentPosts,
                "cooldown_seconds" => self::COOLDOWN_IMMEDIATE,
            ];
        }

        return [
            "should_engage" => true,
            "message" => "欢迎来到{$siteName}！我是AI助手，可以帮你搜索文章，试试问我吧~",
            "cooldown_seconds" => self::COOLDOWN_IMMEDIATE,
        ];
    }

    private function handlePage404(array $ctx, array $real): array
    {
        // KB推荐导航
        $kbNav = $this->getKbContent("导航 菜单", 3);
        return [
            "should_engage" => true,
            "message" => "页面未找到！试试搜索你感兴趣的内容，或让AI帮你导航~",
            "suggestions" => $kbNav ?: null,
            "cooldown_seconds" => self::COOLDOWN_MEDIUM,
        ];
    }

    private function handleContentCopied(array $ctx, array $real): array
    {
        $length = $ctx["copied_length"] ?? 0;
        if ($length < 100) return ["should_engage" => false, "reason" => "too_short"];

        return [
            "should_engage" => true,
            "message" => "复制了内容？需要AI帮你改写、翻译或生成摘要吗？",
            "cooldown_seconds" => self::COOLDOWN_SHORT,
        ];
    }

    private function handleSearchNoResult(array $ctx, array $real): array
    {
        $query = $ctx["search_query"] ?? "";
        $q = $query ? "「{$query}」" : "";

        // 从知识库搜索
        $kbResults = $this->getKbContent($query, 3);
        if (!empty($kbResults)) {
            return [
                "should_engage" => true,
                "message" => $query
                    ? "没找到关于{$q}的内容，但知识库中有这些相关内容 👇"
                    : "没找到相关内容？试试这些 👇",
                "suggestions" => $kbResults,
                "cooldown_seconds" => self::COOLDOWN_SHORT,
            ];
        }

        // KB无结果，从真实文章搜索
        if ($query) {
            $posts = get_posts([
                "s" => $query, "post_type" => "post", "post_status" => "publish",
                "posts_per_page" => 3,
            ]);
            if (!empty($posts)) {
                $suggestions = array_map(fn($p) => [
                    "id" => $p->ID, "title" => $p->post_title,
                    "url" => get_permalink($p->ID),
                ], $posts);
                return [
                    "should_engage" => true,
                    "message" => "没找到精确匹配{$q}的内容，但你可能对这些感兴趣 👇",
                    "suggestions" => $suggestions,
                    "cooldown_seconds" => self::COOLDOWN_SHORT,
                ];
            }
        }

        return [
            "should_engage" => true,
            "message" => $query
                ? "没找到关于{$q}的内容，我可以帮你生成相关内容！"
                : "没找到相关内容？我可以帮你生成！",
            "cooldown_seconds" => self::COOLDOWN_SHORT,
        ];
    }

    // 商城站专用事件

    private function handleProductBrowse(array $ctx, array $real): array
    {
        // 必须有真实商品才触发
        if ($real['product_count'] === 0) {
            return ['should_engage' => false, 'reason' => 'no_products'];
        }
        return [
            'should_engage'    => true,
            'message'          => '看了3个同类产品了，需要我帮你做详细的对比分析吗？',
            'cooldown_seconds' => 1800,
        ];
    }

    private function handleCartAbandon(array $ctx, array $real): array
    {
        $userId = $ctx['user_id'] ?? 0;
        // 必须有真实商品 + 用户有未支付订单
        if ($real['product_count'] === 0) {
            return ['should_engage' => false, 'reason' => 'no_products'];
        }
        if (!$userId || !$this->userHasPendingOrder($userId)) {
            return ['should_engage' => false, 'reason' => 'no_pending_order'];
        }
        return [
            'should_engage'    => true,
            'message'          => '购物车里的宝贝在等你呢！现在下单享限时优惠~',
            'cooldown_seconds' => 7200,
        ];
    }

    // 论坛站专用事件

    private function handleForumBrowse(array $ctx, array $real): array
    {
        if ($real['forum_count'] === 0) {
            return ['should_engage' => false, 'reason' => 'no_forum_posts'];
        }
        return [
            'should_engage'    => true,
            'message'          => '浏览了3个帖子还没有互动？发表你的看法，和大家一起讨论吧！',
            'cooldown_seconds' => 7200,
        ];
    }

    private function handleForumNoPost(array $ctx, array $real): array
    {
        if ($real['forum_count'] === 0) {
            return ['should_engage' => false, 'reason' => 'no_forum_posts'];
        }
        return [
            'should_engage'    => true,
            'message'          => '新来的朋友！去发个帖子介绍自己，或者看看新手引导吧~',
            'cooldown_seconds' => 0,
        ];
    }

    public function generateSuggestions(): array
    {
        $suggestions = [];

        $aiAvailable = $this->isAiAvailable();
        $aiStatus = $this->getAiStatus();

        if (!$aiAvailable) {
            $suggestions[] = [
                'type'        => 'ai_disconnected',
                'priority'    => 'high',
                'title'       => 'AI 服务未连接',
                'description' => '请先在「AI配置」页面添加并测试AI连接。没有AI连接，标签生成、SEO优化、内容处理等功能无法使用。',
                'action'      => 'configure_ai',
                'requires_ai' => false,
                'metric'      => 0,
            ];
        }

        // 无标签文章
        $untagged = $this->countUntaggedPosts();
        if ($untagged > 0) {
            $suggestions[] = [
                'type'        => 'missing_tags',
                'priority'    => $untagged > 10 ? 'high' : 'medium',
                'title'       => "{$untagged} 篇文章缺少标签",
                'description' => $aiAvailable
                    ? "建议使用「批量标签生成」工具为这些文章补充标签，提升SEO和用户体验。"
                    : "文章缺少标签会影响SEO，但当前AI未连接，无法自动生成。请先配置AI连接。",
                'action'      => $aiAvailable ? 'generate_tags_batch' : 'configure_ai',
                'action_params' => ['count' => min($untagged, 50)],
                'requires_ai' => true,
                'metric'      => $untagged,
            ];
        }

        // 过期草稿
        $staleDrafts = $this->countStaleDrafts();
        if ($staleDrafts > 0) {
            $suggestions[] = [
                'type'        => 'stale_drafts',
                'priority'    => $staleDrafts > 5 ? 'medium' : 'low',
                'title'       => "{$staleDrafts} 篇草稿超过7天未处理",
                'description' => '建议清理过期草稿，发布有价值的内容或删除无效草稿。',
                'action'      => 'review_drafts',
                'requires_ai' => false,
                'metric'      => $staleDrafts,
            ];
        }

        // 无SEO描述
        $noSeoCount = $this->countPostsWithoutMeta('_xzd_ai_seo_desc');
        if ($noSeoCount > 3) {
            $suggestions[] = [
                'type'        => 'missing_seo',
                'priority'    => $noSeoCount > 20 ? 'high' : 'medium',
                'title'       => "{$noSeoCount} 篇文章缺少SEO描述",
                'description' => $aiAvailable ? 'SEO描述有助于搜索引擎排名，建议批量生成。' : '文章缺少SEO描述，但AI未连接无法自动生成。',
                'action'      => $aiAvailable ? 'generate_seo_batch' : 'configure_ai',
                'action_params' => ['count' => min($noSeoCount, 50)],
                'requires_ai' => true,
                'metric'      => $noSeoCount,
            ];
        }

        // 近期错误
        $recentErrors = $this->countRecentErrors();
        if ($recentErrors > 0) {
            $suggestions[] = [
                'type'        => 'recent_errors',
                'priority'    => $recentErrors > 5 ? 'high' : 'medium',
                'title'       => "近24小时有 {$recentErrors} 次操作失败",
                'description' => '建议查看操作日志中的失败记录，排查API连接或权限问题。',
                'action'      => 'view_error_logs',
                'requires_ai' => false,
                'metric'      => $recentErrors,
            ];
        }

        // 成本预警
        $monthCost = $this->getMonthCost();
        $budget = \XZD\AI\V5\Core\Config::instance()->get('cost.monthly_budget', 0);
        if ($budget > 0 && $monthCost > $budget * 0.8) {
            $pct = round($monthCost / $budget * 100);
            $suggestions[] = [
                'type'        => 'budget_warning',
                'priority'    => $monthCost > $budget ? 'high' : 'medium',
                'title'       => "本月费用 ¥{$monthCost}，已使用预算的 {$pct}%",
                'description' => '建议检查成本追踪面板，优化AI调用频率或更换更经济的模型。',
                'action'      => 'view_cost_analytics',
                'metric'      => $monthCost,
            ];
        }

        // 队列积压
        $queueBacklog = $this->countQueueBacklog();
        if ($queueBacklog > 10) {
            $suggestions[] = [
                'type'        => 'queue_backlog',
                'priority'    => $queueBacklog > 50 ? 'high' : 'medium',
                'title'       => "任务队列积压 {$queueBacklog} 条",
                'description' => '队列积压可能影响批量处理性能，建议清理或检查Action Scheduler状态。',
                'action'      => 'view_queue',
                'metric'      => $queueBacklog,
            ];
        }

        // 插件更新
        $pluginUpdates = $this->countPendingUpdates();
        if ($pluginUpdates > 0) {
            $suggestions[] = [
                'type'        => 'pending_updates',
                'priority'    => $pluginUpdates > 3 ? 'medium' : 'low',
                'title'       => "{$pluginUpdates} 个插件/主题有待更新",
                'description' => '保持插件更新有助于安全性和兼容性。',
                'action'      => 'view_updates',
                'metric'      => $pluginUpdates,
            ];
        }

        $order = ['high' => 0, 'medium' => 1, 'low' => 2];
        usort($suggestions, fn($a, $b) => $order[$a['priority']] - $order[$b['priority']]);

        return $suggestions;
    }

    public function getHealthSummary(): array
    {
        global $wpdb;

        $postCounts = wp_count_posts();
        $userCounts = count_users();

        return [
            'total_posts'       => (int) ($postCounts->publish ?? 0),
            'total_drafts'      => (int) ($postCounts->draft ?? 0),
            'total_pages'       => (int) ($postCounts->page ?? 0),
            'total_users'       => (int) ($userCounts['total_users'] ?? 0),
            'untagged_posts'    => $this->countUntaggedPosts(),
            'stale_drafts'      => $this->countStaleDrafts(),
            'no_seo_posts'      => $this->countPostsWithoutMeta('_xzd_ai_seo_desc'),
            'no_cover_posts'    => $this->countPostsWithoutThumbnail(),
            'recent_errors_24h' => $this->countRecentErrors(),
            'queue_backlog'     => $this->countQueueBacklog(),
            'month_cost_rmb'    => $this->getMonthCost(),
            'total_operations'  => (int) $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}xzd_ai_operation_log"),
            'active_chats'      => (int) $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}xzd_ai_chat_sessions WHERE status = 'active'"),
            'total_connections' => count(array_filter(
                \XZD\AI\V5\Core\Config::instance()->get('connections.text', []),
                fn($c) => !empty($c['api_key'])
            )),
        ];
    }

    public function runFullScan(): array
    {
        $health = $this->getHealthSummary();
        $suggestions = $this->generateSuggestions();

        $score = 100;
        $issues = [];

        if ($health['untagged_posts'] > 10) { $score -= 10; $issues[] = '多篇文章缺少标签'; }
        if ($health['stale_drafts'] > 5) { $score -= 5; $issues[] = '存在过期草稿'; }
        if ($health['no_seo_posts'] > 10) { $score -= 10; $issues[] = '多篇文章缺少SEO描述'; }
        if ($health['recent_errors_24h'] > 5) { $score -= 15; $issues[] = '近期错误率较高'; }
        if ($health['queue_backlog'] > 50) { $score -= 10; $issues[] = '任务队列积压'; }
        if ($health['total_connections'] === 0) { $score -= 20; $issues[] = '未配置AI连接'; }
        if ($health['month_cost_rmb'] > 0) {
            $budget = \XZD\AI\V5\Core\Config::instance()->get('cost.monthly_budget', 0);
            if ($budget > 0 && $health['month_cost_rmb'] > $budget * 0.9) { $score -= 10; $issues[] = '接近月度预算上限'; }
        }

        $score = max(0, $score);

        return [
            'score'        => $score,
            'grade'        => $score >= 90 ? 'A' : ($score >= 70 ? 'B' : ($score >= 50 ? 'C' : 'D')),
            'issues'       => $issues,
            'health'       => $health,
            'suggestions'  => $suggestions,
            'scanned_at'   => current_time('mysql'),
        ];
    }

    // 数据库查询辅助

    private function isAiAvailable(): bool
    {
        $connections = \XZD\AI\V5\Core\Config::instance()->get('connections.text', []);
        foreach ($connections as $conn) {
            if (!empty($conn['api_key']) && ($conn['is_enabled'] ?? true)) {
                return true;
            }
        }
        return false;
    }

    private function getAiStatus(): array
    {
        $connections = \XZD\AI\V5\Core\Config::instance()->get('connections.text', []);
        $total = count($connections);
        $enabled = 0;
        $withKey = 0;
        foreach ($connections as $conn) {
            if ($conn['is_enabled'] ?? true) $enabled++;
            if (!empty($conn['api_key'])) $withKey++;
        }
        return [
            'total'   => $total,
            'enabled' => $enabled,
            'with_key' => $withKey,
            'available' => $enabled > 0 && $withKey > 0,
        ];
    }

    private function countUntaggedPosts(): int
    {
        global $wpdb;
        return (int) $wpdb->get_var(
            "SELECT COUNT(DISTINCT p.ID) FROM {$wpdb->posts} p
             LEFT JOIN {$wpdb->term_relationships} tr ON p.ID = tr.object_id
             LEFT JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'post_tag'
             WHERE p.post_type = 'post' AND p.post_status = 'publish'
             AND tt.term_taxonomy_id IS NULL"
        );
    }

    private function countStaleDrafts(): int
    {
        global $wpdb;
        return (int) $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->posts}
             WHERE post_type = 'post' AND post_status = 'draft'
             AND post_modified < %s",
            date('Y-m-d H:i:s', strtotime('-7 days'))
        ));
    }

    private function countPostsWithoutMeta(string $metaKey): int
    {
        global $wpdb;
        return (int) $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->posts} p
             WHERE p.post_type = 'post' AND p.post_status = 'publish'
             AND NOT EXISTS (
                 SELECT 1 FROM {$wpdb->postmeta} pm
                 WHERE pm.post_id = p.ID AND pm.meta_key = %s
             )",
            $metaKey
        ));
    }

    private function countPostsWithoutThumbnail(): int
    {
        global $wpdb;
        return (int) $wpdb->get_var(
            "SELECT COUNT(*) FROM {$wpdb->posts} p
             WHERE p.post_type = 'post' AND p.post_status = 'publish'
             AND NOT EXISTS (
                 SELECT 1 FROM {$wpdb->postmeta} pm
                 WHERE pm.post_id = p.ID AND pm.meta_key = '_thumbnail_id'
             )"
        );
    }

    private function countRecentErrors(): int
    {
        global $wpdb;
        return (int) $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->prefix}xzd_ai_operation_log
             WHERE status IN ('error', 'failed') AND created_at > %s",
            date('Y-m-d H:i:s', strtotime('-24 hours'))
        ));
    }

    private function getMonthCost(): float
    {
        global $wpdb;
        return (float) $wpdb->get_var($wpdb->prepare(
            "SELECT COALESCE(SUM(cost_rmb), 0) FROM {$wpdb->prefix}xzd_ai_cost_log
             WHERE created_at >= %s",
            date('Y-m-01')
        ));
    }

    private function countQueueBacklog(): int
    {
        return \XZD\AI\V5\Tools\QueueManager::getTotalBacklog();
    }

    private function countPendingUpdates(): int
    {
        if (!function_exists('get_plugin_updates') || !function_exists('get_theme_updates')) {
            require_once ABSPATH . 'wp-admin/includes/update.php';
        }
        $pluginUpdates = count((array) get_plugin_updates());
        $themeUpdates = count((array) get_theme_updates());
        $coreUpdates = get_core_updates();
        $coreNeedsUpdate = 0;
        if (!empty($coreUpdates) && isset($coreUpdates[0]->response) && $coreUpdates[0]->response !== 'latest') {
            $coreNeedsUpdate = 1;
        }
        return $pluginUpdates + $themeUpdates + $coreNeedsUpdate;
    }

    private function countNewPosts(int $days): int
    {
        global $wpdb;
        return (int) $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->posts}
             WHERE post_type = 'post' AND post_status = 'publish'
             AND post_date > %s",
            date('Y-m-d H:i:s', strtotime("-{$days} days"))
        ));
    }
}
