"""Base workflow ABC — all workflows implement validate/execute/compile."""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Any, Dict, List, Optional

from databridge_core.sdk.core.context import SDKContext
from databridge_core.sdk.core.types import CompiledArtifact, Result


class BaseWorkflow(ABC):
    """Abstract base for all SDK workflows.

    Subclasses must implement:
        - ``validate(params)`` — check inputs, raise ``ValidationError``
        - ``execute(params, ctx)`` — run the workflow
        - ``compile_to_snowflake(params, ctx)`` — generate Snowflake DDL

    Class attributes:
        name: Dotted workflow name (e.g. ``reconciliation.hash_compare``).
        category: Top-level category (e.g. ``reconciliation``).
        description: Human-readable description.
        required_params: List of required parameter names.
        optional_params: Dict of optional param names to defaults.
    """

    name: str = ""
    category: str = ""
    description: str = ""
    required_params: List[str] = []
    optional_params: Dict[str, Any] = {}

    @abstractmethod
    def validate(self, params: Dict[str, Any]) -> Dict[str, Any]:
        """Validate and normalize input parameters.

        Args:
            params: Raw parameters from the caller.

        Returns:
            Normalized parameters ready for execution.

        Raises:
            sdk.core.exceptions.ValidationError: On invalid input.
        """

    @abstractmethod
    def execute(
        self, params: Dict[str, Any], ctx: Optional[SDKContext] = None
    ) -> Result:
        """Execute the workflow.

        Args:
            params: Validated parameters.
            ctx: SDK context (config, audit, connection).

        Returns:
            Result with step outcomes and summary.
        """

    @abstractmethod
    def compile_to_snowflake(
        self, params: Dict[str, Any], ctx: Optional[SDKContext] = None
    ) -> List[CompiledArtifact]:
        """Compile the workflow into Snowflake native objects.

        Args:
            params: Validated parameters.
            ctx: SDK context with Snowflake connection config.

        Returns:
            List of compiled artifacts (DDL statements).
        """

    def _check_required(self, params: Dict[str, Any]) -> None:
        """Helper to verify required parameters are present."""
        from databridge_core.sdk.core.exceptions import ValidationError

        missing = [p for p in self.required_params if p not in params]
        if missing:
            raise ValidationError(
                f"{self.name}: missing required parameters: {missing}"
            )

    def _apply_defaults(self, params: Dict[str, Any]) -> Dict[str, Any]:
        """Apply default values for optional parameters."""
        merged = dict(self.optional_params)
        merged.update(params)
        return merged
