
import fastapi
import subprocess

from loguru import logger

from importlib.metadata import version
from beanie.operators import And

from AgentService.config import Config

from AgentService.types.chat import ChatToolState, Chat
from AgentService.types.message import Message
from AgentService.enums.chat import ChatToolStateStatus

from .models import (
    SendMessageRequest, SendMessageResponse,
    GetStatesRequest, GetStatesResponse,
    GetChatRequest, GetChatResponse,
    GetVersionResponse
)


chat_router = fastapi.APIRouter(prefix="/chat")


@chat_router.post("")
async def send_message(request: SendMessageRequest) -> SendMessageResponse:
    agent = Config().agent

    response = await agent.answer(
        chat_id=request.chat_id,
        text=request.text,
        context=request.context,
        tool_answers=request.tool_answers
    )

    return SendMessageResponse(
        data=response,
        status="ok"
    )


@chat_router.get("")
async def get_chat(chat_id: str) -> GetChatResponse:
    agent = Config().agent

    chat = await agent.get_chat(chat_id=chat_id, create=False)
    if not chat:
        return GetChatResponse(
            data=[],
            status="ok"
        )

    messages = await Message.find_many(Message.chat_id == chat.id).to_list()

    return GetChatResponse(
        data=messages,
        status="ok"
    )


@chat_router.get("/version")
async def get_version() -> GetVersionResponse:
    try:
        outer_version = subprocess.run(
            "python3.11 -c \"from importlib.metadata import version; print(version('AgentService'))\"",
            shell=True,
            capture_output=True,
            text=True,
            cwd="."
        ).stdout

    except Exception as err:
        logger.exception(err)

        outer_version = "N/A"

    return GetVersionResponse(
        data={
            "inner": version("AgentService"),
            "outer": outer_version,
        },
        status="ok"
    )


@chat_router.get("/states")
async def get_states() -> GetStatesResponse:
    states = await ChatToolState.find_all().to_list()

    return GetStatesResponse(
        data=states,
        status="ok"
    )


@chat_router.get("/state")
async def get_state(request: GetStatesRequest) -> GetStatesResponse:
    chat = await Chat.find_one(Chat.chat_id == request.chat_id)

    if not chat:
        return GetStatesResponse(
            description=f"Can't find such chat {request.chat_id}",
            status="error"
        )

    states = await ChatToolState.find_many(
        And(
            ChatToolState.chat_id == chat.id,
            ChatToolState.status == ChatToolStateStatus.in_progress
        )
    ).to_list()

    return GetStatesResponse(
        data=states,
        status="ok"
    )
