"""
状态机核心组件
定义状态机的基本结构和执行逻辑
包含完整的状态管理、转换和上下文系统
"""

import time
import threading
from abc import ABC, abstractmethod
from typing import Dict, List, Optional, Any, Callable, Union
from enum import Enum
from dataclasses import dataclass, field
from datetime import datetime

class StateType(Enum):
    """状态类型枚举"""
    IDLE = "idle"
    ACTIVE = "active"
    SUSPENDED = "suspended"
    TERMINATED = "terminated"

@dataclass
class StateContext:
    """
    状态上下文数据类
    存储状态相关的数据和信息
    """
    data: Dict[str, Any] = field(default_factory=dict)
    state_machine: Optional['StateMachine'] = None
    timestamp: datetime = field(default_factory=datetime.now)
    execution_count: int = 0
    
    def get(self, key: str, default: Any = None) -> Any:
        """获取数据"""
        return self.data.get(key, default)
        
    def set(self, key: str, value: Any) -> None:
        """设置数据"""
        self.data[key] = value
        
    def has(self, key: str) -> bool:
        """检查是否存在键"""
        return key in self.data
        
    def remove(self, key: str) -> bool:
        """移除数据"""
        if key in self.data:
            del self.data[key]
            return True
        return False
        
    def clear(self) -> None:
        """清空数据"""
        self.data.clear()
        
    def update(self, data_dict: Dict[str, Any]) -> None:
        """批量更新数据"""
        self.data.update(data_dict)
        
    def copy(self) -> 'StateContext':
        """创建上下文副本"""
        return StateContext(
            data=self.data.copy(),
            state_machine=self.state_machine,
            timestamp=self.timestamp,
            execution_count=self.execution_count
        )

class StateTransition:
    """
    状态转换类
    定义状态之间的转换条件和动作
    """
    
    def __init__(self, from_state: str, to_state: str, 
                 condition: Optional[Callable[[StateContext], bool]] = None,
                 action: Optional[Callable[[StateContext], None]] = None,
                 priority: int = 0):
        self.from_state = from_state
        self.to_state = to_state
        self.condition = condition
        self.action = action
        self.priority = priority  # 优先级，数字越大优先级越高
        self.transition_count = 0  # 转换次数
        
    def can_transition(self, context: StateContext) -> bool:
        """检查是否可以转换"""
        if self.condition:
            try:
                return self.condition(context)
            except Exception as e:
                print(f"转换条件检查出错: {e}")
                return False
        return True
        
    def execute_action(self, context: StateContext) -> None:
        """执行转换动作"""
        if self.action:
            try:
                self.action(context)
            except Exception as e:
                print(f"转换动作执行出错: {e}")
                
    def increment_count(self) -> int:
        """增加转换计数并返回新计数"""
        self.transition_count += 1
        return self.transition_count

