from typing import Callable, Generator, override

from rxbp.flowabletree.sources.connectable import ConnectableFlowableNode
from rxbp.state import State
from rxbp.flowabletree.observer import Observer
from rxbp.flowabletree.subscriptionresult import SubscriptionResult
from rxbp.flowabletree.nodes import SingleChildFlowableNode

class Flowable[U](SingleChildFlowableNode[U, U]):
    # used for the donotation.do notation
    def __iter__(self) -> Generator[None, None, U]: ...
    def accumulate[V](self, func: Callable[[V, U], V], init: V) -> Flowable[V]: ...
    def buffer(self) -> Flowable[U]: ...
    def copy(self, /, **changes) -> Flowable[U]: ...
    def default_if_empty[V](self, value: V) -> Flowable[U | V]: ...
    def filter(self, predicate: Callable[[U], bool]) -> Flowable[U]: ...
    def first(self) -> Flowable[U]: ...
    def flat_map[V](self, func: Callable[[U], Flowable[V]]) -> Flowable[V]: ...
    def last(self) -> Flowable[U]: ...
    def map[V](self, func: Callable[[U], V]) -> Flowable[V]: ...
    def repeat(self, count: int | None) -> Flowable[U]: ...
    def reduce(self, func: Callable[[U, U], U]) -> Flowable[U]: ...
    def repeat_first(self) -> Flowable[U]: ...
    def share(self) -> Flowable[U]: ...
    def skip(self, count: int) -> Flowable[U]: ...
    def skip_while(self, predicate: Callable[[U], bool]) -> Flowable[U]: ...
    def take(self, count: int) -> Flowable[U]: ...
    def take_while(self, predicate: Callable[[U], bool]) -> Flowable[U]: ...
    def tap(
        self,
        on_next: Callable[[U], None] | None = None,
        on_next_and_completed: Callable[[U], None] | None = None,
        on_completed: Callable[[], None] | None = None,
        on_error: Callable[[Exception], None] | None = None,
    ) -> Flowable[U]: ...
    def to_list(self) -> Flowable[list[U]]: ...
    def zip(self, others: tuple[Flowable[U], ...]) -> Flowable[tuple[U, ...]]: ...
    def zip_with_index(self) -> Flowable[tuple[U, int]]: ...
    @override
    def unsafe_subscribe(
        self, state: State, observer: Observer[U]
    ) -> tuple[State, SubscriptionResult]: ...

class ConnectableFlowable[U](Flowable[U]):
    @property
    def child(self) -> ConnectableFlowableNode[U]: ...
