# EXECUTOR-COUPLED: This node raises FlowFailureError which the workflow
# executor handles specially — setting execution status to "failed" rather
# than "completed with errors". Changes here must be coordinated with
# workflow_executor.py in flowire-app.

"""Throw Error node for intentionally failing a workflow."""

from typing import Any

from flowire_sdk import BaseNode, BaseNodeOutput, HandleConfig, NodeExecutionContext, NodeHandles, NodeMetadata
from flowire_sdk.exceptions import FlowFailureError
from pydantic import BaseModel, Field


class ThrowErrorInput(BaseModel):
    """Input schema for Throw Error node."""

    error_message: str = Field(
        default="",
        description="Error message for the failure. Supports expressions like {{node-id.field}}.",
    )


class ThrowErrorOutput(BaseNodeOutput):
    """Output schema for Throw Error node.

    This node never produces output (it always raises FlowFailureError),
    but the schema is required by the node registry.
    """

    pass


class ThrowErrorNode(BaseNode):
    """Intentionally fail a workflow with a user-defined error message.

    When this node executes, the entire workflow is marked as "failed"
    with the provided error message. Use this in conditional branches
    to signal that the workflow reached an invalid state.
    """

    input_schema = ThrowErrorInput
    output_schema = ThrowErrorOutput

    metadata = NodeMetadata(
        name="Throw Error",
        description="Intentionally fail the workflow with a custom error message",
        category="logic",
        icon="⛔",
        color="#D32F2F",
        handles=NodeHandles(
            inputs=[HandleConfig(id="default", position="left")],
            outputs=[],  # Terminal node
        ),
    )

    async def execute_logic(
        self,
        validated_inputs: dict[str, Any],
        context: NodeExecutionContext,
    ) -> None:
        """Raise FlowFailureError to fail the workflow."""
        error_message = validated_inputs.get("error_message", "")
        raise FlowFailureError(error_message)
