import logging

import agentspeak
from spade.behaviour import OneShotBehaviour
from spade.message import Message
from spade_bdi.bdi import BDIAgent

from control_backend.agents.bdi.behaviours.belief_setter import BeliefSetterBehaviour
from control_backend.agents.bdi.behaviours.receive_llm_resp_behaviour import (
    ReceiveLLMResponseBehaviour,
)
from control_backend.core.config import settings


class BDICoreAgent(BDIAgent):
    """
    This is the Brain agent that does the belief inference with AgentSpeak.
    This is a continous process that happens automatically in the background.
    This class contains all the actions that can be called from AgentSpeak plans.
    It has the BeliefSetter behaviour and can aks and recieve requests from the LLM agent.
    """

    logger = logging.getLogger("bdi_core_agent")

    async def setup(self) -> None:
        """
        Initializes belief behaviors and message routing.
        """
        self.logger.info("BDICoreAgent setup started")

        self.add_behaviour(BeliefSetterBehaviour())
        self.add_behaviour(ReceiveLLMResponseBehaviour())

        self.logger.info("BDICoreAgent setup complete")

    def add_custom_actions(self, actions) -> None:
        """
        Registers custom AgentSpeak actions callable from plans.
        """

        @actions.add(".reply", 1)
        def _reply(agent: "BDICoreAgent", term, intention):
            """
            Sends text to the LLM (AgentSpeak action).
            Example: .reply("Hello LLM!")
            """
            message_text = agentspeak.grounded(term.args[0], intention.scope)
            self.logger.info("Reply action sending: %s", message_text)

            self._send_to_llm(str(message_text))
            yield

    def _send_to_llm(self, text: str):
        """
        Sends a text query to the LLM Agent asynchronously.
        """

        class SendBehaviour(OneShotBehaviour):
            async def run(self) -> None:
                msg = Message(
                    to=settings.agent_settings.llm_agent_name + "@" + settings.agent_settings.host,
                    body=text,
                )

                await self.send(msg)
                self.agent.logger.info("Message sent to LLM: %s", text)

        self.add_behaviour(SendBehaviour())
