"""
条件分支节点
"""
import logging
import operator
from typing import Any, Dict

from ..base import BaseNode, NodeContext, NodeResult
from ..registry import NodeRegistry

logger = logging.getLogger(__name__)


@NodeRegistry.register
class ConditionNode(BaseNode):
    """
    条件分支节点
    
    根据条件判断选择不同的分支
    """
    
    node_type = 'condition'
    node_name = '条件分支'
    node_category = 'logic'
    node_icon = 'git-branch'
    node_description = '根据条件判断选择不同的执行分支'
    
    supports_branches = True
    
    inputs = [
        {
            'name': 'value',
            'type': 'any',
            'description': '要判断的值',
        },
    ]
    
    outputs = [
        {
            'name': 'branch',
            'type': 'string',
            'description': '选中的分支',
        },
    ]
    
    # 支持的操作符
    OPERATORS = {
        'eq': operator.eq,          # 等于
        'ne': operator.ne,          # 不等于
        'gt': operator.gt,          # 大于
        'gte': operator.ge,         # 大于等于
        'lt': operator.lt,          # 小于
        'lte': operator.le,         # 小于等于
        'contains': lambda a, b: b in str(a),  # 包含
        'not_contains': lambda a, b: b not in str(a),  # 不包含
        'starts_with': lambda a, b: str(a).startswith(str(b)),  # 开头是
        'ends_with': lambda a, b: str(a).endswith(str(b)),  # 结尾是
        'is_empty': lambda a, _: not a,  # 为空
        'is_not_empty': lambda a, _: bool(a),  # 不为空
    }
    
    def execute(self, context: NodeContext) -> NodeResult:
        """执行条件判断"""
        try:
            branches = self.config.get('branches', [])
            
            # 遍历所有 IF 分支
            for branch in branches:
                branch_id = branch.get('id')
                conditions = branch.get('conditions', [])
                
                # 评估该分支的所有条件
                if self._evaluate_branch(conditions, context):
                    return NodeResult(
                        success=True,
                        output=branch_id,
                        next_node_id=branch_id,
                        metadata={'matched_branch': branch_id},
                    )
            
            # 没有匹配的条件，走 ELSE 分支
            return NodeResult(
                success=True,
                output='else',
                next_node_id='else',
                metadata={'matched_branch': 'else'},
            )
            
        except Exception as e:
            logger.exception(f'条件节点执行失败: {e}')
            return NodeResult(
                success=False,
                error=str(e),
            )
    
    def _evaluate_branch(self, conditions: list, context: NodeContext) -> bool:
        """评估分支的一组条件 (AND 关系)"""
        if not conditions:
            return True # 无条件默认为真
            
        for condition in conditions:
            if not self._evaluate_condition(condition, context):
                return False
        return True

    def _resolve_variable(self, variable: str, context: NodeContext) -> Any:
        """
        解析变量引用
        
        支持格式：
        - {{variable_name}} - 直接变量引用
        - {{NodeID.key}} - 节点输出引用
        - 普通字符串 - 直接返回
        """
        if not isinstance(variable, str):
            return variable
            
        # 检查是否是 {{...}} 格式
        if not (variable.startswith('{{') and variable.endswith('}}')):
            return variable
            
        content = variable[2:-2].strip()
        
        logger.info(f'解析变量: {variable}, content={content}, 上下文变量keys={list(context.variables.keys())}')
        
        # 尝试解析 NodeID.key 格式
        if '.' in content:
            parts = content.split('.', 1)
            node_id = parts[0]
            var_key = parts[1]
            
            logger.info(f'解析节点变量: node_id={node_id}, var_key={var_key}')
            
            # 先尝试从节点输出命名空间获取
            node_outputs = context.get_variable(f'_node_{node_id}')
            logger.info(f'节点输出 _node_{node_id}: {node_outputs}')
            if isinstance(node_outputs, dict) and var_key in node_outputs:
                return node_outputs[var_key]
            
            # 回退：尝试直接从变量获取
            node_data = context.get_variable(node_id)
            logger.info(f'直接变量 {node_id}: {node_data}')
            if isinstance(node_data, dict) and var_key in node_data:
                return node_data[var_key]
        
        # 直接变量引用
        value = context.get_variable(content)
        if value is not None:
            return value
            
        return None

    def _evaluate_condition(self, condition: Dict, context: NodeContext) -> bool:
        """评估单个条件"""
        variable = condition.get('variable', '')
        op_name = condition.get('operator', 'equals')
        value = condition.get('value', '')
        
        # 解析变量和值
        left_val = self._resolve_variable(variable, context)
        right_val = self._resolve_variable(value, context)
        
        logger.info(f'条件评估: variable={variable}, left_val={left_val}, op={op_name}, right_val={right_val}')
        
        # 映射操作符
        op_mapping = {
            'equals': 'eq',
            'not_equals': 'ne',
        }
        op_key = op_mapping.get(op_name, op_name)
        op_func = self.OPERATORS.get(op_key, operator.eq)
        
        try:
            # 特殊处理空值判断，不需要右值
            if op_key in ['is_empty', 'is_not_empty']:
                return op_func(left_val, None)
                
            # 布尔值比较：将字符串 "true"/"false" 转换为布尔值
            if isinstance(left_val, bool) and isinstance(right_val, str):
                if right_val.lower() in ['true', '1', 'yes']:
                    right_val = True
                elif right_val.lower() in ['false', '0', 'no']:
                    right_val = False
            elif isinstance(right_val, bool) and isinstance(left_val, str):
                if left_val.lower() in ['true', '1', 'yes']:
                    left_val = True
                elif left_val.lower() in ['false', '0', 'no']:
                    left_val = False
            
            # 尝试转换类型以进行比较 (如数字)
            if isinstance(left_val, (int, float)) and isinstance(right_val, str):
                try:
                    if '.' in right_val:
                        right_val = float(right_val)
                    else:
                        right_val = int(right_val)
                except:
                    pass
            
            # 字符串比较忽略类型差异
            if op_key in ['contains', 'not_contains', 'starts_with', 'ends_with']:
                return op_func(str(left_val), str(right_val))

            return op_func(left_val, right_val)
        except Exception as e:
            logger.warning(f'条件评估失败: {e}')
            return False
    
    @classmethod
    def get_config_schema(cls) -> Dict[str, Any]:
        """获取配置 Schema"""
        return {
            'type': 'object',
            'properties': {
                'conditions': {
                    'type': 'array',
                    'title': '条件列表',
                    'items': {
                        'type': 'object',
                        'properties': {
                            'variable': {
                                'type': 'string',
                                'title': '变量名',
                            },
                            'operator': {
                                'type': 'string',
                                'title': '操作符',
                                'enum': list(cls.OPERATORS.keys()),
                                'default': 'eq',
                            },
                            'value': {
                                'type': 'string',
                                'title': '比较值',
                            },
                            'branch_id': {
                                'type': 'string',
                                'title': '分支 ID',
                            },
                        },
                    },
                },
                'default_branch': {
                    'type': 'string',
                    'title': '默认分支',
                    'description': '没有条件匹配时执行的分支',
                },
            },
        }
