use std::fs::File;
use std::io;
use std::io::BufRead;

use itertools::Itertools;
use levenshtein::levenshtein;



pub fn sort_string(word: &String) -> String {
    let mut sorted_word = word.trim().to_string();
    sorted_word.make_ascii_lowercase();
    sorted_word = sorted_word.chars().sorted().collect();

    sorted_word
}


pub fn expand_umlauts(word: &str) -> String {
    let mut umlaut_word = String::from(word);

    umlaut_word = umlaut_word.replace('ä', "ae");
    umlaut_word = umlaut_word.replace('ö', "oe");
    umlaut_word = umlaut_word.replace('ü', "ue");
    umlaut_word = umlaut_word.replace('ß', "ss");

    umlaut_word
}


pub fn read_dict_file(filepath: &str) -> Vec<String> {
    let file = File::open(filepath).unwrap();

    let line_reader = io::BufReader::new(file).lines();

    let collected_words: Vec<String> = line_reader.collect::<Result<_, _>>().unwrap();

    collected_words.iter().map(|s| expand_umlauts(s)).collect()
}

pub fn fuzzy_match(lines: &Vec<String>, fuzzy_word: &String) -> Vec<String> {
    let mut matching_words: Vec<String> = Vec::new();

    let mut stripped_word = String::from(fuzzy_word);


    let mut num_wildcards = 0;

    while stripped_word.contains('*') {
        stripped_word.remove(stripped_word.find('*').unwrap());
        num_wildcards += 1;
    }

    for word in lines {
        if fuzzy_word.len() != word.len() {
            continue;
        }

        if levenshtein(&sort_string(&stripped_word), &sort_string(&word)) == num_wildcards {
            matching_words.push(String::from(word));
        }
    }

    matching_words
}
