from typing import Any, ClassVar, Literal
from typing_extensions import Self

from numpy import ndarray
from numpy.random import RandomState

from .._typing import ArrayLike, Float, Int, MatrixLike
from ..base import BaseEstimator
from ._base import MissingIndicator, SimpleImputer, _BaseImputer

_ImputerTriplet = ...

class IterativeImputer(_BaseImputer):
    random_state_: RandomState = ...
    indicator_: MissingIndicator = ...
    n_features_with_missing_: int = ...
    feature_names_in_: ndarray = ...
    n_features_in_: int = ...
    n_iter_: int = ...
    imputation_sequence_: list[tuple] = ...
    initial_imputer_: SimpleImputer = ...

    _parameter_constraints: ClassVar[dict] = ...

    def __init__(
        self,
        estimator: None | BaseEstimator = None,
        *,
        missing_values: float = ...,
        sample_posterior: bool = False,
        max_iter: Int = 10,
        tol: Float = 1e-3,
        n_nearest_features: None | Int = None,
        initial_strategy: Literal["mean", "median", "most_frequent", "constant"] = "mean",
        imputation_order: Literal["ascending", "descending", "roman", "arabic", "random"] = "ascending",
        skip_complete: bool = False,
        min_value: float | ArrayLike = ...,
        max_value: float | ArrayLike = ...,
        verbose: Int = 0,
        random_state: RandomState | None | Int = None,
        add_indicator: bool = False,
        keep_empty_features: bool = False,
    ) -> None: ...
    def fit_transform(self, X: MatrixLike, y: Any = None) -> ndarray: ...
    def transform(self, X: MatrixLike) -> ndarray: ...
    def fit(self, X: MatrixLike, y: Any = None) -> Self: ...
    def get_feature_names_out(self, input_features: None | ArrayLike = None) -> ndarray: ...