class State(ABC):
    """
    状态基类
    """
    
    def __init__(self, name: str = "State", state_type: StateType = StateType.ACTIVE):
        self.name = name
        self.state_type = state_type
        self.enter_time: Optional[datetime] = None
        self.exit_time: Optional[datetime] = None
        self.execution_count: int = 0
        self.total_execution_time: float = 0.0
        self.transitions: List[StateTransition] = []
        
    def add_transition(self, transition: StateTransition) -> None:
        """添加状态转换"""
        self.transitions.append(transition)
        
    def add_transition_simple(self, to_state: str, 
                            condition: Optional[Callable[[StateContext], bool]] = None,
                            action: Optional[Callable[[StateContext], None]] = None,
                            priority: int = 0) -> None:
        """添加简单状态转换"""
        transition = StateTransition(self.name, to_state, condition, action, priority)
        self.transitions.append(transition)
        
    def get_transitions(self) -> List[StateTransition]:
        """获取状态转换列表"""
        return self.transitions.copy()
        
    def clear_transitions(self) -> None:
        """清空状态转换"""
        self.transitions.clear()
        
    def get_transition_to(self, target_state: str) -> Optional[StateTransition]:
        """获取到指定状态的转换"""
        for transition in self.transitions:
            if transition.to_state == target_state:
                return transition
        return None
        
    def get_available_transitions(self, context: StateContext) -> List[StateTransition]:
        """获取可用的转换列表（按优先级排序）"""
        available = []
        for transition in self.transitions:
            if transition.can_transition(context):
                available.append(transition)
        # 按优先级排序
        available.sort(key=lambda t: t.priority, reverse=True)
        return available
        
    @abstractmethod
    def enter(self, context: StateContext) -> None:
        """
        进入状态时调用
        :param context: 状态上下文
        """
        self.enter_time = datetime.now()
        self.execution_count = 0
        pass
        
    @abstractmethod
    def execute(self, context: StateContext) -> Optional[str]:
        """
        执行状态逻辑
        :param context: 状态上下文
        :return: 下一个状态名称，如果为None则保持当前状态
        """
        start_time = time.time()
        self.execution_count += 1
        
        # 检查自动转换
        next_state = self._check_auto_transitions(context)
        if next_state:
            return next_state
            
        self.total_execution_time += time.time() - start_time
        return None
        
    @abstractmethod
    def exit(self, context: StateContext) -> None:
        """
        退出状态时调用
        :param context: 状态上下文
        """
        self.exit_time = datetime.now()
        pass
        
    def _check_auto_transitions(self, context: StateContext) -> Optional[str]:
        """检查自动转换"""
        for transition in self.transitions:
            if transition.can_transition(context):
                transition.increment_count()
                transition.execute_action(context)
                return transition.to_state
        return None
        
    def get_statistics(self) -> Dict[str, Any]:
        """获取状态统计信息"""
        duration = 0.0
        if self.enter_time and self.exit_time:
            duration = (self.exit_time - self.enter_time).total_seconds()
        elif self.enter_time:
            duration = (datetime.now() - self.enter_time).total_seconds()
            
        return {
            'name': self.name,
            'type': self.state_type.value,
            'execution_count': self.execution_count,
            'total_execution_time': self.total_execution_time,
            'current_duration': duration,
            'transitions_count': len(self.transitions),
            'enter_time': self.enter_time.isoformat() if self.enter_time else None,
            'exit_time': self.exit_time.isoformat() if self.exit_time else None
        }

class HierarchicalState(State):
    """
    分层状态类
    支持子状态的状态实现
    """
    
    def __init__(self, name: str = "HierarchicalState", 
                 state_type: StateType = StateType.ACTIVE):
        super().__init__(name, state_type)
        self.sub_states: Dict[str, State] = {}
        self.current_sub_state: Optional[State] = None
        self.default_sub_state: Optional[str] = None
        
    def add_sub_state(self, state: State) -> None:
        """添加子状态"""
        self.sub_states[state.name] = state
        
    def remove_sub_state(self, state_name: str) -> bool:
        """移除子状态"""
        if state_name in self.sub_states:
            del self.sub_states[state_name]
            return True
        return False
        
    def get_sub_state(self, state_name: str) -> Optional[State]:
        """获取子状态"""
        return self.sub_states.get(state_name)
        
    def set_default_sub_state(self, state_name: str) -> bool:
        """设置默认子状态"""
        if state_name in self.sub_states:
            self.default_sub_state = state_name
            return True
        return False
        
    def enter_sub_state(self, context: StateContext, sub_state_name: str) -> bool:
        """进入子状态"""
        if sub_state_name in self.sub_states:
            if self.current_sub_state:
                self.current_sub_state.exit(context)
            self.current_sub_state = self.sub_states[sub_state_name]
            self.current_sub_state.enter(context)
            return True
        return False
        
    def exit_sub_state(self, context: StateContext) -> bool:
        """退出当前子状态"""
        if self.current_sub_state:
            self.current_sub_state.exit(context)
            self.current_sub_state = None
            return True
        return False
        
    def execute(self, context: StateContext) -> Optional[str]:
        """执行状态逻辑（包含子状态）"""
        # 首先执行父状态逻辑
        result = super().execute(context)
        if result:
            return result
            
        # 然后执行子状态逻辑
        if self.current_sub_state:
            sub_result = self.current_sub_state.execute(context)
            if sub_result:
                return sub_result
                
        return None

