"""Can the best score tell us that the handbook has no answer?

    python best_scores.py

The search always returns three passages, whatever the question. This prints the
score of the best passage for every test question, the questions the handbook
answers and the ones it does not, each kind from its lowest score up. Then it
tries every score as a line between the two kinds and reports the best line
there is. No language model is used.
"""
import sys
from pathlib import Path

from sentence_transformers import SentenceTransformer

PAGE_FILES = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(PAGE_FILES))
import answer  # noqa: E402  (the page's own file)


def show(title, rows):
    print(title)
    for score, question_text in rows:
        print(f"{score:8.2f}  {question_text}")
    print()


def main():
    passages = answer.read_passages(PAGE_FILES / "handbook.txt")
    questions = answer.read_questions(PAGE_FILES / "questions.jsonl")
    embedder = SentenceTransformer(answer.EMBEDDER)
    passage_vectors = embedder.encode(passages, normalize_embeddings=True)
    with_answer, without = [], []
    for question in questions:
        question_vector = embedder.encode(question["question"], normalize_embeddings=True)
        best = float((passage_vectors @ question_vector).max())
        kind = without if question["answer_in"] is None else with_answer
        kind.append((best, question["question"]))
    with_answer.sort()
    without.sort()
    show(f"The best score for the {len(with_answer)} questions the handbook answers:", with_answer)
    show(f"The best score for the {len(without)} questions it does not answer:", without)

    print(f"with an answer:    from {with_answer[0][0]:.2f} to {with_answer[-1][0]:.2f}")
    print(f"without an answer: from {without[0][0]:.2f} to {without[-1][0]:.2f}")
    below = sum(score < without[-1][0] for score, _ in with_answer)
    print(f"{below} of the {len(with_answer)} questions with an answer score lower than"
          f" the highest question without one.")

    # Try a line under every score: below it we would say "the handbook has no answer".
    best_line, fewest = None, None
    for line, _ in with_answer + without:
        turned_away = sum(score < line for score, _ in with_answer)
        let_through = sum(score >= line for score, _ in without)
        if fewest is None or turned_away + let_through < fewest[0] + fewest[1]:
            best_line, fewest = line, (turned_away, let_through)
    print(f"The best line is at {best_line:.2f}. It would wrongly turn away {fewest[0]} of the"
          f" {len(with_answer)} questions that have an answer,")
    print(f"and let through {fewest[1]} of the {len(without)} that have none.")


if __name__ == "__main__":
    main()
