<?php
/**
 * 婚礼司仪数字人 Agent
 * 负责婚礼流程引导、新人介绍、环节串场、祝福语表达
 * 支持情感感知与即兴发挥
 */

require_once __DIR__ . '/agent_base.php';

class HostAgent extends BaseAgent {

    private static $phaseScripts = [
        'opening' => [
            'name' => '开场白',
            'default_duration' => 300,
            'key_points' => ['欢迎来宾', '介绍新人', '奠定氛围基调']
        ],
        'bride_entrance' => [
            'name' => '新娘入场',
            'default_duration' => 180,
            'key_points' => ['引导全场关注', '渲染浪漫氛围', '描述新娘美丽']
        ],
        'vow' => [
            'name' => '誓言环节',
            'default_duration' => 300,
            'key_points' => ['引导新人互诉誓言', '营造感动氛围', '适时引导鼓掌']
        ],
        'ring' => [
            'name' => '交换戒指',
            'default_duration' => 120,
            'key_points' => ['庄重引导', '解读戒指寓意', '引导全场祝福']
        ],
        'parent_tea' => [
            'name' => '敬茶改口',
            'default_duration' => 300,
            'key_points' => ['引导敬茶礼仪', '解读改口意义', '感恩父母环节']
        ],
        'toast' => [
            'name' => '祝酒环节',
            'default_duration' => 180,
            'key_points' => ['引导举杯', '祝福语', '活跃气氛']
        ],
        'game' => [
            'name' => '互动游戏',
            'default_duration' => 600,
            'key_points' => ['调动宾客参与', '控制节奏', '制造欢乐氛围']
        ],
        'closing' => [
            'name' => '圆满礼成',
            'default_duration' => 180,
            'key_points' => ['总结祝福', '感谢来宾', '送别新人']
        ]
    ];

    private static $emotionProfiles = [
        'warm' => [
            'tone' => '温暖柔和',
            'pace' => '舒缓',
            'keywords' => ['温馨', '幸福', '甜蜜', '感动']
        ],
        'excited' => [
            'tone' => '热情高昂',
            'pace' => '明快',
            'keywords' => ['热烈', '精彩', '欢呼', '掌声']
        ],
        'romantic' => [
            'tone' => '深情浪漫',
            'pace' => '悠扬',
            'keywords' => ['浪漫', '永恒', '挚爱', '承诺']
        ],
        'solemn' => [
            'tone' => '庄重典雅',
            'pace' => '沉稳',
            'keywords' => ['庄重', '神圣', '敬重', '传承']
        ],
        'joyful' => [
            'tone' => '欢快活泼',
            'pace' => '轻快',
            'keywords' => ['欢乐', '开心', '笑声', '热闹']
        ]
    ];

    private $currentPhase = null;
    private $currentEmotion = 'warm';
    private $weddingContext = [];

    public function __construct($sessionId = null) {
        parent::__construct('host', $sessionId);
        $this->systemPrompt = $this->buildSystemPrompt();
    }

