from __future__ import annotations

from array_api_compat import array_namespace

from .annotations import Array, DType, Namespace


def cast_to_result_type[T: tuple[Array | None, ...]](
    arrays: T, *arrays_and_dtypes: type[complex | bool] | Array | DType, xp: Namespace | None = None
) -> T:
    """Casts the input arrays to a common data dtype.

    Args:
        arrays: Arrays to be converted (or None).
        arrays_and_dtypes: Extra arrays and types to be passed to result_type.
        xp: The optional namespace.

    Returns:
        The arrays cast to the inferred type.
    """
    if xp is None:
        xp = array_namespace(*arrays)
    dtype = xp.result_type(*arrays, *arrays_and_dtypes)
    return tuple(  # type: ignore
        xp.astype(x, dtype)  # pyright: ignore
        if x is not None
        else None
        for x in arrays
    )
