"""
行为树装饰节点
包括重复节点、逆变节点、成功节点等
提供多种装饰逻辑实现
"""

import time
import random
from typing import Optional, Callable, Any
from ..core.behavior_tree import DecoratorNode, NodeStatus, BTNodeConfig

class RepeaterNode(DecoratorNode):
    """
    重复节点
    重复执行子节点指定次数
    支持条件检查和间隔时间
    """
    
    def __init__(self, child: Optional['BTNode'] = None, 
                 config: BTNodeConfig = None,
                 count: int = -1,  # 重复次数，-1表示无限重复
                 interval: float = 0.0,  # 重复间隔时间（秒）
                 condition: Optional[Callable[[], bool]] = None):  # 重复条件
        if config is None:
            config = BTNodeConfig(name="Repeater")
        super().__init__(child, config)
        self.count = count
        self.interval = interval
        self.condition = condition
        self.current_count = 0  # 当前已重复次数
        self.last_execution_time = 0.0  # 上次执行时间
        
    def _decorate(self, child_status: NodeStatus) -> NodeStatus:
        """装饰子节点的执行结果"""
        current_time = time.time()
        
        # 检查间隔时间
        if self.interval > 0 and self.current_count > 0:
            time_since_last = current_time - self.last_execution_time
            if time_since_last < self.interval:
                return NodeStatus.RUNNING
                
        # 检查重复条件
        if self.condition and not self.condition():
            # 重置计数器
            self.current_count = 0
            self.last_execution_time = 0.0
            return child_status
            
        if child_status == NodeStatus.RUNNING:
            return NodeStatus.RUNNING
            
        # 子节点执行完成（SUCCESS或FAILURE）
        self.current_count += 1
        self.last_execution_time = current_time
        
        # 检查是否达到重复次数
        if self.count != -1 and self.current_count >= self.count:
            # 重置计数器
            self.current_count = 0
            self.last_execution_time = 0.0
            return child_status
        else:
            # 继续重复执行
            return NodeStatus.RUNNING
            
    def reset(self) -> None:
        """重置节点状态"""
        super().reset()
        self.current_count = 0
        self.last_execution_time = 0.0

class InverterNode(DecoratorNode):
    """
    逆变节点
    反转子节点的执行结果
    SUCCESS变为FAILURE，FAILURE变为SUCCESS
    RUNNING保持不变
    支持条件反转和延迟反转
    """
    
    def __init__(self, child: Optional['BTNode'] = None,
                 config: BTNodeConfig = None,
                 delay: float = 0.0,  # 延迟反转时间
                 condition: Optional[Callable[[], bool]] = None):  # 反转条件
        if config is None:
            config = BTNodeConfig(name="Inverter")
        super().__init__(child, config)
        self.delay = delay
        self.condition = condition
        self.inversion_start_time = 0.0  # 反转开始时间
        
    def _decorate(self, child_status: NodeStatus) -> NodeStatus:
        """装饰子节点的执行结果"""
        # 检查反转条件
        should_invert = True
        if self.condition:
            should_invert = self.condition()
            
        if not should_invert:
            return child_status
            
        # 检查延迟反转
        if self.delay > 0 and child_status != NodeStatus.RUNNING:
            current_time = time.time()
            if self.inversion_start_time == 0.0:
                self.inversion_start_time = current_time
                return child_status  # 暂时不反转
                
            if current_time - self.inversion_start_time < self.delay:
                return child_status  # 延迟未到，暂不反转
                
        # 执行反转
        if child_status == NodeStatus.SUCCESS:
            return NodeStatus.FAILURE
        elif child_status == NodeStatus.FAILURE:
            return NodeStatus.SUCCESS
        else:  # RUNNING
            return NodeStatus.RUNNING
            
    def reset(self) -> None:
        """重置节点状态"""
        super().reset()
        self.inversion_start_time = 0.0

class SucceederNode(DecoratorNode):
    """
    成功节点
    总是返回SUCCESS，无论子节点返回什么
    支持条件成功和延迟成功
    """
    
    def __init__(self, child: Optional['BTNode'] = None,
                 config: BTNodeConfig = None,
                 delay: float = 0.0,  # 延迟成功时间
                 condition: Optional[Callable[[], bool]] = None):  # 成功条件
        if config is None:
            config = BTNodeConfig(name="Succeeder")
        super().__init__(child, config)
        self.delay = delay
        self.condition = condition
        self.success_start_time = 0.0  # 成功开始时间
        
    def _decorate(self, child_status: NodeStatus) -> NodeStatus:
        """装饰子节点的执行结果"""
        # 检查成功条件
        should_succeed = True
        if self.condition:
            should_succeed = self.condition()
            
        if not should_succeed:
            return child_status
            
        # 检查延迟成功
        if self.delay > 0 and child_status != NodeStatus.RUNNING:
            current_time = time.time()
            if self.success_start_time == 0.0:
                self.success_start_time = current_time
                return child_status  # 暂时不成功
                
            if current_time - self.success_start_time < self.delay:
                return child_status  # 延迟未到，暂不成功
                
        # 总是返回成功
        if child_status == NodeStatus.RUNNING:
            return NodeStatus.RUNNING
        else:  # SUCCESS或FAILURE
            return NodeStatus.SUCCESS
            
    def reset(self) -> None:
        """重置节点状态"""
        super().reset()
        self.success_start_time = 0.0

