use dioxus::prelude::*;
use dioxus_router::prelude::{
    use_route,
    Routable,
};
#[derive(Clone)]
pub enum AnimatedRouterContext<R: Routable + PartialEq> {
    FromTo(R, R),
    In(R),
}
impl<R: Routable + PartialEq> AnimatedRouterContext<R> {
    pub fn target_route(&self) -> &R {
        match self {
            Self::FromTo(_, to) => to,
            Self::In(to) => to,
        }
    }
    pub fn set_target_route(&mut self, to: R) {
        match self {
            Self::FromTo(old_from, old_to) => {
                *old_from = old_to.clone();
                *old_to = to
            }
            Self::In(old_to) => *self = Self::FromTo(old_to.clone(), to),
        }
    }
    pub fn settle(&mut self) {
        if let Self::FromTo(_, to) = self {
            *self = Self::In(to.clone())
        }
    }
}
#[derive(Props, Clone, PartialEq)]
pub struct AnimatedRouterProps {
    children: Element,
}
#[allow(non_snake_case)]
pub fn AnimatedRouter<R: Routable + PartialEq + Clone>(
    AnimatedRouterProps { children }: AnimatedRouterProps,
) -> Element {
    let route = use_route::<R>();
    let mut prev_route = use_signal(|| AnimatedRouterContext::In(route.clone()));
    use_context_provider(move || prev_route);
    if prev_route.peek().target_route() != &route {
        prev_route.write().set_target_route(route);
    }
    rsx!({ children })
}
pub fn use_animated_router<Route: Routable + PartialEq>() -> Signal<AnimatedRouterContext<Route>> {
    use_context()
}