"""Expert - 专家团队运行时包装器

Expert 是运行时包装器，持有 ExpertConfig 和 ConfigDrivenAgent 实例，
在标准 Agent 生命周期之上添加团队感知行为。
"""

from __future__ import annotations

import time

from agentkit.core.agent_pool import AgentPool
from agentkit.core.config_driven import ConfigDrivenAgent
from agentkit.core.handoff_transport import InProcessHandoffTransport
from agentkit.core.shared_workspace import SharedWorkspace
from agentkit.experts.config import ExpertConfig


class Expert:
    """运行时包装器：Expert = ExpertConfig + ConfigDrivenAgent + 团队行为

    在标准 Agent 生命周期之上添加团队感知行为，包括：
    - 团队频道消息广播
    - 跨 Expert 协助请求
    - 计划修改提案
    - 能力摘要
    """

    def __init__(
        self,
        config: ExpertConfig,
        agent: ConfigDrivenAgent,
        handoff_transport: InProcessHandoffTransport | None = None,
        workspace: SharedWorkspace | None = None,
    ):
        self.config = config
        self.agent = agent
        self._handoff_transport = handoff_transport
        self._workspace = workspace
        self._team_id: str | None = None
        self._is_active: bool = True

    @classmethod
    async def create(
        cls,
        config: ExpertConfig,
        pool: AgentPool,
        handoff_transport: InProcessHandoffTransport | None = None,
        workspace: SharedWorkspace | None = None,
        team_context: str | None = None,
    ) -> Expert:
        """通过 AgentPool 创建 Expert，实例化 ConfigDrivenAgent。

        如果提供了 team_context，会将其注入到 Agent 的 system prompt 中，
        使 Agent 感知其团队角色和其他 Expert。
        """
        agent = await pool.create_agent(config)

        expert = cls(
            config=config,
            agent=agent,
            handoff_transport=handoff_transport,
            workspace=workspace,
        )

        # 如果提供了团队上下文，修改 Agent 的 prompt 以注入团队角色信息
        if team_context and hasattr(agent, "_prompt_template") and agent._prompt_template:
            sections = agent._prompt_template._sections
            sections.context = (
                f"{team_context}\n\n{sections.context}" if sections.context else team_context
            )

        return expert

    async def send_message(
        self,
        channel: str,
        content: str,
        summary: str | None = None,
    ) -> None:
        """向团队频道广播消息。

        如果内容较长（>500 字符），自动创建摘要并将完整内容存储到 SharedWorkspace。
        即使没有提供 summary，长内容也会存储到 workspace 以避免数据丢失。
        """
        message = {
            "expert_id": self.config.name,
            "expert_name": self.config.name,
            "content": summary or content[:500],
            "timestamp": time.time(),
            "type": "chat",
        }

        if len(content) > 500 and self._workspace:
            # Always store full content in workspace for long messages
            await self._workspace.write(
                f"expert:{self.config.name}:messages:{int(message['timestamp'])}",
                content,
                self.config.name,
            )

        if self._handoff_transport:
            await self._handoff_transport.send(channel, message)

    async def request_assist(
        self,
        target_expert: str,
        task: str,
        reason: str = "",
    ) -> None:
        """通过 handoff 请求其他 Expert 协助。"""
        if not self._handoff_transport:
            raise RuntimeError("No handoff transport configured")

        handoff_msg = {
            "source_expert": self.config.name,
            "target_expert": target_expert,
            "task": task,
            "reason": reason,
            "type": "assist_request",
        }
        await self._handoff_transport.send(f"expert:{target_expert}:handoff", handoff_msg)

    async def propose_plan_modification(
        self,
        plan_id: str,
        modification: dict,
    ) -> None:
        """向 Lead Expert 提交计划修改提案。"""
        if not self._handoff_transport:
            raise RuntimeError("No handoff transport configured")

        proposal = {
            "proposing_expert": self.config.name,
            "plan_id": plan_id,
            "modification": modification,
            "type": "plan_modification_proposal",
        }
        await self._handoff_transport.send("team:plan_modifications", proposal)

    def get_capabilities_summary(self) -> dict:
        """返回此 Expert 的能力摘要，用于团队发现。"""
        return {
            "name": self.config.name,
            "persona": self.config.persona,
            "thinking_style": self.config.thinking_style,
            "bound_skills": self.config.bound_skills,
            "is_lead": self.config.is_lead,
            "color": self.config.color,
            "avatar": self.config.avatar,
        }

    async def destroy(self, pool: AgentPool) -> None:
        """从池中移除 Expert 的 Agent。输出保留在 SharedWorkspace 中。"""
        self._is_active = False
        await pool.remove_agent(self.config.name)

    @property
    def is_active(self) -> bool:
        return self._is_active

    @property
    def team_id(self) -> str | None:
        return self._team_id

    @team_id.setter
    def team_id(self, value: str) -> None:
        self._team_id = value
