<?php

namespace XZD\AI\V5\Agents;

use XZD\AI\V5\Tools\BatchPipeline;
use XZD\AI\V5\Tools\ParallelExecutor;
use XZD\AI\V5\Tools\ToolRegistry;
use XZD\AI\V5\Core\Logger;

/**
 * 批量管理 Agent — Nightshift 模式处理器
 *
 * 核心理念（摘自文档 14.5）:
 *   每篇文章用独立的、干净的 Agent 上下文处理，
 *   避免单次对话中上下文膨胀导致速度/费用/质量下降。
 *
 * 工作流程:
 *   1. 为每篇文章创建独立的 AgentLoop 会话（干净上下文 ~2000 tokens 固定）
 *   2. 从已完成的任务中提取模式（如 "科技类文章标签偏技术"）
 *   3. 将学到的模式反馈给后续任务，提升质量
 *   4. 使用 ParallelExecutor 并行处理独立工具
 */
class BatchManagerAgent extends BaseAgent
{
    private BatchPipeline $pipeline;
    private ParallelExecutor $executor;
    private array $learnedPatterns = [];

    public function __construct()
    {
        parent::__construct();
        $this->pipeline = new BatchPipeline();
        $this->executor = new ParallelExecutor();
    }

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

    public function getName(): string
    {
        return '批量管理 Agent';
    }

    public function getDescription(): string
    {
        return '负责协调大批量文章的 AI 处理任务。使用 Nightshift 模式，每篇文章独立上下文处理，从已完成任务中学习模式。';
    }

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

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

    public function getSystemPrompt(string $role = 'admin', int $userId = 0): string
    {
        $profile = (new SiteProfile())->toPromptText();
        $learned = $this->getLearnedContext();
        return <<<PROMPT
你是批量处理管理 Agent，负责协调大批量文章的 AI 处理任务。

{$profile}

当前学习到的模式：
{$learned}

你的能力：
- 创建批量任务（指定文章范围和要执行的处理阶段）
- 监控任务进度
- 重试失败项
- 从已完成任务中提取可复用的模式

使用 Nightshift 模式：每篇文章独立处理，保持上下文干净。
PROMPT;
    }

    /**
     * 处理批量请求 — 核心入口
     *
     * @param array $postIds   文章 ID 列表
     * @param array $stages    要执行的阶段
     * @param array $options   选项
     * @return \Generator  每完成一篇文章 yield 一次
     */
    public function processBatch(array $postIds, array $stages, array $options = []): \Generator
    {
        $batchSize = $options['batch_size'] ?? $this->pipeline->detectBatchSize(count($postIds));
        $chunks = array_chunk($postIds, $batchSize);

        $totalPosts = count($postIds);
        $processedCount = 0;
        $successCount = 0;
        $failedCount = 0;

        // 重置学习模式
        $this->learnedPatterns = [];

        foreach ($chunks as $chunkIndex => $chunk) {
            foreach ($chunk as $postId) {
                $post = get_post($postId);
                if (!$post) {
                    $failedCount++;
                    $processedCount++;
                    yield [
                        'post_id'      => $postId,
                        'success'      => false,
                        'message'      => '文章不存在',
                        'progress'     => round($processedCount / $totalPosts * 100, 1),
                        'total'        => $totalPosts,
                        'processed'    => $processedCount,
                        'success_cnt'  => $successCount,
                        'failed_cnt'   => $failedCount,
                    ];
                    continue;
                }

                // Nightshift 模式: 每篇文章独立上下文
                $toolCalls = [];
                foreach ($stages as $stage) {
                    $toolCalls[] = [
                        'tool_id' => $stage,
                        'params'  => ['post_id' => $postId],
                    ];
                }

                // 并行执行独立工具
                $prevCtx = \XZD\AI\V5\Tools\ToolRegistry::enterSystemContext();
                try {
                    $results = $this->executor->execute($toolCalls, 0);
                } finally {
                    \XZD\AI\V5\Tools\ToolRegistry::restoreSystemContext($prevCtx);
                }
                $allSuccess = true;

                foreach ($results as $r) {
                    if (!$r['success']) {
                        $allSuccess = false;
                        break;
                    }
                }

                if ($allSuccess) {
                    $successCount++;
                    // 学习模式
                    $this->learn($post, $results);
                } else {
                    $failedCount++;
                }

                $processedCount++;

                yield [
                    'post_id'      => $postId,
                    'post_title'   => $post->post_title,
                    'success'      => $allSuccess,
                    'stage_results'=> $results,
                    'progress'     => round($processedCount / $totalPosts * 100, 1),
                    'total'        => $totalPosts,
                    'processed'    => $processedCount,
                    'success_cnt'  => $successCount,
                    'failed_cnt'   => $failedCount,
                    'patterns'     => $this->learnedPatterns,
                ];

                // 内存保护
                if (memory_get_usage() > 50 * 1024 * 1024) {
                    gc_collect_cycles();
                }
            }

            // 每批之间暂停 1 秒（避免 API 限流）
            if ($chunkIndex < count($chunks) - 1) {
                sleep(1);
            }
        }

        yield [
            'done'         => true,
            'total'        => $totalPosts,
            'processed'    => $processedCount,
            'success_cnt'  => $successCount,
            'failed_cnt'   => $failedCount,
            'patterns'     => $this->learnedPatterns,
        ];
    }