class FailureNode(DecoratorNode):
    """
    失败节点
    总是返回FAILURE，无论子节点返回什么
    支持条件失败和延迟失败
    """
    
    def __init__(self, child: Optional['BTNode'] = None,
                 config: BTNodeConfig = None,
                 delay: float = 0.0,  # 延迟失败时间
                 condition: Optional[Callable[[], bool]] = None):  # 失败条件
        if config is None:
            config = BTNodeConfig(name="Failure")
        super().__init__(child, config)
        self.delay = delay
        self.condition = condition
        self.failure_start_time = 0.0  # 失败开始时间
        
    def _decorate(self, child_status: NodeStatus) -> NodeStatus:
        """装饰子节点的执行结果"""
        # 检查失败条件
        should_fail = True
        if self.condition:
            should_fail = self.condition()
            
        if not should_fail:
            return child_status
            
        # 检查延迟失败
        if self.delay > 0 and child_status != NodeStatus.RUNNING:
            current_time = time.time()
            if self.failure_start_time == 0.0:
                self.failure_start_time = current_time
                return child_status  # 暂时不失败
                
            if current_time - self.failure_start_time < self.delay:
                return child_status  # 延迟未到，暂不失败
                
        # 总是返回失败
        if child_status == NodeStatus.RUNNING:
            return NodeStatus.RUNNING
        else:  # SUCCESS或FAILURE
            return NodeStatus.FAILURE
            
    def reset(self) -> None:
        """重置节点状态"""
        super().reset()
        self.failure_start_time = 0.0

class TimerNode(DecoratorNode):
    """
    计时器节点
    限制子节点的执行时间
    """
    
    def __init__(self, child: Optional['BTNode'] = None,
                 config: BTNodeConfig = None,
                 timeout: float = 5.0):  # 超时时间（秒）
        if config is None:
            config = BTNodeConfig(name="Timer")
        super().__init__(child, config)
        self.timeout = timeout
        self.start_time = 0.0  # 开始时间
        
    def _decorate(self, child_status: NodeStatus) -> NodeStatus:
        """装饰子节点的执行结果"""
        current_time = time.time()
        
        # 记录开始时间
        if self.start_time == 0.0:
            self.start_time = current_time
            
        # 检查是否超时
        if current_time - self.start_time >= self.timeout:
            # 超时，强制返回失败
            self.start_time = 0.0
            if hasattr(self.child, 'on_abort'):
                self.child.on_abort(None)  # 中断子节点
            return NodeStatus.FAILURE
            
        # 如果子节点完成，重置计时器
        if child_status != NodeStatus.RUNNING:
            self.start_time = 0.0
            
        return child_status
        
    def reset(self) -> None:
        """重置节点状态"""
        super().reset()
        self.start_time = 0.0

class CooldownNode(DecoratorNode):
    """
    冷却节点
    在子节点执行后添加冷却时间
    """
    
    def __init__(self, child: Optional['BTNode'] = None,
                 config: BTNodeConfig = None,
                 cooldown_time: float = 1.0):  # 冷却时间（秒）
        if config is None:
            config = BTNodeConfig(name="Cooldown")
        super().__init__(child, config)
        self.cooldown_time = cooldown_time
        self.last_execution_time = 0.0  # 上次执行完成时间
        self.is_on_cooldown = False  # 是否在冷却中
        
    def _decorate(self, child_status: NodeStatus) -> NodeStatus:
        """装饰子节点的执行结果"""
        current_time = time.time()
        
        # 检查是否在冷却中
        if self.is_on_cooldown:
            if current_time - self.last_execution_time >= self.cooldown_time:
                # 冷却结束
                self.is_on_cooldown = False
                self.last_execution_time = 0.0
                return NodeStatus.FAILURE  # 冷却结束后返回失败，等待下次执行
            else:
                # 仍在冷却中
                return NodeStatus.FAILURE
                
        # 子节点正在运行
        if child_status == NodeStatus.RUNNING:
            return NodeStatus.RUNNING
            
        # 子节点完成，开始冷却
        self.is_on_cooldown = True
        self.last_execution_time = current_time
        return child_status
        
    def reset(self) -> None:
        """重置节点状态"""
        super().reset()
        self.last_execution_time = 0.0
        self.is_on_cooldown = False

class RandomizerNode(DecoratorNode):
    """
    随机化节点
    随机决定是否执行子节点
    """
    
    def __init__(self, child: Optional['BTNode'] = None,
                 config: BTNodeConfig = None,
                 success_rate: float = 0.5):  # 成功率（0.0-1.0）
        if config is None:
            config = BTNodeConfig(name="Randomizer")
        super().__init__(child, config)
        self.success_rate = max(0.0, min(1.0, success_rate))  # 限制在0-1之间
        self.should_execute = False  # 是否应该执行子节点
        self.has_decided = False  # 是否已经做出决定
        
    def _decorate(self, child_status: NodeStatus) -> NodeStatus:
        """装饰子节点的执行结果"""
        # 如果还没有做出决定，随机决定是否执行
        if not self.has_decided:
            self.should_execute = random.random() < self.success_rate
            self.has_decided = True
            
        # 如果决定不执行，直接返回成功
        if not self.should_execute:
            return NodeStatus.SUCCESS
            
        # 执行子节点
        return child_status
        
    def reset(self) -> None:
        """重置节点状态"""
        super().reset()
        self.should_execute = False
        self.has_decided = False