<?php

namespace XZD\AI\V5\Agents;

use XZD\AI\V5\AI\Client;
use XZD\AI\V5\AI\Types;
use XZD\AI\V5\Core\Logger;

/**
 * 意图解析器 — 三层级联路由
 *
 * L1: 关键词/正则匹配 (零成本, <1ms)
 * L2: 案例库检索 (DB 查询, <10ms)
 * L3: AI 语义判断 (~500ms)
 */
class IntentParser
{
    // L1 路由规则表
    private const ROUTING_RULES = [
        'content' => [
            'agent'    => 'content',
            'patterns' => [
                '/写.*文章|生成.*文章|AI.*写|草稿|批量.*生成/',
                '/标签|tag|关键词|keyword/',
                '/SEO|优化|排名|关键词密度|描述|title/i',
                '/摘要|summary|总结|概括/',
                '/润色|polish|改写|翻译|扩展|缩写/',
                '/封面|cover|特色图|缩略图|配图/',
                '/质量|评分|score|检测|去重|查重/',
                '/内链|autolink|链接|锚文本/',
                '/ALT|alt|图片描述|替代文本/',
            ],
        ],
        'site_manager' => [
            'agent'    => 'site_manager',
            'patterns' => [
                '/删除.*文章|文章.*删除|批量.*删除/',
                '/修改.*设置|网站.*设置|站点.*配置|全局.*设置/',
                '/插件|plugin|激活|停用|启用.*插件/',
                '/清除.*缓存|缓存.*清理|刷新.*缓存/',
                '/分类|category|taxonomy|目录/',
                '/Schema|结构化|标记|schema/',
                '/推送|push|index|百度|Bing|Google.*提交/',
                '/死链|dead.?link|检测.*链接|404/',
                '/统计|stats|概览|仪表|数据.*分析/',
                '/评论|comment|回复.*评论/',
                '/更新.*插件|插件.*更新|升级.*插件|检查.*更新|最新.*版本|插件.*版本/',
            ],
        ],
        'user_manager' => [
            'agent'    => 'user_manager',
            'patterns' => [
                '/用户.*创建|创建.*用户|用户.*删除|删除.*用户/',
                '/改.*角色|设置.*角色|权限.*分配/',
            ],
        ],
        'theme' => [
            'agent'    => 'theme',
            'patterns' => [
                '/积分|points|奖励/',
                '/余额|balance|充值|扣费|支付/',
                '/VIP|会员|vip|等级|升级|特权/',
                '/封禁|ban|拉黑|解封|黑名单|禁用/',
                '/通知|私信|消息|message|站内信/',
                '/签到|checkin|打卡/',
                '/邀请|invite|推荐.*用户/',
                '/主题|theme|外观|样式|皮肤/',
                '/颜色|配色|字体|布局|CSS/',
                '/子比|zibll/',
                '/勋章|徽章|medal|badge/',
                '/订单|order|退款|交易/',
                '/论坛|bbs|帖子|社区/',
            ],
        ],
    ];

    /**
     * 解析意图 — 三层级联
     *
     * @return array ['agent'=>'content|site_manager|user_manager|theme','confidence'=>0.XX,'method'=>'keyword|case|ai','reason'=>'']
     */
    public function parse(string $message): array
    {
        // L1: 关键词匹配
        $l1 = $this->keywordMatch($message);
        if ($l1['confidence'] >= 0.8) {
            return $l1;
        }

        // L2: 案例库检索
        $l2 = $this->caseLookup($message);
        if ($l2['confidence'] >= 0.7) {
            return $l2;
        }

        // L2 补充: 如果 L1 有低置信度匹配，合并使用
        if ($l1['confidence'] >= 0.3) {
            return $l1;
        }

        // L3: AI 语义判断
        return $this->aiClassify($message);
    }

    /**
     * 批量解析
     */
    public function parseBatch(array $messages): array
    {
        return array_map(fn($m) => $this->parse($m), $messages);
    }