    /**
     * 从成功案例中学习模式
     *
     * 例如: 科技类文章 → 标签偏技术词 | 生活类 → 偏日常词
     */
    private function learn(\WP_Post $post, array $results): void
    {
        $categories = wp_get_post_categories($post->ID, ['fields' => 'names']);
        $catKey = !empty($categories) ? implode(',', $categories) : 'uncategorized';

        if (!isset($this->learnedPatterns[$catKey])) {
            $this->learnedPatterns[$catKey] = [
                'category'     => $catKey,
                'count'        => 0,
                'sample_tags'  => [],
                'sample_seo'   => [],
            ];
        }

        $this->learnedPatterns[$catKey]['count']++;

        foreach ($results as $r) {
            if (!$r['success']) {
                continue;
            }
            $toolId = $r['tool_id'] ?? '';
            $data = $r['data'] ?? null;
            if (!$data) {
                continue;
            }

            // 收集标签样例
            if ($toolId === 'generate_tags' && !empty($data['tags'])) {
                $this->learnedPatterns[$catKey]['sample_tags'] = array_merge(
                    $this->learnedPatterns[$catKey]['sample_tags'],
                    array_slice((array)$data['tags'], 0, 3)
                );
            }

            // 收集 SEO 关键词样例
            if ($toolId === 'generate_seo' && !empty($data['keywords'])) {
                $this->learnedPatterns[$catKey]['sample_seo'] = array_merge(
                    $this->learnedPatterns[$catKey]['sample_seo'],
                    array_slice((array)$data['keywords'], 0, 3)
                );
            }
        }

        // 去重
        $this->learnedPatterns[$catKey]['sample_tags'] = array_unique(
            $this->learnedPatterns[$catKey]['sample_tags']
        );
        $this->learnedPatterns[$catKey]['sample_seo'] = array_unique(
            $this->learnedPatterns[$catKey]['sample_seo']
        );
    }

    /**
     * 获取学到的模式上下文
     */
    public function getLearnedContext(): string
    {
        if (empty($this->learnedPatterns)) {
            return '暂无学习到的模式。';
        }

        $lines = [];
        foreach ($this->learnedPatterns as $catKey => $pattern) {
            if ($pattern['count'] === 0) {
                continue;
            }
            $tags = !empty($pattern['sample_tags']) ? implode('、', $pattern['sample_tags']) : '无';
            $keywords = !empty($pattern['sample_seo']) ? implode('、', $pattern['sample_seo']) : '无';
            $lines[] = "- {$catKey}（已处理 {$pattern['count']} 篇）→ 标签示例: {$tags} | 关键词示例: {$keywords}";
        }

        return "从已完成的任务中学习到的模式：\n" . implode("\n", $lines);
    }

    /**
     * 处理用户对话消息
     */
    public function handle(string $message, string $role): array
    {
        // 委托给 Orchestrator 的路由系统
        return [
            'content' => '批量处理功能已通过 REST API 和后台界面开放。请使用以下方式：\n'
                . '- 后台 → 功能配置 → 批量操作\n'
                . '- 对我说 "帮我处理最近N篇文章的标签和SEO"\n'
                . '- API: POST /wp-json/xzdbk-ai/v1/pipeline/run',
        ];
    }
}
