"""PathwayNode — sub-pathway execution node."""

from __future__ import annotations

from typing import TYPE_CHECKING, Literal

from pydantic import Field

from core.common import JsonObject
from core.pathways.models.io import NodeInputs, NodeOutputs
from core.pathways.nodes.base import NodeBase
from core.pathways.nodes.models import PathwayExecutionOutput

if TYPE_CHECKING:
    from core.pathways.context import Context


class PathwayNode(NodeBase):
    """Sub-pathway execution — pathways in pathways.

    Executes another registered pathway as a child. The parent
    sees this as a single node; internally it runs a complete
    sub-pathway.

    Attributes
    ----------
    pathway_id : str
        ID of a registered pathway to execute.
    inputs : JsonObject
        Mapping of input values (supports ``{{var}}`` templates).
    output_key : str | None
        Key to extract from sub-pathway outputs.
    """

    type: Literal["pathway"] = "pathway"
    pathway_id: str
    inputs: JsonObject = Field(default_factory=dict)
    output_key: str | None = None

    async def compute(self, inputs: NodeInputs, ctx: Context) -> NodeOutputs:
        """Execute the sub-pathway and return its results."""
        template_data = inputs.to_dict()
        pathway_service = ctx.services.pathway_service
        pathway_vm = ctx.services.pathway_executor

        if not pathway_service:
            raise RuntimeError("Pathway service not configured — cannot run sub-pathway")

        if not pathway_vm:
            raise RuntimeError("Pathway VM not configured — cannot run sub-pathway")

        sub_pathway = pathway_service.load(self.pathway_id)
        if not sub_pathway:
            raise RuntimeError(f"Sub-pathway not found: {self.pathway_id}")

        resolved_inputs = self._resolve_templates(self.inputs, template_data)
        if not isinstance(resolved_inputs, dict):
            resolved_inputs = {}

        for key, value in template_data.items():
            if key not in resolved_inputs and not key.startswith("_"):
                resolved_inputs[key] = value

        result = await pathway_vm.execute(sub_pathway, inputs=resolved_inputs)

        outputs: JsonObject = {}
        if hasattr(result, "outputs"):
            outputs = result.outputs
        elif isinstance(result, dict):
            outputs = result

        if self.output_key and isinstance(outputs, dict):
            extracted = outputs.get(self.output_key, outputs)
            output = PathwayExecutionOutput(
                success=True,
                pathway_id=self.pathway_id,
                result=extracted,
            )
            return NodeOutputs(output=output.model_dump())

        output = PathwayExecutionOutput(
            success=True,
            pathway_id=self.pathway_id,
            outputs=outputs,
        )
        return NodeOutputs(output=output.model_dump())


__all__ = ["PathwayNode"]
