#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
急语箱 MCP 服务器 - 使用官方 MCP SDK
高情商沟通助手 - 场景识别服务
"""

import os
import sys
import pickle
import logging
from pathlib import Path
from typing import Optional

from mcp.server.fastmcp import FastMCP

# 配置日志（输出到 stderr，避免干扰 stdout）
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    stream=sys.stderr
)
logger = logging.getLogger(__name__)

# 创建 MCP 服务器实例
mcp = FastMCP(
    "急语箱MCP服务器",
    dependencies=["scikit-learn"]
)


# 全局变量存储模型
vectorizer = None
model = None
reverse_label_map = None


def load_model():
    """加载 ML 模型"""
    global vectorizer, model, reverse_label_map

    try:
        # 尝试从多个位置加载模型
        possible_paths = [
            # PyPI 包安装后的路径
            Path(__file__).parent.parent / "models" / "lightweight_model_all_data.pkl",
            # 本地开发路径
            Path(__file__).parent.parent.parent.parent / "tests" / "ml_output" / "lightweight_model_all_data.pkl",
            # 相对于当前工作目录
            Path("tests/ml_output/lightweight_model_all_data.pkl"),
        ]

        model_path = None
        for path in possible_paths:
            if path.exists():
                model_path = path
                break

        if model_path:
            with open(model_path, 'rb') as f:
                model_data = pickle.load(f)
            vectorizer = model_data['vectorizer']
            model = model_data['model']
            reverse_label_map = model_data['reverse_label_map']
            logger.info(f"模型加载成功: {model_path}")
        else:
            logger.warning("模型文件未找到，场景识别功能将不可用")
    except Exception as e:
        logger.error(f"模型加载失败: {str(e)}")


# 启动时加载模型
load_model()


@mcp.tool()
def recognize_scenario(text: str) -> str:
    """
    识别对话场景

    支持职场、爱情、家庭、社交四种场景的识别，准确率95%+

    参数:
    - text: 需要识别场景的对话文本

    返回:
    - JSON 字符串，包含场景类型和置信度
    """
    import json

    if not model or not vectorizer:
        return json.dumps({
            "scenario": "unknown",
            "confidence": 0.0,
            "error": "模型未加载"
        }, ensure_ascii=False, indent=2)

    try:
        features = vectorizer.transform([text])
        pred_label = model.predict(features)[0]
        predicted = reverse_label_map[pred_label]

        # 获取置信度
        confidence = 0.95
        if hasattr(model, 'predict_proba'):
            proba = model.predict_proba(features)[0]
            confidence = float(proba[pred_label])

        return json.dumps({
            "scenario": predicted,
            "confidence": round(confidence, 4)
        }, ensure_ascii=False, indent=2)

    except Exception as e:
        logger.error(f"场景识别失败: {str(e)}")
        return json.dumps({
            "scenario": "unknown",
            "confidence": 0.0,
            "error": str(e)
        }, ensure_ascii=False, indent=2)


@mcp.tool()
def analyze_participants(text: str) -> str:
    """
    分析对话参与者

    识别对话中涉及的人数和角色关系

    参数:
    - text: 需要分析的对话文本

    返回:
    - JSON 字符串，包含参与者数量和列表
    """
    import json

    try:
        lines = text.split('\n')
        speakers = set()

        for line in lines:
            line = line.strip()
            if ':' in line:
                speaker = line.split(':')[0].strip()
                if speaker and len(speaker) < 20:
                    speakers.add(speaker)

        return json.dumps({
            "participant_count": len(speakers),
            "participants": list(speakers)
        }, ensure_ascii=False, indent=2)

    except Exception as e:
        logger.error(f"参与者分析失败: {str(e)}")
        return json.dumps({
            "error": str(e)
        }, ensure_ascii=False, indent=2)


@mcp.tool()
def analyze_relationship(text: str) -> str:
    """
    分析对话者关系

    判断是平等关系、上下级关系还是亲密关系

    参数:
    - text: 需要分析的对话文本

    返回:
    - JSON 字符串，包含关系类型和置信度
    """
    import json

    try:
        relationship = "unknown"
        confidence = 0.5

        # 关键词分析
        keywords = {
            "平等": ["同事", "同学", "朋友", "伙伴"],
            "上下级": ["老板", "经理", "领导", "下属", "员工", "主管"],
            "亲密": ["亲爱的", "宝贝", "老公", "老婆", "爸", "妈", "孩子"]
        }

        text_lower = text.lower()
        scores = {}

        for rel, words in keywords.items():
            score = sum(1 for word in words if word in text_lower)
            if score > 0:
                scores[rel] = score

        if scores:
            relationship = max(scores, key=scores.get)
            confidence = min(0.9, 0.5 + scores[relationship] * 0.1)

        return json.dumps({
            "relationship": relationship,
            "confidence": round(confidence, 4)
        }, ensure_ascii=False, indent=2)

    except Exception as e:
        logger.error(f"关系分析失败: {str(e)}")
        return json.dumps({
            "error": str(e)
        }, ensure_ascii=False, indent=2)


@mcp.tool()
def analyze_attitude(text: str) -> str:
    """
    分析对话态度

    识别说话人的情绪和态度倾向

    参数:
    - text: 需要分析的对话文本

    返回:
    - JSON 字符串，包含态度类型和置信度
    """
    import json

    try:
        attitude = "neutral"
        confidence = 0.5

        # 情感词分析
        positive_words = ["好", "棒", "优秀", "赞", "喜欢", "爱", "感谢"]
        negative_words = ["差", "坏", "讨厌", "恨", "不满", "生气", "愤怒"]

        pos_count = sum(1 for word in positive_words if word in text)
        neg_count = sum(1 for word in negative_words if word in text)

        if pos_count > neg_count:
            attitude = "positive"
            confidence = min(0.9, 0.5 + pos_count * 0.1)
        elif neg_count > pos_count:
            attitude = "negative"
            confidence = min(0.9, 0.5 + neg_count * 0.1)

        return json.dumps({
            "attitude": attitude,
            "confidence": round(confidence, 4)
        }, ensure_ascii=False, indent=2)

    except Exception as e:
        logger.error(f"态度分析失败: {str(e)}")
        return json.dumps({
            "error": str(e)
        }, ensure_ascii=False, indent=2)


@mcp.resource("jyu://scenarios")
def list_scenarios() -> str:
    """
    列出支持的场景类型

    返回:
    - JSON 字符串，包含所有支持的场景类型
    """
    import json

    scenarios = {
        "workplace": "职场场景",
        "love": "爱情场景",
        "family": "家庭场景",
        "social": "社交场景"
    }

    return json.dumps({
        "supported_scenarios": scenarios,
        "total_count": len(scenarios),
        "accuracy": "95%+"
    }, ensure_ascii=False, indent=2)


@mcp.prompt()
def scenario_analysis_guide() -> str:
    """急语箱场景识别使用指南"""
    return """
