#include "search.h"
#include <set>
#include <map>
#include <numeric>

std::vector<std::string_view> Search(std::string_view text, std::string_view query, size_t results_count) {

    auto split_to_words = [&](std::string_view line) {
        std::vector<std::string_view> line_tokens;
        ssize_t first_alpha_pos = -1;

        for (ssize_t i = 0; i < line.size(); i++) {
            if (isalpha(line[i])) {
                if (first_alpha_pos == -1) {
                    first_alpha_pos = i;
                }
            } else {
                if (first_alpha_pos != -1) {
                    line_tokens.emplace_back(line.substr(first_alpha_pos, i - first_alpha_pos));
                    first_alpha_pos = -1;
                }
            }
        }

        if (first_alpha_pos != -1) {
            line_tokens.emplace_back(line.substr(first_alpha_pos, line.size() - first_alpha_pos));
        }

        return line_tokens;
    };

    const auto less_without_case = [&](const std::string_view& a, const std::string_view& b) {
        if (a.size() != b.size()) {
            return a.size() < b.size();
        }

        for (size_t i = 0; i < a.size(); i++) {
            if (tolower(a[i]) != tolower(b[i])) {
                return tolower(a[i]) < tolower(b[i]);
            }
        }

        return true;
    };

    std::vector<std::string_view> lines;
    size_t start_pos = 0;
    for (size_t i = 0; i < text.size(); i++) {
        if (text[i] == '\n') {
            lines.emplace_back(text.substr(start_pos, i - start_pos));
            start_pos = i + 1;
        }
    }
    lines.emplace_back(text.substr(start_pos, text.size() - start_pos));

    std::vector<std::string_view> query_tokens = split_to_words(query);
    std::set<std::string_view, decltype(less_without_case)> query_words(less_without_case);

    for (const auto& query_word : query_tokens) {
        query_words.insert(query_word);
    }

    std::map<std::string_view, bool, decltype(less_without_case)> lines_count_by_word(less_without_case);
    std::vector<std::map<std::string_view, int32_t, decltype(less_without_case)>> word_count_in_line(lines.size());
    std::vector<size_t> words_count_in_line(lines.size());

    for (size_t i = 0; i < lines.size(); i++) {
        std::vector<std::string_view> words_in_line = split_to_words(lines[i]);
        words_count_in_line[i] = words_in_line.size();
        for (const auto& word : words_in_line) {
            if (query_words.contains(word)) {
                lines_count_by_word[word] = true;
                word_count_in_line[i][word]++;
            }
        }
    }

    std::vector<double> metrics(lines.size());
    for (size_t i = 0; i < lines.size(); i++) {
        for (const auto& [word, count] : word_count_in_line[i]) {
            metrics[i] += (static_cast<double>(count) / static_cast<double>(words_count_in_line[i])) *
                          std::log(static_cast<double>(lines.size()) / lines_count_by_word[word]);
        }
    }

    std::vector<size_t> order(lines.size());
    std::iota(order.begin(), order.end(), 0);

    std::ranges::sort(order.begin(), order.end(), [&metrics](size_t i, size_t j) {
        if (metrics[i] == metrics[j]) {
            return metrics[i] > metrics[j];
        }

        return i < j;
    });

//

    size_t relevant = 0;
    for (size_t i = 0; i < lines.size(); ++i) {
        if (metrics[order[i]] > 0.0) {
            ++relevant;
        } else {
            break;
        }
    }

    if (results_count > relevant) {
        results_count = relevant;
    }

    std::vector<std::string_view> result(results_count);
    for (size_t i = 0; i < results_count; ++i) {
        result[i] = lines[order[i]];
    }
    return result;
}
выдаёт ошибку error: no matching constructor for initialization of 'key_compare' (aka 'const (lambda at /Users/mihailledenev/ami-Mikhail-Ledenev-led_dev/tasks/search/search.cpp:32:36)')
        : __tree_(__vc(key_compare())) {}