import unicodedata


def calculate_score(data, related_sents, print_low_recall=False):
    """Calculates the accuracy scores for the sentence retrieval

    Args:
        data (List[dict]): The FEVEROUS dataset
        related_sents (List[dict]): The results from the sentence retrieval
        print_low_recall (bool, optional): If True, will print the first 10 samples that does not have any matches. Defaults to False.

    Returns:
        Tuple(float, float, List[dict]): A tuple containing the precision, recall and no match samples
    """
    sum_precision = 0
    sum_recall = 0
    counter = 0
    claims_with_sent_evidence = 0
    no_match_samples = []

    for i in range(len(data)):
        evidence_sents = data[i]["evidence"][0]["content"]
        evidence_sents = [sent for sent in evidence_sents if "_sentence_" in sent]
        if len(evidence_sents) == 0:
            continue
        claims_with_sent_evidence += 1
        rel_sents_obj = related_sents[i]
        rel_sents = rel_sents_obj["top_sents"]
        assert (
            rel_sents_obj["id"] == data[i]["id"]
        )  # Make sure that the arrays are in the same order
        nr_of_correct_sents = 0
        for sent in evidence_sents:
            for rel_sent in rel_sents:
                if unicodedata.normalize("NFC", rel_sent) == unicodedata.normalize(
                    "NFC", sent
                ):
                    nr_of_correct_sents += 1
        precision = (nr_of_correct_sents / len(rel_sents)) * 100
        recall = (nr_of_correct_sents / len(evidence_sents)) * 100
        sum_precision += precision
        sum_recall += recall

        if nr_of_correct_sents == 0:
            obj = {
                "claim": data[i]["claim"],
                "evidence_sents": evidence_sents,
                "related_sents": rel_sents,
            }
            no_match_samples.append(obj)

        if print_low_recall and counter < 10 and recall < 30:
            print("Retrieved sentences: {}".format(rel_sents))
            print("Correct sentences: {}".format(evidence_sents))
            print("Precision for nr {}: {}".format(i, precision))
            print("Recall for nr {}: {}".format(i, recall))
            print()
            counter += 1

    precision = sum_precision / claims_with_sent_evidence
    recall = sum_recall / claims_with_sent_evidence

    return precision, recall, no_match_samples