"""
This type stub file was generated by pyright.
"""

import numpy as np
from typing import Any, Callable, Literal, Sequence, TYPE_CHECKING, TypeVar, Union, overload
from pandas._libs.tslibs import BaseOffset, NaTType
from pandas._typing import ArrayLike, DatetimeLikeScalar, Dtype, DtypeObj, NpDtype, PositionalIndexer2D, PositionalIndexerTuple, ScalarIndexer, SequenceIndexer, npt
from pandas.util._decorators import Appender, Substitution
from pandas.core.dtypes.dtypes import DatetimeTZDtype
from pandas.core.arraylike import OpsMixin
from pandas.core.arrays._mixins import NDArrayBackedExtensionArray, ravel_compat
from pandas.core.ops.common import unpack_zerodim_and_defer
from pandas.core.arrays import DatetimeArray, TimedeltaArray

if TYPE_CHECKING:
    ...
DTScalarOrNaT = Union[DatetimeLikeScalar, NaTType]
DatetimeLikeArrayT = TypeVar("DatetimeLikeArrayT", bound="DatetimeLikeArrayMixin")
class InvalidComparison(Exception):
    """
    Raised by _validate_comparison_value to indicate to caller it should
    return invalid_comparison.
    """
    ...


class DatetimeLikeArrayMixin(OpsMixin, NDArrayBackedExtensionArray):
    """
    Shared Base/Mixin class for DatetimeArray, TimedeltaArray, PeriodArray

    Assumes that __new__/__init__ defines:
        _data
        _freq

    and that the inheriting class has methods:
        _generate_range
    """
    _infer_matches: tuple[str, ...]
    _is_recognized_dtype: Callable[[DtypeObj], bool]
    _recognized_scalars: tuple[type, ...]
    _ndarray: np.ndarray
    def __init__(self, data, dtype: Dtype | None = ..., freq=..., copy=...) -> None:
        ...
    
    def __iter__(self): # -> Generator[DTScalarOrNaT, None, None]:
        ...
    
    @property
    def asi8(self) -> npt.NDArray[np.int64]:
        """
        Integer representation of the values.

        Returns
        -------
        ndarray
            An ndarray with int64 dtype.
        """
        ...
    
    def __array__(self, dtype: NpDtype | None = ...) -> np.ndarray:
        ...
    
    @overload
    def __getitem__(self, item: ScalarIndexer) -> DTScalarOrNaT:
        ...
    
    @overload
    def __getitem__(self: DatetimeLikeArrayT, item: SequenceIndexer | PositionalIndexerTuple) -> DatetimeLikeArrayT:
        ...
    
    def __getitem__(self: DatetimeLikeArrayT, key: PositionalIndexer2D) -> DatetimeLikeArrayT | DTScalarOrNaT:
        """
        This getitem defers to the underlying array, which by-definition can
        only handle list-likes, slices, and integer scalars
        """
        ...
    
    def __setitem__(self, key: int | Sequence[int] | Sequence[bool] | slice, value: NaTType | Any | Sequence[Any]) -> None:
        ...
    
    def astype(self, dtype, copy: bool = ...): # -> NDArray[object_] | ndarray[Any, Unknown] | ExtensionArray | NDArray[Any] | NDArray[int64] | NDArray[Unknown]:
        ...
    
    @overload
    def view(self: DatetimeLikeArrayT) -> DatetimeLikeArrayT:
        ...
    
    @overload
    def view(self, dtype: Literal["M8[ns]"]) -> DatetimeArray:
        ...
    
    @overload
    def view(self, dtype: Literal["m8[ns]"]) -> TimedeltaArray:
        ...
    
    @overload
    def view(self, dtype: Dtype | None = ...) -> ArrayLike:
        ...
    
    def view(self, dtype: Dtype | None = ...) -> ArrayLike:
        ...
    
    def copy(self: DatetimeLikeArrayT, order=...) -> DatetimeLikeArrayT:
        ...
    
    @ravel_compat
    def map(self, mapper): # -> ExtensionArray:
        ...
    
    def isin(self, values) -> npt.NDArray[np.bool_]:
        """
        Compute boolean array of whether each value is found in the
        passed set of values.

        Parameters
        ----------
        values : set or sequence of values

        Returns
        -------
        ndarray[bool]
        """
        ...
    
    def isna(self) -> npt.NDArray[np.bool_]:
        ...
    
    @property
    def freq(self): # -> None:
        """
        Return the frequency object if it is set, otherwise None.
        """
        ...
    
    @freq.setter
    def freq(self, value) -> None:
        ...
    
    @property
    def freqstr(self) -> str | None:
        """
        Return the frequency object as a string if its set, otherwise None.
        """
        ...
    
    @property
    def inferred_freq(self) -> str | None:
        """
        Tries to return a string representing a frequency generated by infer_freq.

        Returns None if it can't autodetect the frequency.
        """
        ...
    
    @property
    def resolution(self) -> str:
        """
        Returns day, hour, minute, second, millisecond or microsecond
        """
        ...
    
    __pow__ = ...
    __rpow__ = ...
    __mul__ = ...
    __rmul__ = ...
    __truediv__ = ...
    __rtruediv__ = ...
    __floordiv__ = ...
    __rfloordiv__ = ...
    __mod__ = ...
    __rmod__ = ...
    __divmod__ = ...
    __rdivmod__ = ...
    @unpack_zerodim_and_defer("__add__")
    def __add__(self, other): # -> DatetimeArray | _NotImplementedType | TimedeltaArray | PeriodArray | Self@DatetimeLikeArrayMixin | Any | ndarray[Any, Unknown]:
        ...
    
    def __radd__(self, other): # -> DatetimeArray | _NotImplementedType | TimedeltaArray | PeriodArray | Self@DatetimeLikeArrayMixin | Any | ndarray[Any, Unknown]:
        ...
    
    @unpack_zerodim_and_defer("__sub__")
    def __sub__(self, other): # -> _NotImplementedType | PeriodArray | Self@DatetimeLikeArrayMixin | Any | NDArray[Any] | NDArray[object_] | ndarray[Any, Unknown]:
        ...
    
    def __rsub__(self, other): # -> _NotImplementedType | PeriodArray | DatetimeArray | Any | NDArray[Any] | NDArray[object_] | ndarray[Any, Unknown] | DatetimeLikeArrayMixin:
        ...
    
    def __iadd__(self: DatetimeLikeArrayT, other) -> DatetimeLikeArrayT:
        ...
    
    def __isub__(self: DatetimeLikeArrayT, other) -> DatetimeLikeArrayT:
        ...
    
    def min(self, *, axis: int | None = ..., skipna: bool = ..., **kwargs): # -> NaTType:
        """
        Return the minimum value of the Array or minimum along
        an axis.

        See Also
        --------
        numpy.ndarray.min
        Index.min : Return the minimum value in an Index.
        Series.min : Return the minimum value in a Series.
        """
        ...
    
    def max(self, *, axis: int | None = ..., skipna: bool = ..., **kwargs): # -> Dtype | Type[str]:
        """
        Return the maximum value of the Array or maximum along
        an axis.

        See Also
        --------
        numpy.ndarray.max
        Index.max : Return the maximum value in an Index.
        Series.max : Return the maximum value in a Series.
        """
        ...
    
    def mean(self, *, skipna: bool = ..., axis: int | None = ...):
        """
        Return the mean value of the Array.

        .. versionadded:: 0.25.0

        Parameters
        ----------
        skipna : bool, default True
            Whether to ignore any NaT elements.
        axis : int, optional, default 0

        Returns
        -------
        scalar
            Timestamp or Timedelta.

        See Also
        --------
        numpy.ndarray.mean : Returns the average of array elements along a given axis.
        Series.mean : Return the mean value in a Series.

        Notes
        -----
        mean is only defined for Datetime and Timedelta dtypes, not for Period.
        """
        ...
    
    def median(self, *, axis: int | None = ..., skipna: bool = ..., **kwargs):
        ...
    


