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_app::ViewProviderMarker;
use fidl_fuchsia_ui_gfx::{ExportToken, ImportToken};
use fidl_fuchsia_ui_viewsv1::{CustomFocusBehavior, ViewLayout, ViewProperties};
use fuchsia_app::client::{App, Launcher};
use fuchsia_async as fasync;
use fuchsia_scenic::{EntityNode, ImportNode, SessionPtr};
use fuchsia_zircon as zx;
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 (import, export) = zx::EventPair::create()?;
        let view_holder_token = ImportToken { value: import };
        let view_token = ExportToken { value: export };
        view_provider.create_view(view_token.value, None, None)?;
        let host_node = EntityNode::new(session.clone());
        let host_import_token = host_node.export_as_request();

        view_container.add_child2(key, view_holder_token.value, host_import_token)?;
        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()?
                .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> {
        // TODO: add correct scenic focusing call here
        println!("Want to 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,
    ) -> Result<(), Error> {
        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)))?;
        self.host_node.set_translation(x_inset, y_inset, 10.0);

        Ok(())
    }
}
