#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
思维模型增强器 - P2增强功能模块
Thinking Model Enhancer - P2 Enhancement Module

实现P2增强功能：
- 思维模型模板库
- 自定义模型配置
- 自动化触发机制
"""

import json
import re
from pathlib import Path
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Any, Callable
from dataclasses import dataclass, field
from enum import Enum
import hashlib


class TriggerType(Enum):
    """触发类型"""
    KEYWORD = "keyword"           # 关键词触发
    PATTERN = "pattern"           # 正则模式触发
    SCHEDULE = "schedule"         # 定时触发
    CONTEXT = "context"           # 上下文触发
    API = "api"                   # API调用触发


class TriggerMode(Enum):
    """触发模式"""
    MANUAL = "manual"             # 手动确认
    AUTO = "auto"                 # 自动执行
    SUGGEST = "suggest"           # 建议模式


@dataclass
class ThinkingTemplate:
    """思维模型模板"""
    template_id: str
    name: str
    description: str
    category: str  # 创建/修复/分析/决策/研究
    stages: List[Dict]  # 阶段定义
    conditions: List[str]  # 适用条件
    examples: List[str]  # 使用示例
    version: str = "1.0"
    author: str = "system"
    created_at: str = ""
    use_count: int = 0
    rating: float = 0.0
    tags: List[str] = field(default_factory=list)
    custom_fields: Dict = field(default_factory=dict)
    
    def to_dict(self) -> Dict:
        return {
            "template_id": self.template_id,
            "name": self.name,
            "description": self.description,
            "category": self.category,
            "stages": self.stages,
            "conditions": self.conditions,
            "examples": self.examples,
            "version": self.version,
            "author": self.author,
            "created_at": self.created_at or datetime.now().isoformat(),
            "use_count": self.use_count,
            "rating": self.rating,
            "tags": self.tags,
            "custom_fields": self.custom_fields
        }


@dataclass
class TriggerRule:
    """触发规则"""
    rule_id: str
    name: str
    trigger_type: TriggerType
    trigger_value: str  # 关键词/模式/时间/上下文
    mode: TriggerMode
    target_model: str  # 目标思维模型
    priority: int  # 优先级
    enabled: bool = True
    cooldown_seconds: int = 300  # 冷却时间
    last_triggered: Optional[str] = None
    conditions: List[str] = field(default_factory=list)
    actions: List[str] = field(default_factory=list)
    
    def to_dict(self) -> Dict:
        return {
            "rule_id": self.rule_id,
            "name": self.name,
            "trigger_type": self.trigger_type.value,
            "trigger_value": self.trigger_value,
            "mode": self.mode.value,
            "target_model": self.target_model,
            "priority": self.priority,
            "enabled": self.enabled,
            "cooldown_seconds": self.cooldown_seconds,
            "last_triggered": self.last_triggered,
            "conditions": self.conditions,
            "actions": self.actions
        }


@dataclass
class CustomModelConfig:
    """自定义模型配置"""
    model_id: str
    name: str
    base_model: str  # 基于哪个基础模型
    modifications: Dict  # 修改内容
    created_at: str = ""
    use_count: int = 0
    performance_notes: List[str] = field(default_factory=list)
    
    def to_dict(self) -> Dict:
        return {
            "model_id": self.model_id,
            "name": self.name,
            "base_model": self.base_model,
            "modifications": self.modifications,
            "created_at": self.created_at or datetime.now().isoformat(),
            "use_count": self.use_count,
            "performance_notes": self.performance_notes
        }


class TemplateLibrary:
    """思维模型模板库"""
    
    def __init__(self, library_dir: Optional[str] = None):
        """初始化模板库"""
        if library_dir is None:
            self.library_dir = Path.home() / ".claude" / "thinking_models" / "templates"
        else:
            self.library_dir = Path(library_dir)
        
        self.library_dir.mkdir(parents=True, exist_ok=True)
        self.templates_file = self.library_dir / "templates.json"
        
        # 加载或创建模板库
        self.templates = self._load_or_create_templates()
    
    def _load_or_create_templates(self) -> Dict:
        """加载或创建默认模板"""
        if self.templates_file.exists():
            with open(self.templates_file, 'r', encoding='utf-8') as f:
                return json.load(f)
        
        # 默认模板
        default_templates = {
            "version": "1.0",
            "updated_at": datetime.now().isoformat(),
            "templates": [
                {
                    "template_id": "quick_decision",
                    "name": "快速决策模板",
                    "description": "用于需要快速做出决策的场景，简化流程",
                    "category": "decision",
                    "stages": [
                        {"name": "问题定义", "order": 1, "required": True},
                        {"name": "选项列举", "order": 2, "required": True},
                        {"name": "利弊分析", "order": 3, "required": True},
                        {"name": "最终决策", "order": 4, "required": True}
                    ],
                    "conditions": ["时间紧迫", "信息有限", "需要快速响应"],
                    "examples": ["快速决定是否采纳建议", "快速选择方案"],
                    "tags": ["快速", "决策", "简化"]
                },
                {
                    "template_id": "deep_analysis",
                    "name": "深度分析模板",
                    "description": "用于需要全面深入分析的场景",
                    "category": "analysis",
                    "stages": [
                        {"name": "问题分解", "order": 1, "required": True},
                        {"name": "数据收集", "order": 2, "required": True},
                        {"name": "多角度分析", "order": 3, "required": True},
                        {"name": "假设验证", "order": 4, "required": True},
                        {"name": "综合结论", "order": 5, "required": True},
                        {"name": "建议制定", "order": 6, "required": False}
                    ],
                    "conditions": ["复杂问题", "需要全面考虑", "时间充裕"],
                    "examples": ["深度分析系统架构", "全面评估方案"],
                    "tags": ["深度", "分析", "全面"]
                },
                {
                    "template_id": "creative_solving",
                    "name": "创意解决问题模板",
                    "description": "用于需要创新思维的问题解决",
                    "category": "solving",
                    "stages": [
                        {"name": "问题重构", "order": 1, "required": True},
                        {"name": "头脑风暴", "order": 2, "required": True},
                        {"name": "方案筛选", "order": 3, "required": True},
                        {"name": "可行性分析", "order": 4, "required": True},
                        {"name": "实施计划", "order": 5, "required": False}
                    ],
                    "conditions": ["常规方法无效", "需要创新", "开放性问题"],
                    "examples": ["创新解决方案", "突破性想法"],
                    "tags": ["创意", "创新", "解决问题"]
                }
            ]
        }
        
        self._save_templates(default_templates)
        return default_templates
    
    def _save_templates(self, templates: Dict):
        """保存模板库"""
        templates["updated_at"] = datetime.now().isoformat()
        with open(self.templates_file, 'w', encoding='utf-8') as f:
            json.dump(templates, f, ensure_ascii=False, indent=2)
    
    def get_template(self, template_id: str) -> Optional[Dict]:
        """获取模板"""
        for template in self.templates.get("templates", []):
            if template.get("template_id") == template_id:
                return template
        return None
    
    def search_templates(self, 
                         query: str = "", 
                         category: Optional[str] = None,
                         tags: Optional[List[str]] = None,
                         limit: int = 10) -> List[Dict]:
        """
        搜索模板
        
        Args:
            query: 搜索关键词
            category: 分类过滤
            tags: 标签过滤
            limit: 返回数量限制
            
        Returns:
            匹配的模板列表
        """
        results = []
        query_lower = query.lower()
        
        for template in self.templates.get("templates", []):
            # 关键词匹配
            if query_lower:
                if not any(query_lower in str(v).lower() 
                          for v in template.values() if isinstance(v, str)):
                    continue
            
            # 分类过滤
            if category and template.get("category") != category:
                continue
            
            # 标签过滤
            if tags:
                template_tags = template.get("tags", [])
                if not any(tag in template_tags for tag in tags):
                    continue
            
            results.append(template)
        
        return results[:limit]
    
    def add_template(self, template: Dict) -> bool:
        """添加新模板"""
        try:
            template["template_id"] = template.get("template_id") or f"custom_{datetime.now().strftime('%Y%m%d%H%M%S')}"
            template["created_at"] = datetime.now().isoformat()
            template["use_count"] = 0
            template["rating"] = 0.0
            
            self.templates["templates"].append(template)
            self._save_templates(self.templates)
            return True
        except Exception:
            return False
    
    def update_template(self, template_id: str, updates: Dict) -> bool:
        """更新模板"""
        for i, template in enumerate(self.templates.get("templates", [])):
            if template.get("template_id") == template_id:
                template.update(updates)
                self._save_templates(self.templates)
                return True
        return False
    
    def delete_template(self, template_id: str) -> bool:
        """删除模板"""
        templates = self.templates.get("templates", [])
        for i, template in enumerate(templates):
            if template.get("template_id") == template_id:
                templates.pop(i)
                self.templates["templates"] = templates
                self._save_templates(self.templates)
                return True
        return False
    
    def get_categories(self) -> List[str]:
        """获取所有分类"""
        categories = set()
        for template in self.templates.get("templates", []):
            if template.get("category"):
                categories.add(template["category"])
        return list(categories)
    
    def increment_use_count(self, template_id: str):
        """增加使用计数"""
        for template in self.templates.get("templates", []):
            if template.get("template_id") == template_id:
                template["use_count"] = template.get("use_count", 0) + 1
                self._save_templates(self.templates)
                break
    
    def get_popular_templates(self, limit: int = 5) -> List[Dict]:
        """获取最受欢迎的模板"""
        templates = self.templates.get("templates", [])
        return sorted(templates, key=lambda x: x.get("use_count", 0), reverse=True)[:limit]


class TriggerManager:
    """触发器管理器"""
    
    def __init__(self, rules_dir: Optional[str] = None):
        """初始化触发器管理器"""
        if rules_dir is None:
            self.rules_dir = Path.home() / ".claude" / "thinking_models" / "triggers"
        else:
            self.rules_dir = Path(rules_dir)
        
        self.rules_dir.mkdir(parents=True, exist_ok=True)
        self.rules_file = self.rules_dir / "rules.json"
        
        # 加载或创建默认规则
        self.rules = self._load_or_create_rules()
    
    def _load_or_create_rules(self) -> Dict:
        """加载或创建默认规则"""
        if self.rules_file.exists():
            with open(self.rules_file, 'r', encoding='utf-8') as f:
                return json.load(f)
        
        # 默认规则
        default_rules = {
            "version": "1.0",
            "updated_at": datetime.now().isoformat(),
            "rules": [
                {
                    "rule_id": "skill_creation_trigger",
                    "name": "技能创建触发器",
                    "trigger_type": "keyword",
                    "trigger_value": "写skill|创建技能|实现功能",
                    "mode": "auto",
                    "target_model": "research_mode",
                    "priority": 1,
                    "enabled": True,
                    "cooldown_seconds": 60,
                    "conditions": [],
                    "actions": ["启动研究型思维模式", "准备技能创建模板"]
                },
                {
                    "rule_id": "system_repair_trigger",
                    "name": "系统修复触发器",
                    "trigger_type": "keyword",
                    "trigger_value": "修复|报错|错误|问题|启动失败",
                    "mode": "auto",
                    "target_model": "diagnostic_mode",
                    "priority": 1,
                    "enabled": True,
                    "cooldown_seconds": 30,
                    "conditions": [],
                    "actions": ["启动诊断型思维模式", "准备修复工具"]
                }
            ]
        }
        
        self._save_rules(default_rules)
        return default_rules
    
    def _save_rules(self, rules: Dict):
        """保存规则"""
        rules["updated_at"] = datetime.now().isoformat()
        with open(self.rules_file, 'w', encoding='utf-8') as f:
            json.dump(rules, f, ensure_ascii=False, indent=2)
    
    def check_triggers(self, 
                       input_text: str, 
                       context: Optional[Dict] = None) -> List[Dict]:
        """
        检查输入是否触发规则
        
        Args:
            input_text: 输入文本
            context: 上下文信息
            
        Returns:
            匹配的触发规则列表
        """
        matches = []
        now = datetime.now().isoformat()
        
        for rule in self.rules.get("rules", []):
            if not rule.get("enabled", True):
                continue
            
            # 检查冷却时间
            last_triggered = rule.get("last_triggered")
            if last_triggered:
                last_time = datetime.fromisoformat(last_triggered)
                cooldown = rule.get("cooldown_seconds", 300)
                if (datetime.now() - last_time).total_seconds() < cooldown:
                    continue
            
            # 检查触发条件
            trigger_type = rule.get("trigger_type")
            trigger_value = rule.get("trigger_value")
            
            if trigger_type == "keyword":
                if trigger_value and any(kw in input_text for kw in trigger_value.split("|")):
                    matches.append(rule)
            
            elif trigger_type == "pattern":
                try:
                    if re.search(trigger_value, input_text):
                        matches.append(rule)
                except Exception:
                    continue
        
        # 按优先级排序
        matches.sort(key=lambda x: x.get("priority", 100))
        
        # 更新最后触发时间
        for rule in matches:
            rule["last_triggered"] = now
        
        if matches:
            self._save_rules(self.rules)
        
        return matches
    
    def add_rule(self, rule: Dict) -> bool:
        """添加规则"""
        try:
            rule["rule_id"] = rule.get("rule_id") or f"rule_{datetime.now().strftime('%Y%m%d%H%M%S')}"
            self.rules["rules"].append(rule)
            self._save_rules(self.rules)
            return True
        except Exception:
            return False
    
    def update_rule(self, rule_id: str, updates: Dict) -> bool:
        """更新规则"""
        for i, rule in enumerate(self.rules.get("rules", [])):
            if rule.get("rule_id") == rule_id:
                rule.update(updates)
                self._save_rules(self.rules)
                return True
        return False
    
    def delete_rule(self, rule_id: str) -> bool:
        """删除规则"""
        rules = self.rules.get("rules", [])
        for i, rule in enumerate(rules):
            if rule.get("rule_id") == rule_id:
                rules.pop(i)
                self.rules["rules"] = rules
                self._save_rules(self.rules)
                return True
        return False
    
    def get_enabled_rules(self) -> List[Dict]:
        """获取所有启用的规则"""
        return [r for r in self.rules.get("rules", []) if r.get("enabled", True)]
    
    def disable_rule(self, rule_id: str) -> bool:
        """禁用规则"""
        return self.update_rule(rule_id, {"enabled": False})
    
    def enable_rule(self, rule_id: str) -> bool:
        """启用规则"""
        return self.update_rule(rule_id, {"enabled": True})


class CustomModelManager:
    """自定义模型管理器"""
    
    def __init__(self, models_dir: Optional[str] = None):
        """初始化自定义模型管理器"""
        if models_dir is None:
            self.models_dir = Path.home() / ".claude" / "thinking_models" / "custom_models"
        else:
            self.models_dir = Path(models_dir)
        
        self.models_dir.mkdir(parents=True, exist_ok=True)
        self.models_file = self.models_dir / "models.json"
        
        # 加载或创建模型配置
        self.models = self._load_or_create_models()
    
    def _load_or_create_models(self) -> Dict:
        """加载或创建模型配置"""
        if self.models_file.exists():
            with open(self.models_file, 'r', encoding='utf-8') as f:
                return json.load(f)
        
        # 默认配置
        default_models = {
            "version": "1.0",
            "updated_at": datetime.now().isoformat(),
            "models": []
        }
        
        self._save_models(default_models)
        return default_models
    
    def _save_models(self, models: Dict):
        """保存模型配置"""
        models["updated_at"] = datetime.now().isoformat()
        with open(self.models_file, 'w', encoding='utf-8') as f:
            json.dump(models, f, ensure_ascii=False, indent=2)
    
    def create_model(self, 
                     name: str, 
                     base_model: str,
                     modifications: Dict) -> Optional[str]:
        """
        创建自定义模型
        
        Args:
            name: 模型名称
            base_model: 基础模型
            modifications: 修改内容
            
        Returns:
            模型ID或None
        """
        try:
            model_id = f"custom_{hashlib.md5((name + datetime.now().isoformat()).encode()).hexdigest()[:8]}"
            
            model = {
                "model_id": model_id,
                "name": name,
                "base_model": base_model,
                "modifications": modifications,
                "created_at": datetime.now().isoformat(),
                "use_count": 0,
                "performance_notes": []
            }
            
            self.models["models"].append(model)
            self._save_models(self.models)
            
            return model_id
        except Exception:
            return None
    
    def get_model(self, model_id: str) -> Optional[Dict]:
        """获取自定义模型"""
        for model in self.models.get("models", []):
            if model.get("model_id") == model_id:
                return model
        return None
    
    def get_models_by_base(self, base_model: str) -> List[Dict]:
        """获取基于特定基础模型的所有自定义模型"""
        return [m for m in self.models.get("models", []) if m.get("base_model") == base_model]
    
    def update_model(self, model_id: str, updates: Dict) -> bool:
        """更新自定义模型"""
        for i, model in enumerate(self.models.get("models", [])):
            if model.get("model_id") == model_id:
                model.update(updates)
                self._save_models(self.models)
                return True
        return False
    
    def delete_model(self, model_id: str) -> bool:
        """删除自定义模型"""
        models = self.models.get("models", [])
        for i, model in enumerate(models):
            if model.get("model_id") == model_id:
                models.pop(i)
                self.models["models"] = models
                self._save_models(self.models)
                return True
        return False
    
    def increment_use_count(self, model_id: str):
        """增加使用计数"""
        for model in self.models.get("models", []):
            if model.get("model_id") == model_id:
                model["use_count"] = model.get("use_count", 0) + 1
                self._save_models(self.models)
                break
    
    def add_performance_note(self, model_id: str, note: str):
        """添加性能备注"""
        for model in self.models.get("models", []):
            if model.get("model_id") == model_id:
                if "performance_notes" not in model:
                    model["performance_notes"] = []
                model["performance_notes"].append({
                    "timestamp": datetime.now().isoformat(),
                    "note": note
                })
                self._save_models(self.models)
                break


def get_template_library() -> TemplateLibrary:
    """获取模板库实例"""
    return TemplateLibrary()


def get_trigger_manager() -> TriggerManager:
    """获取触发器管理器实例"""
    return TriggerManager()


def get_custom_model_manager() -> CustomModelManager:
    """获取自定义模型管理器实例"""
    return CustomModelManager()
