from kalbee.modules.filters.base import BaseFilter
from kalbee.modules.filters.kf_filter import KalmanFilter
from kalbee.modules.filters.abg_filter import AlphaBetaGammaFilter
from kalbee.modules.filters.ekf_filter import ExtendedKalmanFilter
from kalbee.modules.filters.ukf_filter import UnscentedKalmanFilter
from kalbee.modules.filters.particle_filter import ParticleFilter
from kalbee.modules.filters.enkf_filter import EnsembleKalmanFilter
from kalbee.modules.filters.information_filter import InformationFilter
from kalbee.modules.filters.adaptive_kf import AdaptiveKalmanFilter


class AutoFilter:
    """
    Factory class for creating filter instances.
    """

    @staticmethod
    def from_filter(*args, mode: str = "kalmanfilter", **kwargs) -> BaseFilter:
        """
        Create a filter instance based on the specified mode.

        Args:
            mode: The type of filter to create.
                  Options:
                  - 'kalmanfilter', 'kf', 'kalman'
                  - 'extendedkalmanfilter', 'ekf'
                  - 'unscentedkalmanfilter', 'ukf'
                  - 'alphabetagamma', 'abg'
                  - 'particlefilter', 'pf', 'particle'
                  - 'ensemblekalmanfilter', 'enkf', 'ensemble'
                  - 'informationfilter', 'if', 'information'
                  - 'adaptivekalmanfilter', 'akf', 'adaptive'
            *args: Positional arguments passed to the filter constructor.
            **kwargs: Keyword arguments passed to the filter constructor.

        Returns:
            An instance of a BaseFilter subclass.

        Raises:
            ValueError: If the mode is unknown.
        """
        mode_clean = mode.lower().replace("_", "").replace("-", "")

        if mode_clean in ["kalmanfilter", "kf", "kalman"]:
            return KalmanFilter(*args, **kwargs)

        elif mode_clean in ["extendedkalmanfilter", "ekf"]:
            return ExtendedKalmanFilter(*args, **kwargs)

        elif mode_clean in ["alphabetagamma", "abg"]:
            return AlphaBetaGammaFilter(*args, **kwargs)

        elif mode_clean in ["unscentedkalmanfilter", "ukf"]:
            return UnscentedKalmanFilter(*args, **kwargs)

        elif mode_clean in ["particlefilter", "pf", "particle"]:
            return ParticleFilter(*args, **kwargs)

        elif mode_clean in ["ensemblekalmanfilter", "enkf", "ensemble"]:
            return EnsembleKalmanFilter(*args, **kwargs)

        elif mode_clean in ["informationfilter", "if", "information"]:
            return InformationFilter(*args, **kwargs)

        elif mode_clean in ["adaptivekalmanfilter", "akf", "adaptive"]:
            return AdaptiveKalmanFilter(*args, **kwargs)

        else:
            raise ValueError(
                f"Unknown filter mode: '{mode}'. Available modes: "
                "kf, ekf, ukf, abg, pf, enkf, if, akf."
            )
