use crate::{
    config::{get_open_file_path, set_open_file_path},
    database::store_diff,
    get_basepath,
};
use diff_match_patch_rs::{Compat, DiffMatchPatch, Error, PatchInput};
use std::path::Path;
use std::{fs::read_to_string, path::PathBuf};
use tauri::{ipc::RuntimeCapability, App, AssetResolver, Manager, Url};

fn compare_content(old_content: &str, new_content: &str) -> Result<String, Error> {
    // initializing the module
    let dmp = DiffMatchPatch::new();
    // create a list of diffs
    let diffs = dmp.diff_main::<Compat>(old_content, new_content)?;
    // Now, we are going to create a list of `patches` to be applied to the old text to get the new text
    let patches = dmp.patch_make(PatchInput::new_diffs(&diffs))?;
    // in the real world you are going to transmit or store this diff serialized to undiff format to be consumed or used somewhere elese
    let patch_txt = dmp.patch_to_text(&patches);

    Ok(patch_txt)
}

#[tauri::command]
pub async fn save_file(app_handle: tauri::AppHandle, content: String) -> Result<(), String> {
    if let Some(path) = get_open_file_path(app_handle.clone()) {
        if let Ok(file_content) = load_file(app_handle.clone(), &path).await {
            println!(
                "{:?}",
                store_diff(
                    &app_handle,
                    &path.clone(),
                    &PathBuf::from(path).file_name().unwrap().to_string_lossy(),
                    compare_content(&file_content, &content).map_err(|e| format!("{e:?}"))?,
                )
                .await
            );
            println!("{:?}", compare_content(&file_content, &content));
        }
    }
    Ok(())
}

#[tauri::command]
pub async fn load_file(app_handle: tauri::AppHandle, path: &str) -> Result<String, String> {
    set_open_file_path(app_handle, path);
    read_to_string(path).map_err(|e| e.to_string())
}
