from __future__ import annotations

import asyncio
from typing import Any

from app.modules.agent.orchestration.context.execution_context import ExecutionContext


class WorkflowStepBase:
    intent_name = ""

    def __init__(self, workflow, step_name: str) -> None:
        self._workflow = workflow
        self._step_name = step_name

    def should_run(self, context: ExecutionContext) -> bool:
        route_result = context.route_result
        return bool(route_result) and str(route_result.intent or "").upper() == self.intent_name

    async def run(self, context: ExecutionContext) -> None:
        request = context.request
        task_context = context.task_context
        await context.publisher.publish_status(
            request.request_id,
            "task_workflow",
            f"Запускаю workflow {self._workflow.workflow_id}.",
            {"intent": context.route_result.intent, "sub_intent": context.route_result.query_plan.sub_intent},
        )
        result = await asyncio.to_thread(self._workflow.run, task_context)
        context.workflow_result = result
        request.answer = result.answer or ""
        diagnostics = dict(result.meta.get("diagnostics") or {})
        await self._publish_diagnostics(context, diagnostics, result)

    async def _publish_diagnostics(self, context: ExecutionContext, diagnostics: dict[str, Any], result: Any) -> None:
        request_id = context.request.request_id
        if diagnostics:
            await context.publisher.publish_status(
                request_id,
                "rag_retrieval",
                "RAG retrieval завершен.",
                {
                    "planned_layers": list(diagnostics.get("planned_layers") or diagnostics.get("layers_used") or []),
                    "executed_layers": list(diagnostics.get("executed_layers") or []),
                    "non_empty_layers": list(diagnostics.get("non_empty_layers") or diagnostics.get("docs_layers_with_hits") or []),
                },
            )
            await context.publisher.publish_status(
                request_id,
                "evidence_gate",
                "Evidence gate оценен.",
                {
                    "decision": diagnostics.get("gate_decision"),
                    "reason": diagnostics.get("gate_decision_reason"),
                    "missing": list(diagnostics.get("gate_missing_requirements") or []),
                    "satisfied": list(diagnostics.get("gate_satisfied_requirements") or []),
                },
            )
        await context.publisher.publish_status(
            request_id,
            "workflow_result",
            f"Workflow {self._workflow.workflow_id} завершен.",
            {
                "workflow_id": self._workflow.workflow_id,
                "result_type": getattr(result.result_type, "value", str(result.result_type)),
                "answer_length": len(result.answer or ""),
            },
        )
