"""
Agent 状态管理模块

提供完整的Agent状态管理，支持：
- 完整的生命周期管理
- 状态序列化和持久化
- 暂停和恢复
- 动态Agent树结构
"""

import uuid
from datetime import datetime, timezone
from enum import Enum
from typing import Any, Dict, List, Optional
from pydantic import BaseModel, Field


def _generate_agent_id() -> str:
    """生成唯一的Agent ID"""
    return f"agent_{uuid.uuid4().hex[:8]}"


class AgentStatus(str, Enum):
    """Agent 运行状态"""
    CREATED = "created"          # 已创建，未开始
    RUNNING = "running"          # 运行中
    WAITING = "waiting"          # 等待中（等待消息或输入）
    PAUSED = "paused"            # 已暂停
    COMPLETED = "completed"      # 已完成
    FAILED = "failed"            # 失败
    STOPPED = "stopped"          # 被停止
    STOPPING = "stopping"        # 正在停止


class AgentState(BaseModel):
    """
    Agent 状态模型
    
    包含Agent执行所需的所有状态信息，支持：
    - 完整的生命周期管理
    - 状态序列化和持久化
    - 暂停和恢复
    - 动态Agent树结构
    """
    
    # ============ 基本信息 ============
    agent_id: str = Field(default_factory=_generate_agent_id)
    agent_name: str = "DeepAudit Agent"
    agent_type: str = "generic"  # recon, analysis, verification, specialist
    parent_id: Optional[str] = None  # 父Agent ID（用于动态Agent树）
    
    # ============ 任务信息 ============
    task: str = ""
    task_context: Dict[str, Any] = Field(default_factory=dict)
    inherited_context: Dict[str, Any] = Field(default_factory=dict)  # 从父Agent继承的上下文
    
    # ============ 知识模块 ============
    knowledge_modules: List[str] = Field(default_factory=list)  # 加载的知识模块名称
    
    # ============ 执行状态 ============
    status: AgentStatus = AgentStatus.CREATED
    iteration: int = 0
    max_iterations: int = 50
    
    # ============ 对话历史 ============
    messages: List[Dict[str, Any]] = Field(default_factory=list)
    system_prompt: str = ""
    
    # ============ 执行记录 ============
    actions_taken: List[Dict[str, Any]] = Field(default_factory=list)
    observations: List[Dict[str, Any]] = Field(default_factory=list)
    errors: List[str] = Field(default_factory=list)
    
    # ============ 发现列表 ============
    findings: List[Dict[str, Any]] = Field(default_factory=list)
    
    # ============ 时间戳 ============
    created_at: str = Field(default_factory=lambda: datetime.now(timezone.utc).isoformat())
    started_at: Optional[str] = None
    last_updated: str = Field(default_factory=lambda: datetime.now(timezone.utc).isoformat())
    finished_at: Optional[str] = None
    
    # ============ 等待状态 ============
    waiting_for_input: bool = False
    waiting_start_time: Optional[datetime] = None
    waiting_reason: str = ""
    waiting_timeout_seconds: int = 600  # 10分钟超时
    
    # ============ 最终结果 ============
    final_result: Optional[Dict[str, Any]] = None
    
    # ============ 统计信息 ============
    total_tokens: int = 0
    tool_calls: int = 0
    
    # ============ 标志位 ============
    stop_requested: bool = False
    max_iterations_warning_sent: bool = False
    
    class Config:
        use_enum_values = True
    
    # ============ 状态管理方法 ============
    
    def start(self) -> None:
        """开始执行"""
        self.status = AgentStatus.RUNNING
        self.started_at = datetime.now(timezone.utc).isoformat()
        self._update_timestamp()
    
    def increment_iteration(self) -> None:
        """增加迭代次数"""
        self.iteration += 1
        self._update_timestamp()
    
    def set_completed(self, final_result: Optional[Dict[str, Any]] = None) -> None:
        """标记为完成"""
        self.status = AgentStatus.COMPLETED
        self.final_result = final_result
        self.finished_at = datetime.now(timezone.utc).isoformat()
        self._update_timestamp()
    
    def set_failed(self, error: str) -> None:
        """标记为失败"""
        self.status = AgentStatus.FAILED
        self.add_error(error)
        self.finished_at = datetime.now(timezone.utc).isoformat()
        self._update_timestamp()
    
    def request_stop(self) -> None:
        """请求停止"""
        self.stop_requested = True
        self.status = AgentStatus.STOPPING
        self._update_timestamp()
    
    def set_stopped(self) -> None:
        """标记为已停止"""
        self.status = AgentStatus.STOPPED
        self.finished_at = datetime.now(timezone.utc).isoformat()
        self._update_timestamp()
    
    # ============ 等待状态管理 ============
    
    def enter_waiting_state(self, reason: str = "等待消息") -> None:
        """进入等待状态"""
        self.waiting_for_input = True
        self.waiting_start_time = datetime.now(timezone.utc)
        self.waiting_reason = reason
        self.status = AgentStatus.WAITING
        self._update_timestamp()
    
    def resume_from_waiting(self, new_task: Optional[str] = None) -> None:
        """从等待状态恢复"""
        self.waiting_for_input = False
        self.waiting_start_time = None
        self.waiting_reason = ""
        self.stop_requested = False
        self.status = AgentStatus.RUNNING
        if new_task:
            self.task = new_task
        self._update_timestamp()
    
    def has_waiting_timeout(self) -> bool:
        """检查等待是否超时"""
        if not self.waiting_for_input or not self.waiting_start_time:
            return False
        
        if self.stop_requested or self.status in [AgentStatus.COMPLETED, AgentStatus.FAILED]:
            return False
        
        elapsed = (datetime.now(timezone.utc) - self.waiting_start_time).total_seconds()
        return elapsed > self.waiting_timeout_seconds
    
    def is_waiting_for_input(self) -> bool:
        """是否在等待输入"""
        return self.waiting_for_input
    
    # ============ 执行控制 ============
    
    def should_stop(self) -> bool:
        """是否应该停止"""
        return (
            self.stop_requested or 
            self.status in [AgentStatus.COMPLETED, AgentStatus.FAILED, AgentStatus.STOPPED] or
            self.has_reached_max_iterations()
        )
    
    def has_reached_max_iterations(self) -> bool:
        """是否达到最大迭代次数"""
        return self.iteration >= self.max_iterations
    
    def is_approaching_max_iterations(self, threshold: float = 0.85) -> bool:
        """是否接近最大迭代次数"""
        return self.iteration >= int(self.max_iterations * threshold)
    
    # ============ 消息管理 ============
    
    def add_message(self, role: str, content: Any) -> None:
        """添加消息"""
        self.messages.append({
            "role": role,
            "content": content,
            "timestamp": datetime.now(timezone.utc).isoformat(),
        })
        self._update_timestamp()
    
    def get_conversation_history(self) -> List[Dict[str, Any]]:
        """获取对话历史（不含时间戳，用于LLM调用）"""
        return [{"role": m["role"], "content": m["content"]} for m in self.messages]
    
    # ============ 执行记录 ============
    
    def add_action(self, action: Dict[str, Any]) -> None:
        """记录执行的动作"""
        self.actions_taken.append({
            "iteration": self.iteration,
            "timestamp": datetime.now(timezone.utc).isoformat(),
            "action": action,
        })
        self.tool_calls += 1
        self._update_timestamp()
    
    def add_observation(self, observation: Dict[str, Any]) -> None:
        """记录观察结果"""
        self.observations.append({
            "iteration": self.iteration,
            "timestamp": datetime.now(timezone.utc).isoformat(),
            "observation": observation,
        })
        self._update_timestamp()
    
    def add_error(self, error: str) -> None:
        """记录错误"""
        self.errors.append(f"Iteration {self.iteration}: {error}")
        self._update_timestamp()
    
    def add_finding(self, finding: Dict[str, Any]) -> None:
        """添加发现"""
        finding["discovered_at"] = datetime.now(timezone.utc).isoformat()
        finding["discovered_by"] = self.agent_id
        self.findings.append(finding)
        self._update_timestamp()
    
    # ============ 上下文管理 ============
    
    def update_context(self, key: str, value: Any) -> None:
        """更新任务上下文"""
        self.task_context[key] = value
        self._update_timestamp()
    
    def inherit_context(self, parent_context: Dict[str, Any]) -> None:
        """继承父Agent的上下文"""
        self.inherited_context = parent_context.copy()
        self._update_timestamp()
    
    # ============ 统计和摘要 ============
    
    def add_tokens(self, tokens: int) -> None:
        """添加token使用量"""
        self.total_tokens += tokens
        self._update_timestamp()
    
    def get_execution_summary(self) -> Dict[str, Any]:
        """获取执行摘要"""
        return {
            "agent_id": self.agent_id,
            "agent_name": self.agent_name,
            "agent_type": self.agent_type,
            "parent_id": self.parent_id,
            "task": self.task,
            "status": self.status,
            "iteration": self.iteration,
            "max_iterations": self.max_iterations,
            "total_tokens": self.total_tokens,
            "tool_calls": self.tool_calls,
            "findings_count": len(self.findings),
            "errors_count": len(self.errors),
            "created_at": self.created_at,
            "started_at": self.started_at,
            "finished_at": self.finished_at,
            "duration_seconds": self._calculate_duration(),
            "knowledge_modules": self.knowledge_modules,
        }
    
    def _calculate_duration(self) -> Optional[float]:
        """计算执行时长"""
        if not self.started_at:
            return None
        
        end_time = self.finished_at or datetime.now(timezone.utc).isoformat()
        start = datetime.fromisoformat(self.started_at.replace('Z', '+00:00'))
        end = datetime.fromisoformat(end_time.replace('Z', '+00:00'))
        return (end - start).total_seconds()
    
    def _update_timestamp(self) -> None:
        """更新最后修改时间"""
        self.last_updated = datetime.now(timezone.utc).isoformat()