    /**
     * 预测意图——仅使用 L1+L2（不调用 AI）
     */
    public function quickPredict(string $message): array
    {
        $l1 = $this->keywordMatch($message);
        if ($l1['confidence'] >= 0.8) {
            return $l1;
        }
        return $this->caseLookup($message);
    }

    private function keywordMatch(string $message): array
    {
        $bestAgent = '';
        $bestCount = 0;

        foreach (self::ROUTING_RULES as $category => $rule) {
            $matchCount = 0;
            foreach ($rule['patterns'] as $pattern) {
                if (preg_match($pattern, $message)) {
                    $matchCount++;
                }
            }
            if ($matchCount > $bestCount) {
                $bestCount = $matchCount;
                $bestAgent = $rule['agent'];
            }
        }

        if ($bestCount === 0) {
            return ['agent' => 'orchestrator', 'confidence' => 0.0, 'method' => 'keyword', 'reason' => '无匹配关键词，由总调度 Agent 处理'];
        }

        $confidence = match (true) {
            $bestCount >= 3 => 0.95,
            $bestCount >= 2 => 0.85,
            default       => 0.6,
        };

        return [
            'agent'      => $bestAgent,
            'confidence' => $confidence,
            'method'     => 'keyword',
            'reason'     => "匹配 {$bestCount} 个关键词",
        ];
    }

    private function caseLookup(string $message): array
    {
        global $wpdb;
        $table = $wpdb->prefix . 'xzd_ai_intent_cases';

        // 检查表是否存在
        if ($wpdb->get_var("SHOW TABLES LIKE '{$table}'") !== $table) {
            return ['agent' => 'orchestrator', 'confidence' => 0.0, 'method' => 'case', 'reason' => '意图案例表不存在'];
        }

        // 简单全文搜索（提取关键词）
        $keywords = $this->extractKeywords($message, 5);
        if (empty($keywords)) {
            return ['agent' => 'orchestrator', 'confidence' => 0.0, 'method' => 'case', 'reason' => '无有效关键词'];
        }

        $likeClauses = [];
        $likeValues = [];
        foreach ($keywords as $kw) {
            $likeClauses[] = 'pattern LIKE %s';
            $likeValues[] = '%' . $wpdb->esc_like($kw) . '%';
        }

        $query = "SELECT agent, intent, confidence, SUM(example_count) as total_count
                  FROM {$table}
                  WHERE " . implode(' OR ', $likeClauses) . "
                  GROUP BY agent, intent, confidence
                  ORDER BY total_count DESC
                  LIMIT 3";

        $rows = $wpdb->get_results($wpdb->prepare($query, ...$likeValues), ARRAY_A);

        if (empty($rows)) {
            return ['agent' => 'orchestrator', 'confidence' => 0.0, 'method' => 'case', 'reason' => '案例库无匹配'];
        }

        $top = $rows[0];
        return [
            'agent'      => $top['agent'],
            'confidence' => min((float) $top['confidence'], 0.85),
            'method'     => 'case',
            'reason'     => "匹配案例: {$top['intent']}",
        ];
    }

