use crate::APP;
use failure::Error;
use fidl::encoding::OutOfLine;
use fidl::endpoints::create_endpoints;
use fidl_fuchsia_math::{InsetF, SizeF};
use fidl_fuchsia_textinputmod::{TextInputModMarker, TextInputModProxy, TextInputModReceiverMarker,
                                TextInputModReceiverRequest};
use fidl_fuchsia_ui_viewsv1::{CustomFocusBehavior, ViewLayout, ViewProperties, ViewProviderMarker};
use fidl_fuchsia_ui_viewsv1token::ViewOwnerMarker;
use fuchsia_app::client::{App, Launcher};
use fuchsia_async as fasync;
use fuchsia_scenic::{EntityNode, ImportNode, SessionPtr};
use futures::{TryFutureExt, TryStreamExt};

pub struct AskBox {
    _app: App,
    key: u32,
    pub host_node: EntityNode,
    pub text_input_mod: TextInputModProxy,
}

impl AskBox {
    fn setup_view(
        app: &App, key: u32, session: &SessionPtr,
        view_container: &fidl_fuchsia_ui_viewsv1::ViewContainerProxy, import_node: &ImportNode,
    ) -> Result<EntityNode, Error> {
        let view_provider = app.connect_to_service(ViewProviderMarker)?;
        let (view_owner_client, view_owner_server) = create_endpoints::<ViewOwnerMarker>()?;
        view_provider.create_view(view_owner_server, None)?;
        let host_node = EntityNode::new(session.clone());
        let host_import_token = host_node.export_as_request();

        view_container.add_child(key, view_owner_client, host_import_token)?;
        //view_container.request_focus(key)?;
        import_node.add_child(&host_node);
        Ok(host_node)
    }

    fn setup_text_mod_receiver(app: &App) -> Result<TextInputModProxy, Error> {
        let text_input_mod = app.connect_to_service(TextInputModMarker)?;

        let (text_input_receiver, text_input_receiver_request) =
            create_endpoints::<TextInputModReceiverMarker>()?;

        fasync::spawn(
            text_input_receiver_request
                .into_stream()
                .unwrap()
                .map_ok(move |request| match request {
                    TextInputModReceiverRequest::UserEnteredText { text, responder } => {
                        APP.lock()
                            .handle_suggestion(Some(&text))
                            .unwrap_or_else(|e| eprintln!("handle_suggestion error: {:?}", e));
                        responder
                            .send()
                            .unwrap_or_else(|e| eprintln!("UserEnteredText send failed: {:?}", e));
                    }
                    TextInputModReceiverRequest::UserCanceled { responder } => {
                        APP.lock()
                            .handle_suggestion(None)
                            .unwrap_or_else(|e| eprintln!("handle_suggestion error: {:?}", e));
                        responder
                            .send()
                            .unwrap_or_else(|e| eprintln!("UserCanceled send failed: {:?}", e));
                    }
                })
                .try_collect::<()>()
                .unwrap_or_else(|e| eprintln!("text input receiver error: {:?}", e)),
        );

        let f = text_input_mod.listen_for_text_input(text_input_receiver);
        fasync::spawn(f.unwrap_or_else(|e| eprintln!("listen_for_text_input error: {:?}", e)));

        Ok(text_input_mod)
    }

    pub fn focus(
        &mut self, view_container: &fidl_fuchsia_ui_viewsv1::ViewContainerProxy,
    ) -> Result<(), Error> {
        println!("Want to focus {}", self.key);
        view_container.request_focus(self.key)?;
        Ok(())
    }

    pub fn remove(
        &mut self, view_container: &fidl_fuchsia_ui_viewsv1::ViewContainerProxy,
    ) -> Result<(), Error> {
        view_container.remove_child(self.key, None)?;
        Ok(())
    }

    pub fn new(
        key: u32, session: &SessionPtr,
        view_container: &fidl_fuchsia_ui_viewsv1::ViewContainerProxy, import_node: &ImportNode,
    ) -> Result<AskBox, Error> {
        let app = Launcher::new()?.launch(
            "fuchsia-pkg://fuchsia.com/text_input_mod#meta/text_input_mod.cmx".to_string(),
            None,
        )?;

        let host_node = Self::setup_view(&app, key, session, view_container, import_node)?;
        let text_input_mod = Self::setup_text_mod_receiver(&app)?;

        Ok(AskBox {
            _app: app,
            key,
            host_node,
            text_input_mod,
        })
    }

    pub fn layout(
        &self, view_container: &fidl_fuchsia_ui_viewsv1::ViewContainerProxy, width: f32,
        height: f32,
    ) {
        let x_inset = width * 0.1;
        let y_inset = height * 0.4;
        let mut view_properties = ViewProperties {
            custom_focus_behavior: Some(Box::new(CustomFocusBehavior { allow_focus: true })),
            view_layout: Some(Box::new(ViewLayout {
                inset: InsetF {
                    bottom: 0.0,
                    left: 0.0,
                    right: 0.0,
                    top: 0.0,
                },
                size: SizeF {
                    width: width - 2.0 * x_inset,
                    height: height - 2.0 * y_inset,
                },
            })),
        };
        view_container
            .set_child_properties(self.key, Some(OutOfLine(&mut view_properties)))
            .unwrap();
        self.host_node.set_translation(x_inset, y_inset, 10.0);
    }
}