class StateMachine:
    """
    状态机类
    """
    
    def __init__(self, name: str):
        self.name = name
        self.current_state: Optional[State] = None
        self.previous_state: Optional[State] = None
        self.context: Optional[StateContext] = None
        self.states: Dict[str, State] = {}
        self.is_running: bool = False
        self.start_time: Optional[datetime] = None
        self.last_update_time: Optional[datetime] = None
        self.update_count: int = 0
        self.lock = threading.RLock()  # 线程安全锁
        self.state_change_callbacks: List[Callable[[State, State], None]] = []
        self.custom_functions: Dict[str, Callable] = {}
        
    def add_state(self, state: State) -> None:
        """添加状态"""
        with self.lock:
            self.states[state.name] = state
            
    def remove_state(self, state_name: str) -> bool:
        """移除状态"""
        with self.lock:
            if state_name in self.states:
                del self.states[state_name]
                return True
            return False
            
    def get_state(self, state_name: str) -> Optional[State]:
        """获取状态"""
        with self.lock:
            return self.states.get(state_name)
            
    def set_context(self, context: StateContext) -> None:
        """设置状态上下文"""
        with self.lock:
            self.context = context
            if context:
                context.state_machine = self
                
    def change_state(self, new_state: Union[State, str]) -> bool:
        """切换状态"""
        with self.lock:
            # 解析状态对象
            if isinstance(new_state, str):
                if new_state not in self.states:
                    print(f"状态 '{new_state}' 不存在")
                    return False
                new_state = self.states[new_state]
                
            # 如果已经是当前状态，直接返回
            if new_state == self.current_state:
                return True
                
            # 退出当前状态
            if self.current_state:
                try:
                    self.current_state.exit(self.context)
                except Exception as e:
                    print(f"退出状态 '{self.current_state.name}' 时出错: {e}")
                    
            # 保存前一个状态
            self.previous_state = self.current_state
            
            # 进入新状态
            self.current_state = new_state
            if self.current_state:
                try:
                    self.current_state.enter(self.context)
                except Exception as e:
                    print(f"进入状态 '{self.current_state.name}' 时出错: {e}")
                    return False
                    
            # 触发状态变更回调
            self._trigger_state_change_callbacks(self.previous_state, self.current_state)
            
            return True
            
    def revert_to_previous_state(self) -> bool:
        """恢复到之前的状态"""
        with self.lock:
            if self.previous_state:
                return self.change_state(self.previous_state)
            return False
            
    def update(self) -> bool:
        """更新状态机"""
        with self.lock:
            self.update_count += 1
            self.last_update_time = datetime.now()
            
            if not self.current_state or not self.context:
                return False
                
            try:
                # 执行当前状态逻辑
                next_state_name = self.current_state.execute(self.context)
                
                # 如果有下一个状态，切换状态
                if next_state_name and next_state_name in self.states:
                    next_state = self.states[next_state_name]
                    if next_state != self.current_state:
                        return self.change_state(next_state)
                        
            except Exception as e:
                print(f"状态机更新出错: {e}")
                import traceback
                traceback.print_exc()
                return False
                
            return True
            
    def start(self) -> bool:
        """启动状态机"""
        with self.lock:
            if self.is_running:
                return True
                
            self.is_running = True
            self.start_time = datetime.now()
            self.update_count = 0
            return True
            
    def stop(self) -> bool:
        """停止状态机"""
        with self.lock:
            if not self.is_running:
                return True
                
            # 退出当前状态
            if self.current_state:
                try:
                    self.current_state.exit(self.context)
                except Exception as e:
                    print(f"退出状态时出错: {e}")
                    
            self.is_running = False
            return True
            
    def get_current_state(self) -> Optional[State]:
        """获取当前状态"""
        with self.lock:
            return self.current_state
            
    def get_previous_state(self) -> Optional[State]:
        """获取之前的状态"""
        with self.lock:
            return self.previous_state
            
    def get_current_state_name(self) -> Optional[str]:
        """获取当前状态名称"""
        with self.lock:
            return self.current_state.name if self.current_state else None
            
    def is_in_state(self, state_name: str) -> bool:
        """检查是否处于指定状态"""
        with self.lock:
            return self.current_state and self.current_state.name == state_name
            
    def add_state_change_callback(self, callback: Callable[[State, State], None]) -> None:
        """添加状态变更回调"""
        with self.lock:
            self.state_change_callbacks.append(callback)
            
    def remove_state_change_callback(self, callback: Callable[[State, State], None]) -> bool:
        """移除状态变更回调"""
        with self.lock:
            if callback in self.state_change_callbacks:
                self.state_change_callbacks.remove(callback)
                return True
            return False
            
    def _trigger_state_change_callbacks(self, old_state: Optional[State], new_state: Optional[State]) -> None:
        """触发状态变更回调"""
        for callback in self.state_change_callbacks:
            try:
                callback(old_state, new_state)
            except Exception as e:
                print(f"状态变更回调执行出错: {e}")
                
    def add_custom_function(self, name: str, func: Callable) -> None:
        """添加自定义函数"""
        with self.lock:
            self.custom_functions[name] = func
            
    def get_custom_function(self, name: str) -> Optional[Callable]:
        """获取自定义函数"""
        with self.lock:
            return self.custom_functions.get(name)
            
    def get_statistics(self) -> Dict[str, Any]:
        """获取状态机统计信息"""
        with self.lock:
            duration = 0.0
            if self.start_time:
                end_time = self.last_update_time or datetime.now()
                duration = (end_time - self.start_time).total_seconds()
                
            current_state_stats = None
            if self.current_state:
                current_state_stats = self.current_state.get_statistics()
                
            return {
                'name': self.name,
                'is_running': self.is_running,
                'start_time': self.start_time.isoformat() if self.start_time else None,
                'last_update_time': self.last_update_time.isoformat() if self.last_update_time else None,
                'update_count': self.update_count,
                'total_duration': duration,
                'states_count': len(self.states),
                'current_state': current_state_stats,
                'previous_state': self.previous_state.name if self.previous_state else None
            }