# 急语箱 MCP 服务器使用指南

## 功能介绍

急语箱 MCP 服务器提供高情商沟通助手功能，可以帮助您：

1. **场景识别** - 自动识别对话属于职场、爱情、家庭还是社交场景
2. **参与者分析** - 识别对话中涉及的人数和角色
3. **关系分析** - 判断对话者之间的关系类型
4. **态度分析** - 识别说话人的情绪和态度倾向

## 可用工具

### recognize_scenario
识别对话场景，支持四种场景类型，准确率95%+

参数:
- text: 对话文本

返回:
- scenario: 场景类型
- confidence: 置信度

### analyze_participants
分析对话参与者

参数:
- text: 对话文本

返回:
- participant_count: 参与者数量
- participants: 参与者列表

### analyze_relationship
分析对话者关系

参数:
- text: 对话文本

返回:
- relationship: 关系类型 (平等/上下级/亲密)
- confidence: 置信度

### analyze_attitude
分析对话态度

参数:
- text: 对话文本

返回:
- attitude: 态度类型 (positive/negative/neutral)
- confidence: 置信度

## Claude Desktop 配置示例

```json
{
  "mcpServers": {
    "jyu-mcp": {
      "command": "uvx",
      "args": ["jyu-mcp-server"]
    }
  }
}
```

## 使用示例

您可以直接在对话中让 Claude 使用这些工具：

```
用户：帮我分析这段对话的场景和态度：
"老板，这个项目的方案我已经完成了，请您过目。"

Claude：我来帮您分析这段对话...
[调用 recognize_scenario 和 analyze_attitude]
这段对话的场景是：职场场景
态度是：积极正面
```
"""


def main():
    """启动 MCP 服务器"""
    logger.info("急语箱 MCP Server (STDIO) 启动")
    mcp.run()


if __name__ == "__main__":
    main()
