from __future__ import annotations

from fastapi import APIRouter
from pydantic import BaseModel, HttpUrl
from typing import TYPE_CHECKING

from app.modules.agent.changeset_validator import ChangeSetValidator
from app.modules.agent.confluence_service import ConfluenceService
from app.modules.agent.llm import AgentLlmService
from app.modules.agent.prompt_loader import PromptLoader
from app.modules.agent.story_context_repository import StoryContextRepository
from app.modules.agent.story_session_recorder import StorySessionRecorder
from app.modules.agent.service import GraphAgentRuntime
from app.modules.agent.repository import AgentRepository
from app.modules.contracts import RagRetriever
from app.modules.shared.gigachat.client import GigaChatClient
from app.modules.shared.gigachat.settings import GigaChatSettings
from app.modules.shared.gigachat.token_provider import GigaChatTokenProvider


class ConfluenceFetchRequest(BaseModel):
    url: HttpUrl


if TYPE_CHECKING:
    from app.modules.rag.explain.retriever_v2 import CodeExplainRetrieverV2


class AgentModule:
    def __init__(
        self,
        rag_retriever: RagRetriever,
        agent_repository: AgentRepository,
        story_context_repository: StoryContextRepository,
        code_explain_retriever: CodeExplainRetrieverV2 | None = None,
    ) -> None:
        self.confluence = ConfluenceService()
        self.changeset_validator = ChangeSetValidator()
        self.story_context_repository = story_context_repository
        settings = GigaChatSettings.from_env()
        token_provider = GigaChatTokenProvider(settings)
        client = GigaChatClient(settings, token_provider)
        prompt_loader = PromptLoader()
        llm = AgentLlmService(client=client, prompts=prompt_loader)
        self.llm = llm
        story_recorder = StorySessionRecorder(story_context_repository)
        self.runtime = GraphAgentRuntime(
            rag=rag_retriever,
            confluence=self.confluence,
            changeset_validator=self.changeset_validator,
            llm=self.llm,
            agent_repository=agent_repository,
            story_recorder=story_recorder,
            code_explain_retriever=code_explain_retriever,
        )

    def internal_router(self) -> APIRouter:
        router = APIRouter(prefix="/internal/tools", tags=["internal-tools"])

        @router.post("/confluence/fetch")
        async def fetch_page(request: ConfluenceFetchRequest) -> dict:
            return await self.confluence.fetch_page(str(request.url))

        return router