class StateMachineManager:
    """
    状态机管理器
    用于管理多个状态机的生命周期
    """
    
    def __init__(self):
        self.state_machines: Dict[str, StateMachine] = {}
        self.active_machines: List[str] = []
        self.lock = threading.RLock()
        
    def add_machine(self, name: str, machine: StateMachine) -> bool:
        """添加状态机"""
        with self.lock:
            if name in self.state_machines:
                return False
            self.state_machines[name] = machine
            return True
            
    def remove_machine(self, name: str) -> bool:
        """移除状态机"""
        with self.lock:
            if name in self.state_machines:
                machine = self.state_machines[name]
                if machine.is_running:
                    machine.stop()
                del self.state_machines[name]
                if name in self.active_machines:
                    self.active_machines.remove(name)
                return True
            return False
            
    def get_machine(self, name: str) -> Optional[StateMachine]:
        """获取状态机"""
        with self.lock:
            return self.state_machines.get(name)
            
    def activate_machine(self, name: str) -> bool:
        """激活状态机"""
        with self.lock:
            if name in self.state_machines and name not in self.active_machines:
                self.active_machines.append(name)
                return self.state_machines[name].start()
            return False
            
    def deactivate_machine(self, name: str) -> bool:
        """停用状态机"""
        with self.lock:
            if name in self.active_machines:
                self.active_machines.remove(name)
                machine = self.state_machines.get(name)
                if machine:
                    return machine.stop()
            return False
            
    def update_all(self) -> Dict[str, bool]:
        """更新所有激活的状态机"""
        with self.lock:
            results = {}
            for machine_name in self.active_machines.copy():
                machine = self.state_machines.get(machine_name)
                if machine:
                    results[machine_name] = machine.update()
            return results
            
    def get_machine_stats(self, name: str) -> Optional[Dict[str, Any]]:
        """获取特定状态机的统计信息"""
        with self.lock:
            machine = self.get_machine(name)
            if machine:
                return machine.get_statistics()
            return None
            
    def get_all_stats(self) -> Dict[str, Dict[str, Any]]:
        """获取所有状态机的统计信息"""
        with self.lock:
            stats = {}
            for name, machine in self.state_machines.items():
                stats[name] = machine.get_statistics()
            return stats
            
    def start_all(self) -> Dict[str, bool]:
        """启动所有状态机"""
        with self.lock:
            results = {}
            for name, machine in self.state_machines.items():
                results[name] = machine.start()
            return results
            
    def stop_all(self) -> Dict[str, bool]:
        """停止所有状态机"""
        with self.lock:
            results = {}
            for name, machine in self.state_machines.items():
                results[name] = machine.stop()
            return results