"""Base abstractions for NeuroWeave encoding models."""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from .base_estimator import BaseEstimator
    from .result import EncodingResult


class BaseEncodingModel(ABC):
    """Base class for all NeuroWeave encoding models.

    Encoding models define how stimulus features are mapped to neural
    responses across time. Concrete subclasses may construct design
    matrices, delegate parameter estimation to estimators, and return
    structured result objects.

    Parameters
    ----------
    **params : Any
        Model configuration parameters stored by the base class.
    """

    def __init__(self, **params: Any) -> None:
        self._params = dict(params)

    @abstractmethod
    def fit(
        self,
        X: Any,
        y: Any,
        estimator: BaseEstimator | None = None,
    ) -> EncodingResult:
        """Fit the encoding model.

        Parameters
        ----------
        X : Any
            Design matrix or feature representation.
        y : Any
            Neural response targets.
        estimator : BaseEstimator | None, optional
            Estimator used to solve model parameters.

        Returns
        -------
        EncodingResult
            Result object for the fitted encoding model.
        """

        raise NotImplementedError()

    @abstractmethod
    def predict(self, X: Any) -> EncodingResult:
        """Generate predictions from the encoding model.

        Parameters
        ----------
        X : Any
            Design matrix or feature representation.

        Returns
        -------
        EncodingResult
            Result object containing prediction outputs.
        """

        raise NotImplementedError()

    @abstractmethod
    def score(self, X: Any, y: Any) -> EncodingResult:
        """Score the encoding model.

        Parameters
        ----------
        X : Any
            Design matrix or feature representation.
        y : Any
            Neural response targets.

        Returns
        -------
        EncodingResult
            Result object containing model evaluation outputs.
        """

        raise NotImplementedError()

    def get_params(self) -> dict[str, Any]:
        """Return model parameters.

        Returns
        -------
        dict[str, Any]
            Mapping of parameter names to values.
        """

        raise NotImplementedError()

    def set_params(self, **params: Any) -> BaseEncodingModel:
        """Set model parameters.

        Parameters
        ----------
        **params : Any
            Parameter names and values to update.

        Returns
        -------
        BaseEncodingModel
            The model instance.
        """

        raise NotImplementedError()
