#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Skill基类
所有Skill都应该继承此类
"""

from abc import ABC, abstractmethod
from typing import Dict, Any, List, Optional, Tuple


class BaseSkill(ABC):
    """Skill基类"""
    
    def __init__(self, toolkit_instance=None):
        """
        初始化Skill
        
        Args:
            toolkit_instance: NetworkToolkit实例,用于访问GUI组件
        """
        self.toolkit = toolkit_instance
        self._metadata = self.get_metadata()
    
    @abstractmethod
    def get_metadata(self) -> Dict[str, Any]:
        """
        返回Skill元数据
        
        Returns:
            元数据字典,包含以下字段:
            {
                "name": str,  # Skill名称(唯一标识,小写英文)
                "display_name": str,  # 显示名称(中文)
                "description": str,  # 功能描述
                "category": str,  # 分类(network/system/info/advanced)
                "keywords": List[str],  # 关键词列表,用于匹配用户查询
                "parameters": List[Dict],  # 参数列表
                "examples": List[str],  # 使用示例
                "requires_admin": bool,  # 是否需要管理员权限
                "requires_ui": bool  # 是否需要UI交互
            }
            
        参数格式示例:
            {
                "name": "host",
                "type": "string",  # string/int/float/bool
                "required": True,
                "default": None,  # 可选,默认值
                "description": "目标主机IP或域名"
            }
        """
        pass
    
    @abstractmethod
    def execute(self, **kwargs) -> str:
        """
        执行Skill
        
        Args:
            **kwargs: 参数字典
            
        Returns:
            执行结果字符串
        """
        pass
    
    def validate_params(self, params: Dict[str, Any]) -> Tuple[bool, str]:
        """
        验证参数
        
        Args:
            params: 参数字典
            
        Returns:
            (是否有效, 错误信息)
        """
        metadata = self._metadata
        parameters = metadata.get("parameters", [])
        
        # 过滤掉内部私有参数(下划线开头),不做校验
        params = {k: v for k, v in params.items() if not k.startswith('_')}
        
        # 检查必需参数
        for param in parameters:
            param_name = param["name"]
            if param.get("required", False):
                if param_name not in params or params[param_name] is None or params[param_name] == "":
                    return False, f"缺少必需参数: {param_name} ({param.get('description', '')})"
        
        # 类型验证(简单版本)
        for param in parameters:
            param_name = param["name"]
            param_type = param.get("type", "string")
            
            if param_name in params and params[param_name] is not None:
                value = params[param_name]
                
                if param_type == "int":
                    try:
                        int(value)
                    except (ValueError, TypeError):
                        return False, f"参数{param_name}应为整数"
                elif param_type == "float":
                    try:
                        float(value)
                    except (ValueError, TypeError):
                        return False, f"参数{param_name}应为浮点数"
                elif param_type == "bool":
                    if not isinstance(value, bool):
                        return False, f"参数{param_name}应为布尔值"
        
        return True, ""
    
    def match_query(self, query: str) -> float:
        """
        判断查询是否匹配此Skill
        
        Args:
            query: 用户查询字符串
            
        Returns:
            匹配度(0-1),>0.3才认为匹配
        """
        query_lower = query.lower()
        keywords = self._metadata.get("keywords", [])
        
        # 精确匹配Skill名称
        if self._metadata["name"] in query_lower:
            return 1.0
        
        # 关键词匹配
        match_count = 0
        for keyword in keywords:
            if keyword.lower() in query_lower:
                match_count += 1
        
        if match_count > 0:
            # 匹配度 = 0.5 + (匹配关键词比例 * 0.5)
            return 0.5 + (match_count / len(keywords)) * 0.5
        
        return 0.0
    
    def get_parameter_info(self, param_name: str) -> Optional[Dict[str, Any]]:
        """获取指定参数的信息"""
        parameters = self._metadata.get("parameters", [])
        for param in parameters:
            if param["name"] == param_name:
                return param
        return None
    
    def get_all_parameters(self) -> List[str]:
        """获取所有参数名称"""
        parameters = self._metadata.get("parameters", [])
        return [param["name"] for param in parameters]
    
    def get_required_parameters(self) -> List[str]:
        """获取所有必需参数名称"""
        parameters = self._metadata.get("parameters", [])
        return [param["name"] for param in parameters if param.get("required", False)]
    
    def __str__(self):
        """字符串表示"""
        return f"Skill({self._metadata['name']})"
    
    def __repr__(self):
        """开发者表示"""
        return f"<Skill: {self._metadata['name']} ({self._metadata['display_name']})>"
