use napi::bindgen_prelude;
use napi::bindgen_prelude::JsObjectValue;

use super::macros::{
    namespace_event_handler, namespace_field_getter, namespace_function, register_provider,
};
use super::{
    DecorationRenderOptions, FileDecorationProvider, TextEditor, TextEditorDecorationType,
    TextEditorSelectionChangeEvent,
};

namespace_event_handler! {
    "window" {
        "onDidChangeTextEditorSelection": on_did_change_text_editor_selections(TextEditorSelectionChangeEvent);
        "onDidChangeVisibleTextEditors": on_did_change_visible_text_editors(Vec<TextEditor>);
    }
}

namespace_field_getter! {
    "window" {
        "activeTextEditor": get_active_text_editor -> Option<TextEditor<'env>>;
        "visibleTextEditors": get_visible_text_editors -> Vec<TextEditor<'env>>;
    }
}

namespace_function! {
    "window" {
        "createTextEditorDecorationType":
            create_text_editor_decoration_type(
                render_options: DecorationRenderOptions,
            ) -> TextEditorDecorationType<'env>;
    }
}

register_provider!("window", "registerFileDecorationProvider", register_file_decoration_provider(provider: FileDecorationProvider));

pub fn create_log_output_channel<'env>(
    env: &napi::Env,
    name: &str,
) -> Result<bindgen_prelude::Object<'env>, napi::Error> {
    let vscode_object = super::VscodeContext::vscode(env)?;
    let window: bindgen_prelude::Object = vscode_object.get_named_property("window")?;

    let function_prototype: bindgen_prelude::Function<
        bindgen_prelude::FnArgs<(&str, bindgen_prelude::Object)>,
        bindgen_prelude::Object,
    > = window.get_named_property("createOutputChannel")?;

    let mut options = bindgen_prelude::Object::new(env)?;
    options.set_named_property("log", true)?;

    let output_channel =
        function_prototype.apply(window, bindgen_prelude::FnArgs::from((name, options)))?;

    Ok(output_channel)
}