# Standard library imports

# External imports
import contextlib
import logging

import zmq
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

from control_backend.agents.bdi.bdi_core import BDICoreAgent
from control_backend.agents.bdi.text_extractor import TBeliefExtractor
from control_backend.agents.belief_collector.belief_collector import BeliefCollectorAgent
from control_backend.agents.llm.llm import LLMAgent

# Internal imports
from control_backend.agents.ri_communication_agent import RICommunicationAgent
from control_backend.agents.vad_agent import VADAgent
from control_backend.api.v1.router import api_router
from control_backend.core.config import settings
from control_backend.core.zmq_context import context

logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG)


@contextlib.asynccontextmanager
async def lifespan(app: FastAPI):
    logger.info("%s starting up.", app.title)

    # Initiate sockets
    internal_comm_socket = context.socket(zmq.PUB)
    internal_comm_address = settings.zmq_settings.internal_comm_address
    internal_comm_socket.bind(internal_comm_address)
    app.state.internal_comm_socket = internal_comm_socket
    logger.info("Internal publishing socket bound to %s", internal_comm_socket)

    # Initiate agents
    ri_communication_agent = RICommunicationAgent(
        settings.agent_settings.ri_communication_agent_name + "@" + settings.agent_settings.host,
        settings.agent_settings.ri_communication_agent_name,
        address="tcp://*:5555",
        bind=True,
    )
    await ri_communication_agent.start()

    llm_agent = LLMAgent(
        settings.agent_settings.llm_agent_name + "@" + settings.agent_settings.host,
        settings.agent_settings.llm_agent_name,
    )
    await llm_agent.start()

    bdi_core = BDICoreAgent(
        settings.agent_settings.bdi_core_agent_name + "@" + settings.agent_settings.host,
        settings.agent_settings.bdi_core_agent_name,
        "src/control_backend/agents/bdi/rules.asl",
    )
    await bdi_core.start()

    belief_collector = BeliefCollectorAgent(
        settings.agent_settings.belief_collector_agent_name + "@" + settings.agent_settings.host,
        settings.agent_settings.belief_collector_agent_name,
    )
    await belief_collector.start()

    text_belief_extractor = TBeliefExtractor(
        settings.agent_settings.text_belief_extractor_agent_name
        + "@"
        + settings.agent_settings.host,
        settings.agent_settings.text_belief_extractor_agent_name,
    )
    await text_belief_extractor.start()

    _temp_vad_agent = VADAgent("tcp://localhost:5558", False)
    await _temp_vad_agent.start()

    yield

    logger.info("%s shutting down.", app.title)


# if __name__ == "__main__":
app = FastAPI(title=settings.app_title, lifespan=lifespan)

# This middleware allows other origins to communicate with us
app.add_middleware(
    CORSMiddleware,  # https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS
    allow_origins=[settings.ui_url],  # address of our UI application
    allow_methods=["*"],  # GET, POST, etc.
)

app.include_router(api_router, prefix="")  # TODO: make prefix /api/v1


@app.get("/")
async def root():
    return {"status": "ok"}
