import sys
import numpy as np
from gensim.models import KeyedVectors
import random

TOLERANCE = 1e-4  # tolérance sur la similarité cosinus

if len(sys.argv) < 3:
    print("Usage: python cemantle.py <mot> <score>")
    sys.exit(1)

first_word = sys.argv[1].lower()
first_score = float(sys.argv[2]) / 100

# Détection de la langue
lang = sys.argv[3] if len(sys.argv) > 3 else "en"
if lang == "fr":
    TOLERANCE = 1e-2
    with open("french_words.txt") as f:
        valid_words = set(w.strip() for w in f)
    print("Mode français : dictionnaire français chargé.")
    model_path = "frWac_non_lem_no_postag_no_phrase_200_cbow_cut0.bin"
    print("Chargement du modèle français (frWac cut100)...")
    model = KeyedVectors.load_word2vec_format(model_path, binary=True)
else:
    with open("english_words.txt") as f:
        valid_words = set(w.strip() for w in f)
    print("Mode anglais : dictionnaire anglais chargé.")
    model_path = "GoogleNews-vectors-negative300.bin.gz"
    print("Chargement du modèle anglais...")
    model = KeyedVectors.load_word2vec_format(model_path, binary=True)

if first_word not in model:
    print(f"Mot inconnu du modèle: {first_word}")
    sys.exit(1)

# Calculer la similarité cosinus entre deux vecteurs
cos = lambda a, b: np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

def is_valid_word(word):
    if lang == "fr":
        return word.islower() and all(c.isalpha() for c in word) and word in valid_words and 3 <= len(word) <= 15
    else:
        return word.islower() and word.isalpha() and word in valid_words and 3 <= len(word) <= 15

# Filtrer les mots à la bonne distance du mot donné, et qui sont valides
vec1 = model[first_word]
words = []
for w in model.index_to_key:
    if w == first_word:
        continue
    if not is_valid_word(w):
        continue
    sim = cos(vec1, model[w])
    if abs(sim - first_score) < TOLERANCE:
        words.append(w)

print(f"{len(words)} mots à la distance {first_score*100:.2f} de '{first_word}' (valides)")

while words:
    guess = random.choice(words)
    print(f"Try: {guess}")
    s = input("Score: ")
    if s == "n":
        words.remove(guess)
        print(f"Mot refusé, {len(words)} restants.")
        continue
    try:
        score = float(s) / 100
    except ValueError:
        print("Entrée invalide, recommencez.")
        continue
    vec_guess = model[guess]
    # Filtrer les mots à la bonne distance du guess
    words = [w for w in words if abs(cos(vec_guess, model[w]) - score) < TOLERANCE]
    print(f"{len(words)} mots restants à la distance {score*100:.2f} de '{guess}'")

    if not words:
        print("Plus aucun mot possible. Terminé.")
        break
    if len(words) == 1:
        print(f"Plus qu'un seul mot possible: {words[0]}")
        break
