"""Base AgentScope-backed agent primitives for DSCons."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any

try:
    from agentscope.agent import AgentBase
    from agentscope.message import Msg
except ImportError:  # pragma: no cover

    class AgentBase:  # type: ignore[no-redef]
        def __init__(self, *args: Any, **kwargs: Any) -> None:
            pass

    class Msg(dict):  # type: ignore[no-redef]
        pass


from app.agents.personas import build_persona_system_prompt


@dataclass(slots=True)
class AgentExecutionContext:
    """Execution context passed to logical agents."""

    query: str
    task_type: str
    retrieved_chunks: list[dict[str, Any]]
    agent_code: str = "minh"
    persona_name: str = "Minh"
    persona_profile: dict[str, Any] = field(default_factory=dict)


class BaseTaskAgent(AgentBase):
    """AgentScope-backed logical agent sharing a single LLM client."""

    agent_name: str = "base_agent"
    system_prompt: str = "You are a helpful construction assistant."

    def __init__(self, llm_client: Any) -> None:
        super().__init__()
        self._llm_client = llm_client
        self._last_observed: list[Msg] = []

    async def observe(self, msg: Msg | list[Msg] | None) -> None:
        """Capture observed messages for AgentScope-compatible tracing."""

        if msg is None:
            return
        if isinstance(msg, list):
            self._last_observed.extend(msg)
            return
        self._last_observed.append(msg)

    async def run(self, context: AgentExecutionContext) -> str:
        """Execute the task with retrieved knowledge context."""

        query_msg = Msg(
            name="user",
            role="user",
            content=context.query,
            metadata={
                "task_type": context.task_type,
                "agent_code": context.agent_code,
                "persona_name": context.persona_name,
            },
        )
        await self.observe(query_msg)
        response_msg = await self.reply(context=context)
        if hasattr(response_msg, "get_text_content"):
            return response_msg.get_text_content()
        if hasattr(response_msg, "content"):
            return str(response_msg.content or "")
        return str(
            response_msg.get("content", "")
            if isinstance(response_msg, dict)
            else response_msg
        )

    async def reply(self, *args: Any, **kwargs: Any) -> Msg:
        """Generate an AgentScope message response from task context."""

        context = kwargs["context"]
        knowledge_block = self._format_retrieved_chunks(context.retrieved_chunks)
        persona_block = self._format_persona_profile(context.persona_profile)

        # Build comprehensive persona system prompt
        effective_system_prompt = build_persona_system_prompt(
            agent_code=context.agent_code,
            task_type=context.task_type,
        )
        if (
            self.system_prompt
            and self.system_prompt != "You are a helpful construction assistant."
        ):
            effective_system_prompt += (
                f"\n\n[CHỈ DẪN CHUYÊN BIỆT TỪ SPECIALIST CLASS]:\n{self.system_prompt}"
            )

        user_prompt = (
            f"AI employee code: {context.agent_code}\n"
            f"AI employee name: {context.persona_name}\n"
            f"Task type: {context.task_type}\n"
            f"User query: {context.query}\n\n"
            f"Persona guidance:\n{persona_block}\n\n"
            f"Retrieved knowledge:\n{knowledge_block}\n\n"
            "Answer in Vietnamese when possible, keep the response practical and concise, "
            "and stay consistent with the persona style and pronoun guidance."
        )
        messages = [
            {"role": "system", "content": effective_system_prompt},
            {"role": "user", "content": user_prompt},
        ]
        content = await self._llm_client.chat(messages, agent_code=context.agent_code)
        reply = Msg(
            name=self.agent_name,
            role="assistant",
            content=content,
            metadata={
                "task_type": context.task_type,
                "agent_code": context.agent_code,
                "persona_name": context.persona_name,
            },
        )
        await self.observe(reply)
        return reply

    def _format_retrieved_chunks(self, chunks: list[dict[str, Any]]) -> str:
        """Convert retrieval hits into a prompt-safe text block."""

        if not chunks:
            return "- Không có dữ liệu tham chiếu trong kho tri thức."
        lines: list[str] = []
        for index, chunk in enumerate(chunks, start=1):
            text = str(chunk.get("text", "")).strip()
            metadata = chunk.get("metadata", {}) or {}
            lines.append(f"{index}. {text}")
            if metadata:
                lines.append(f"   Metadata: {metadata}")
        return "\n".join(lines)

    def _format_persona_profile(self, persona_profile: dict[str, Any]) -> str:
        """Convert persona metadata into a prompt-safe guidance block."""

        if not persona_profile:
            return "- Không có cấu hình persona, dùng phong cách mặc định."
        lines = [
            f"- Vai trò: {persona_profile.get('role_title', 'Chưa rõ')}",
            f"- Phong cách giao tiếp: {persona_profile.get('communication_style', 'Chưa rõ')}",
            f"- Tông mặc định: {persona_profile.get('default_tone', 'Chưa rõ')}",
            f"- Mô tả: {persona_profile.get('description', 'Chưa rõ')}",
        ]
        pronoun_guidance = persona_profile.get("pronoun_guidance", []) or []
        if pronoun_guidance:
            lines.append("- Hướng dẫn xưng hô:")
            for item in pronoun_guidance:
                lines.append(f"  - {item}")
        return "\n".join(lines)
