use dioxus_core::fc_to_builder;
use dioxus_core::Element;
use dioxus_core::VirtualDom;
use dioxus_core_macro::rsx;
use freya_common::EventMessage;
use freya_core::prelude::*;
use freya_dom::prelude::{FreyaDOM, SafeDOM};
use freya_engine::prelude::*;
use freya_hooks::{use_init_accessibility, PlatformInformation};
use std::sync::{Arc, Mutex};
use tokio::sync::broadcast;
use tokio::sync::mpsc::unbounded_channel;
use winit::window::CursorIcon;
use crate::config::TestingConfig;
use crate::test_handler::TestingHandler;
use crate::test_utils::TestUtils;
pub fn launch_test(root: AppComponent) -> TestingHandler {
    launch_test_with_config(root, TestingConfig::default())
}
pub fn launch_test_with_config(root: AppComponent, config: TestingConfig) -> TestingHandler {
    let vdom = with_accessibility(root);
    let fdom = FreyaDOM::default();
    let sdom = SafeDOM::new(fdom);
    let (event_emitter, event_receiver) = unbounded_channel::<DomEvent>();
    let (platform_event_emitter, platform_event_receiver) = unbounded_channel::<EventMessage>();
    let layers = Arc::default();
    let viewports = Arc::default();
    let mut font_collection = FontCollection::new();
    font_collection.set_dynamic_font_manager(FontMgr::default());
    let mut handler = TestingHandler {
        vdom,
        events_queue: EventsQueue::new(),
        nodes_state: NodesState::default(),
        font_collection,
        event_emitter,
        event_receiver,
        utils: TestUtils {
            sdom,
            layers,
            viewports,
        },
        config,
        platform_event_emitter,
        platform_event_receiver,
        accessibility_manager: AccessibilityManager::new(ACCESSIBILITY_ROOT_ID).wrap(),
        ticker_sender: broadcast::channel(5).0,
        navigation_state: NavigatorState::new(NavigationMode::NotKeyboard),
        platform_information: Arc::new(Mutex::new(PlatformInformation::new(config.size))),
        cursor_icon: CursorIcon::default(),
    };
    handler.init_dom();
    handler
}
fn with_accessibility(app: AppComponent) -> VirtualDom {
    #[derive(Clone)]
    struct RootProps {
        app: AppComponent,
    }
    #[allow(non_snake_case)]
    fn Root(props: RootProps) -> Element {
        use_init_accessibility();
        #[allow(non_snake_case)]
        let App = props.app;
        rsx!(App {})
    }
    VirtualDom::new_with_props(Root, RootProps { app })
}
type AppComponent = fn() -> Element;