class DatelikeOps(DatetimeLikeArrayMixin):
    """
    Common ops for DatetimeIndex/PeriodIndex, but not TimedeltaIndex.
    """
    @Substitution(URL="https://docs.python.org/3/library/datetime.html" "#strftime-and-strptime-behavior")
    def strftime(self, date_format: str) -> npt.NDArray[np.object_]:
        """
        Convert to Index using specified date_format.

        Return an Index of formatted strings specified by date_format, which
        supports the same string format as the python standard library. Details
        of the string format can be found in `python string format
        doc <%(URL)s>`__.

        Formats supported by the C `strftime` API but not by the python string format
        doc (such as `"%%R"`, `"%%r"`) are not officially supported and should be
        preferably replaced with their supported equivalents (such as `"%%H:%%M"`,
        `"%%I:%%M:%%S %%p"`).

        Note that `PeriodIndex` support additional directives, detailed in
        `Period.strftime`.

        Parameters
        ----------
        date_format : str
            Date format string (e.g. "%%Y-%%m-%%d").

        Returns
        -------
        ndarray[object]
            NumPy ndarray of formatted strings.

        See Also
        --------
        to_datetime : Convert the given argument to datetime.
        DatetimeIndex.normalize : Return DatetimeIndex with times to midnight.
        DatetimeIndex.round : Round the DatetimeIndex to the specified freq.
        DatetimeIndex.floor : Floor the DatetimeIndex to the specified freq.
        Timestamp.strftime : Format a single Timestamp.
        Period.strftime : Format a single Period.

        Examples
        --------
        >>> rng = pd.date_range(pd.Timestamp("2018-03-10 09:00"),
        ...                     periods=3, freq='s')
        >>> rng.strftime('%%B %%d, %%Y, %%r')
        Index(['March 10, 2018, 09:00:00 AM', 'March 10, 2018, 09:00:01 AM',
               'March 10, 2018, 09:00:02 AM'],
              dtype='object')
        """
        ...
    