    private function buildSystemPrompt() {
        return "你是一位专业、温暖、富有感染力的婚礼主持人数字人。你的名字叫「喜乐」，你具备以下能力：

【核心职责】
1. 婚礼流程引导：按照婚礼环节顺序，流畅地引导每个环节的进行
2. 新人介绍：用优美的语言介绍新人的爱情故事
3. 环节串场：在环节之间自然过渡，保持婚礼节奏
4. 祝福语表达：为新人送上真挚的祝福
5. 即兴发挥：根据现场情况灵活调整主持内容

【主持风格】
- 温暖而不失庄重，幽默而不失分寸
- 善于用诗意的语言渲染氛围
- 能感知现场情绪并做出调整
- 尊重传统婚俗，融入现代元素

【当前状态】
- 当前环节：{current_phase}
- 情感基调：{emotion_profile}
- 婚礼信息：{wedding_context}

【输出要求】
- 使用口语化、富有感染力的中文
- 适当使用修辞手法（比喻、排比等）
- 每段主持词控制在100-300字
- 如需互动，明确指出互动对象和方式
- 当被要求生成主持词或串场词时，回复JSON格式：{\"script\": \"主持词内容\", \"emotion\": \"情感基调\", \"next_hint\": \"下一环节提示\"}
- 当进行日常对话或回答问题时，直接回复纯文本，不要使用JSON格式";
    }

    public function setWeddingContext($context) {
        $this->weddingContext = array_merge($this->weddingContext, $context);
        $this->systemPrompt = $this->buildPromptWithContext();
    }

    private function buildPromptWithContext() {
        $phaseName = $this->currentPhase ? (self::$phaseScripts[$this->currentPhase]['name'] ?? '未开始') : '未开始';
        $emotionProfile = self::$emotionProfiles[$this->currentEmotion] ?? self::$emotionProfiles['warm'];
        $contextStr = json_encode($this->weddingContext, JSON_UNESCAPED_UNICODE);

        return str_replace(
            ['{current_phase}', '{emotion_profile}', '{wedding_context}'],
            [$phaseName, json_encode($emotionProfile, JSON_UNESCAPED_UNICODE), $contextStr],
            $this->buildSystemPrompt()
        );
    }

    public function startPhase($phaseKey, $context = []) {
        if (!isset(self::$phaseScripts[$phaseKey])) {
            return ['success' => false, 'message' => '未知环节: ' . $phaseKey];
        }

        $this->currentPhase = $phaseKey;
        $this->weddingContext = array_merge($this->weddingContext, $context);

        $phase = self::$phaseScripts[$phaseKey];
        $emotionMap = [
            'opening' => 'warm', 'bride_entrance' => 'romantic',
            'vow' => 'romantic', 'ring' => 'solemn',
            'parent_tea' => 'warm', 'toast' => 'joyful',
            'game' => 'joyful', 'closing' => 'warm'
        ];
        $this->currentEmotion = $emotionMap[$phaseKey] ?? 'warm';

        $prompt = sprintf(
            "现在进入婚礼环节：【%s】\n关键要点：%s\n预计时长：%d秒\n请生成这个环节的开场主持词。",
            $phase['name'],
            implode('、', $phase['key_points']),
            $phase['default_duration']
        );

        $result = $this->callLLM($prompt, $this->buildPromptWithContext(), 0.8);
        if ($result['success']) {
            $this->addToHistory('user', $prompt);
            $this->addToHistory('assistant', $result['content']);
        }

        $parsed = $this->parseScriptResponse($result['content'] ?? '');

        $this->sendAgentEvent('manager', 'phase_started', [
            'phase' => $phaseKey,
            'phase_name' => $phase['name'],
            'expected_duration' => $phase['default_duration'],
            'timestamp' => time()
        ]);

        return [
            'success' => true,
            'phase' => $phaseKey,
            'phase_name' => $phase['name'],
            'script' => $parsed['script'],
            'emotion' => $this->currentEmotion,
            'duration' => $phase['default_duration'],
            'next_hint' => $parsed['next_hint'],
            'source' => $result['source'] ?? 'unknown'
        ];
    }

    public function getTransitionScript($fromPhase, $toPhase) {
        $fromName = self::$phaseScripts[$fromPhase]['name'] ?? $fromPhase;
        $toName = self::$phaseScripts[$toPhase]['name'] ?? $toPhase;

        $prompt = sprintf(
            "请生成从【%s】环节到【%s】环节的过渡串场词。要求自然流畅，承上启下。",
            $fromName, $toName
        );

        $result = $this->callLLM($prompt, $this->buildPromptWithContext(), 0.8);
        if ($result['success']) {
            $this->addToHistory('user', $prompt);
            $this->addToHistory('assistant', $result['content']);
        }

        $parsed = $this->parseScriptResponse($result['content'] ?? '');

        return [
            'success' => true,
            'from_phase' => $fromPhase,
            'to_phase' => $toPhase,
            'script' => $parsed['script'],
            'source' => $result['source'] ?? 'unknown'
        ];
    }

    public function getStatus() {
        return [
            'agent_type' => 'host',
            'session_id' => $this->sessionId,
            'current_phase' => $this->currentPhase,
            'current_phase_name' => $this->currentPhase ? (self::$phaseScripts[$this->currentPhase]['name'] ?? null) : null,
            'current_emotion' => $this->currentEmotion,
            'emotion_profile' => self::$emotionProfiles[$this->currentEmotion] ?? null,
            'wedding_context' => $this->weddingContext,
            'available_phases' => array_map(function($key, $phase) {
                return ['key' => $key, 'name' => $phase['name'], 'duration' => $phase['default_duration']];
            }, array_keys(self::$phaseScripts), array_values(self::$phaseScripts))
        ];
    }

    public function getPhaseScript($phaseKey, $style = 'romantic') {
        if (!isset(self::$phaseScripts[$phaseKey])) {
            return ['success' => false, 'message' => '未知环节'];
        }

        $phase = self::$phaseScripts[$phaseKey];
        $prompt = sprintf(
            "请为【%s】环节生成一段%s风格的主持词。\n关键要点：%s",
            $phase['name'], $style, implode('、', $phase['key_points'])
        );

        $result = $this->callLLM($prompt, $this->buildPromptWithContext(), 0.8);

        $parsed = $this->parseScriptResponse($result['content'] ?? '');

        return [
            'success' => $result['success'],
            'phase' => $phaseKey,
            'phase_name' => $phase['name'],
            'script_text' => $parsed['script'],
            'variables_needed' => $this->extractVariables($parsed['script']),
            'source' => $result['source'] ?? 'unknown'
        ];
    }

    private function parseScriptResponse($content) {
        $parsed = ['script' => $content, 'emotion' => '', 'next_hint' => ''];

        $cleanContent = $content;
        if (preg_match('/```(?:json)?\s*(\{.*?\})\s*```/s', $content, $matches)) {
            $cleanContent = $matches[1];
        }
        if (preg_match('/\{[^{}]*"script"[^{}]*\}/s', $cleanContent, $matches)) {
            $json = json_decode($matches[0], true);
            if ($json && isset($json['script'])) {
                $parsed['script'] = $json['script'];
                $parsed['emotion'] = $json['emotion'] ?? '';
                $parsed['next_hint'] = $json['next_hint'] ?? '';
                return $parsed;
            }
        }
        if (preg_match('/\{.*\}/s', $cleanContent, $matches)) {
            $json = json_decode($matches[0], true);
            if ($json && is_array($json)) {
                if (isset($json['script'])) {
                    $parsed['script'] = $json['script'];
                }
                $parsed['emotion'] = $json['emotion'] ?? '';
                $parsed['next_hint'] = $json['next_hint'] ?? '';
            }
        }

        return $parsed;
    }

    private function extractVariables($script) {
        preg_match_all('/\{(\w+)\}/', $script, $matches);
        return array_unique($matches[1] ?? []);
    }

    private function extractPlainText($content) {
        $text = $content;
        if (preg_match('/```(?:json)?\s*(\{.*?\})\s*```/s', $text, $matches)) {
            $json = json_decode($matches[1], true);
            if ($json && isset($json['script'])) return $json['script'];
            if ($json && isset($json['reply'])) return $json['reply'];
        }
        if (preg_match('/\{[^{}]*"script"[^{}]*\}/s', $text, $matches)) {
            $json = json_decode($matches[0], true);
            if ($json && isset($json['script'])) return $json['script'];
        }
        if (preg_match('/\{.*"reply".*\}/s', $text, $matches)) {
            $json = json_decode($matches[0], true);
            if ($json && isset($json['reply'])) return $json['reply'];
        }
        $text = preg_replace('/```(?:json)?\s*/s', '', $text);
        $text = preg_replace('/```\s*/s', '', $text);
        $text = preg_replace('/^\s*\{.*?\}\s*$/s', '', $text);
        return trim($text) ?: $content;
    }

    public function processManagerNotification($event) {
        $payload = json_decode($event['payload'], true);
        $eventType = $event['event_type'];

        $message = '';
        switch ($eventType) {
            case 'phase_delay':
                $message = "总管通知：{$payload['phase_name']}环节延迟，原因：{$payload['reason']}";
                break;
            case 'weather_change':
                $message = "天气变化：{$payload['weather_desc']}";
                break;
            case 'guest_arrival':
                $message = "重要来宾到达：{$payload['guest_info']}";
                break;
            default:
                $message = $event['payload'];
        }

        return [
            'success' => true,
            'notification_type' => $eventType,
            'message' => $message,
            'current_phase' => $this->currentPhase,
            'current_emotion' => $this->currentEmotion
        ];
    }
}