    private function aiClassify(string $message): array
    {
        // 意图分类缓存 — 相同消息5分钟内不重复调用AI
        $cacheKey = 'xzd_intent_' . md5(trim($message));
        $cached = get_transient($cacheKey);
        if ($cached && is_array($cached)) {
            Logger::info('intent_cache', "意图分类缓存命中: " . $cached['agent']);
            return $cached;
        }

        try {
            $client = Client::instance();

            $systemPrompt = <<<PROMPT
你是一个意图分类器。分析用户消息，将其归类到以下 Agent 之一:

- content: 内容创作 (写文章/改文章/标签/SEO/润色/翻译/封面图/摘要/内链/去重)
- site_manager: 站点管理 (文章CRUD/设置/插件/缓存/分类/评论/数据统计/死链检测/搜索推送)
- user_manager: 用户管理 (创建/删除用户/角色变更)
- theme: 主题与用户资产 (积分/余额/VIP/封禁/通知/签到/邀请/勋章/订单/论坛/主题外观)

只回复 JSON: {"agent":"content|site_manager|user_manager|theme","confidence":0.0-1.0,"reason":"简短理由"}
PROMPT;

            // 意图分类是简单任务，路由到便宜模型并关闭 thinking 省 token
            $intentOpts = ['temperature' => 0, 'max_tokens' => 100, 'disable_thinking' => true];
            $simpleModel = \XZD\AI\V5\Core\Config::instance()->get('simple_task_model', 'deepseek-v4-flash');
            if (!empty($simpleModel)) {
                $intentOpts['model'] = $simpleModel;
            }
            $result = $client->chat([
                Types::system($systemPrompt),
                Types::user($message),
            ], $intentOpts);

            $content = $result['content'] ?? '';

            // 容忍AI返回markdown代码块或多余文本
            $jsonStr = $content;
            if (preg_match('/```(?:json)?\s*\n?(.*?)\n?```/s', $content, $m)) {
                $jsonStr = trim($m[1]);
            } elseif (preg_match('/\{[^}]*"agent"\s*:\s*"[^"]*"[^}]*\}/s', $content, $m)) {
                $jsonStr = $m[0];
            }

            $json = json_decode($jsonStr, true);

            if ($json && isset($json['agent'])) {
                $result = [
                    'agent'      => $json['agent'],
                    'confidence' => (float) ($json['confidence'] ?? 0.7),
                    'method'     => 'ai',
                    'reason'     => $json['reason'] ?? 'AI 语义判断',
                ];
                // 缓存意图分类结果5分钟
                set_transient($cacheKey, $result, 300);
                return $result;
            }

            Logger::warning('intent_ai', "AI 分类返回无效 JSON: {$content}");
        } catch (\Throwable $e) {
            Logger::error('intent_ai', $e->getMessage());
        }

        return ['agent' => 'orchestrator', 'confidence' => 0.5, 'method' => 'ai_fallback', 'reason' => 'AI 分类失败，由总调度 Agent 处理'];
    }

    /**
     * 从消息中提取关键词
     */
    private function extractKeywords(string $message, int $limit = 5): array
    {
        // 移除标点和常见停用词
        $cleaned = preg_replace('/[^\x{4e00}-\x{9fff}\w\s]/u', ' ', $message);
        $words = preg_split('/\s+/', trim($cleaned));
        $stopWords = ['的', '了', '在', '是', '我', '有', '和', '就', '不', '人', '都', '一', '一个', '上', '也', '很', '到', '说', '要', '去', '你', '会', '着', '没有', '看', '好', '自己', '这'];
        $words = array_filter($words, fn($w) =>
            mb_strlen($w) >= 2 && !in_array(mb_strtolower($w), $stopWords)
        );
        return array_slice(array_values($words), 0, $limit);
    }

    /**
     * 添加意图案例
     */
    public function addCase(string $pattern, string $intent, string $agent, float $confidence = 0.80): bool
    {
        global $wpdb;
        $table = $wpdb->prefix . 'xzd_ai_intent_cases';

        return (bool) $wpdb->insert($table, [
            'pattern'       => $pattern,
            'intent'        => $intent,
            'agent'         => $agent,
            'confidence'    => $confidence,
            'example_count' => 1,
            'created_at'    => current_time('mysql'),
        ]);
    }

    /**
     * 增强已有案例
     */
    public function boostCase(int $caseId): void
    {
        global $wpdb;
        $table = $wpdb->prefix . 'xzd_ai_intent_cases';
        $wpdb->query("UPDATE {$table} SET example_count = example_count + 1 WHERE id = " . (int) $caseId);
    }
}
