use crate::{
	dictionary,
	utils::{self, AlphabeticalKey, ErrorCandidate},
};
use itertools::Itertools;
use std::{collections::BTreeMap, range::Range};

pub(crate) fn get_error_candidates<'text>(
	dict: &dictionary::Dictionary,
	txt_file: &'text str,
) -> impl Iterator<Item = ErrorCandidate<'text>> {
	let utils::UnicodeData { ref segmenter } = utils::UNICODE_DATA;

	let mut mistakes = BTreeMap::<AlphabeticalKey, Vec<Range<usize>>>::new();

	let words = segmenter.as_borrowed().segment_str(txt_file).tuple_windows().filter_map(
		|(s, e)| {
			let range = (s..e).into();
			let text: &str = &txt_file[range];

			Some((text, range)).filter(|s| !s.0.trim().is_empty())
		},
	);

	for (word, r) in words {
		let Some(_) = word.chars().find(|c| c.is_alphabetic()) else {
			continue;
		};

		if !dict.check(word) {
			mistakes.entry(AlphabeticalKey(word)).or_default().push(r);
		}
	}

	mistakes.into_iter()
		.map(move |(AlphabeticalKey(word), ranges)| ErrorCandidate::new(word, ranges))
}
