use std::rc::Rc;

use iri_string::types::UriAbsoluteString;

use crate::event_loop::ExtensionState;
use crate::event_loop::js_function::Functions;
use crate::vscode_sys;

#[tracing::instrument(skip(text_editor_reference, extension_state, js_functions))]
pub async fn handle(
    uri: UriAbsoluteString,
    text_editor_reference: vscode_sys::reference::TextEditorRef,
    extension_state: &mut ExtensionState,
    js_functions: &Functions,
) {
    let Some((repository_path, relative_path, repository)) =
        extension_state.get_repository_mut(&uri)
    else {
        // TODO: keep track of unassigned text editors in case they later become part of a repository
        tracing::info!(message = "Ignoring text editor");
        return;
    };

    if repository.open_editors.contains_key(relative_path) {
        tracing::debug!(
            message = "Ignoring existing text editor",
            ?repository_path,
            ?relative_path
        );
    } else {
        let text_editor = Rc::new(text_editor_reference);

        let editor_contents = match js_functions.get_text_editor_contents(&text_editor).await {
            Ok(contents) => contents,
            Err(error) => {
                tracing::error!(message = "Failed to get text editor contents", ?error);
                return;
            }
        };

        if let Err(error) = repository
            .repository
            .create_open_file(relative_path.to_path_buf(), editor_contents)
        {
            tracing::error!(message = "Failed to create open file", ?error);
        };

        repository
            .open_editors
            .insert(relative_path.to_path_buf(), text_editor);

        tracing::info!(
            message = "Opened new text editor",
            ?repository_path,
            ?relative_path
        );
    }
}