use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher};
use html_tag::HtmlTag;
use std::{
    fs::{self, DirEntry},
    path::Path,
};

#[tauri::command]
pub fn search_files(basepath: &str, searchstring: &str, filter: Vec<String>) -> Vec<String> {
    match shellexpand::full(basepath) {
        Ok(path) => _search_files(&Path::new(&path.into_owned()), searchstring, &filter),

        Err(_) => Vec::new(),
    }
}
pub fn _search_files(path: &Path, searchstring: &str, filter: &Vec<String>) -> Vec<String> {
    let mut search_results: Vec<String> = Vec::new();
    if let Ok(entries) = fs::read_dir(path) {
        for dir_entry_res in entries {
            if let Ok(dir_entry) = dir_entry_res {
                if let Ok(metadata) = fs::metadata(dir_entry.path()) {
                    if metadata.is_file() {
                        if entry_match(&dir_entry, searchstring, filter) {
                            let div = search_result_div_from_dir_entry(&dir_entry).to_html();
                            // println!("{:?}", div);
                            search_results.push(div);
                        }
                    } else if metadata.is_dir() {
                        search_results.append(&mut _search_files(
                            &dir_entry.path(),
                            searchstring,
                            &filter,
                        ));
                    }
                }
            }
        }
    }
    println!("{:?}", search_results);
    return search_results;
}
fn entry_match(dir_entry: &DirEntry, searchstring: &str, filter: &Vec<String>) -> bool {
    if filter.contains(
        &dir_entry
            .path()
            .extension()
            .unwrap_or_default()
            .to_string_lossy()
            .to_string(),
    ) {
        let matcher = SkimMatcherV2::default();
        let search_match: Option<i64> =
            matcher.fuzzy_match(&dir_entry.file_name().to_string_lossy(), searchstring);
        // debug!(
        //     "{} = {} : {:?}",
        //     search_str, &application.name, search_match
        // );
        if let Some(score) = search_match {
            return true;
        }
        // self.matches.sort_by(|a, b| b.1.cmp(&a.1));
    }
    return false;
}

fn search_result_div_from_dir_entry(dir_entry: &DirEntry) -> HtmlTag {
    let mut file_div = HtmlTag::new("div")
        .with_class("filetree-node")
        .with_id(&format!("{}", dir_entry.path().to_string_lossy()));
    let mut file_button = HtmlTag::new("button").with_class("file-search-button");
    match dir_entry
        .path()
        .extension()
        .unwrap_or_default()
        .to_string_lossy()
        .to_string()
        .as_str()
    {
        "md" => file_button.add_child(
            HtmlTag::new("img")
                .with_class("filetree-icon")
                .with_attribute("src", "images/markdown.svg"),
        ),

        _ => file_button.add_child(
            HtmlTag::new("img")
                .with_class("filetree-icon")
                .with_attribute("src", "images/file.svg"),
        ),
    };

    file_button.add_child(HtmlTag::new("a").with_body(&dir_entry.file_name().to_string_lossy()));
    file_div.add_child(file_button);
    return file_div;
}
