from __future__ import annotations

import asyncio

from app.core.exceptions import AppError
from app.modules.agent.task_runtime.context import TaskRuntimeContextBuilder
from app.modules.agent.task_runtime.enrichment import ContextEnrichmentService
from app.modules.agent.orchestration.adapters.intent_router_adapter import IntentRouterAdapter
from app.modules.agent.orchestration.context.execution_context import ExecutionContext
from app.modules.agent.orchestration.v2_progress import build_progress_callback
from app.schemas.common import ModuleName


class RouteIntentStep:
    def __init__(
        self,
        router: IntentRouterAdapter,
        context_builder: TaskRuntimeContextBuilder,
        enrichment: ContextEnrichmentService,
    ) -> None:
        self._router = router
        self._context_builder = context_builder
        self._enrichment = enrichment

    async def run(self, context: ExecutionContext) -> None:
        rag_session_id = context.session.active_rag_session_id
        if not rag_session_id:
            raise AppError(
                "rag_session_not_bound",
                "Agent session has no active rag_session_id for process v2.",
                ModuleName.RAG,
            )
        request = context.request
        loop = asyncio.get_running_loop()
        task_context = self._context_builder.build(
            task_id=request.request_id,
            dialog_session_id=context.session.session_id,
            rag_session_id=rag_session_id,
            mode="auto",
            message=request.message,
            attachments=[],
            files=[],
            progress_cb=build_progress_callback(loop, context.publisher, request.request_id),
            trace=context.trace,
        )
        task_context.enriched_context = self._enrichment.enrich(task_context)
        context.task_context = task_context
        await context.publisher.publish_status(
            request.request_id,
            "intent_router",
            "Маршрутизирую запрос и определяю целевой workflow.",
        )
        route_result = await asyncio.to_thread(
            self._router.route,
            request.message,
            task_context.conversation_state,
            task_context.repo_context,
            context.trace.module("intent_router"),
        )
        task_context.route_result = route_result
        context.route_result = route_result
        await context.publisher.publish_status(
            request.request_id,
            "intent_router",
            f"Маршрут выбран: {route_result.intent} / {route_result.query_plan.sub_intent}.",
            {
                "intent": route_result.intent,
                "sub_intent": route_result.query_plan.sub_intent,
                "matched_intent_source": route_result.matched_intent_source,
            },
        )