_round_doc = ...
_round_example = ...
_floor_example = ...
_ceil_example = ...
TimelikeOpsT = TypeVar("TimelikeOpsT", bound="TimelikeOps")
class TimelikeOps(DatetimeLikeArrayMixin):
    """
    Common ops for TimedeltaIndex/DatetimeIndex, but not PeriodIndex.
    """
    _default_dtype: np.dtype
    def __init__(self, values, dtype=..., freq=..., copy: bool = ...) -> None:
        ...
    
    def __array_ufunc__(self, ufunc: np.ufunc, method: str, *inputs, **kwargs): # -> Any | _NotImplementedType | tuple[Unknown, ...]:
        ...
    
    @Appender((_round_doc + _round_example).format(op="round"))
    def round(self, freq, ambiguous=..., nonexistent=...):
        ...
    
    @Appender((_round_doc + _floor_example).format(op="floor"))
    def floor(self, freq, ambiguous=..., nonexistent=...):
        ...
    
    @Appender((_round_doc + _ceil_example).format(op="ceil"))
    def ceil(self, freq, ambiguous=..., nonexistent=...):
        ...
    
    def any(self, *, axis: int | None = ..., skipna: bool = ...) -> bool:
        ...
    
    def all(self, *, axis: int | None = ..., skipna: bool = ...) -> bool:
        ...
    
    def factorize(self, na_sentinel: int = ..., sort: bool = ...): # -> tuple[ndarray[Any, dtype[intp]], TimelikeOps | Self@TimelikeOps] | tuple[ndarray[Unknown, Unknown], ExtensionArray]:
        ...
    


def ensure_arraylike_for_datetimelike(data, copy: bool, cls_name: str): # -> tuple[ArrayLike | NDArray[Unknown], bool]:
    ...

@overload
def validate_periods(periods: None) -> None:
    ...

@overload
def validate_periods(periods: float) -> int:
    ...

def validate_periods(periods: float | None) -> int | None:
    """
    If a `periods` argument is passed to the Datetime/Timedelta Array/Index
    constructor, cast it to an integer.

    Parameters
    ----------
    periods : None, float, int

    Returns
    -------
    periods : None or int

    Raises
    ------
    TypeError
        if periods is None, float, or int
    """
    ...

def validate_inferred_freq(freq, inferred_freq, freq_infer) -> tuple[BaseOffset | None, bool]:
    """
    If the user passes a freq and another freq is inferred from passed data,
    require that they match.

    Parameters
    ----------
    freq : DateOffset or None
    inferred_freq : DateOffset or None
    freq_infer : bool

    Returns
    -------
    freq : DateOffset or None
    freq_infer : bool

    Notes
    -----
    We assume at this point that `maybe_infer_freq` has been called, so
    `freq` is either a DateOffset object or None.
    """
    ...

def maybe_infer_freq(freq): # -> tuple[BaseOffset | None, bool]:
    """
    Comparing a DateOffset to the string "infer" raises, so we need to
    be careful about comparisons.  Make a dummy variable `freq_infer` to
    signify the case where the given freq is "infer" and set freq to None
    to avoid comparison trouble later on.

    Parameters
    ----------
    freq : {DateOffset, None, str}

    Returns
    -------
    freq : {DateOffset, None}
    freq_infer : bool
        Whether we should inherit the freq of passed data.
    """
    ...

def dtype_to_unit(dtype: DatetimeTZDtype | np.dtype) -> str:
    """
    Return the unit str corresponding to the dtype's resolution.

    Parameters
    ----------
    dtype : DatetimeTZDtype or np.dtype
        If np.dtype, we assume it is a datetime64 dtype.

    Returns
    -------
    str
    """
    ...

