import time
import random
import json
import os
from datetime import datetime
import nltk
from nltk.corpus import gutenberg

# Setup NLTK
nltk.download('gutenberg', quiet=True)

SCORE_FILE = "typing_scores.json"

def load_scores():
    if os.path.exists(SCORE_FILE):
        with open(SCORE_FILE, "r") as f:
            return json.load(f)
    return []

def save_score(wpm, accuracy):
    scores = load_scores()
    scores.append({
        "wpm": wpm,
        "accuracy": accuracy,
        "date": datetime.now().strftime("%Y-%m-%d %H:%M")
    })
    # Sort by WPM descending and keep top 5
    scores = sorted(scores, key=lambda x: x['wpm'], reverse=True)[:5]
    with open(SCORE_FILE, "w") as f:
        json.dump(scores, f, indent=4)

def display_leaderboard():
    scores = load_scores()
    if not scores:
        return
    print("\n🏆 PERSONAL BESTS:")
    print(f"{'Rank':<5} {'WPM':<10} {'Accuracy':<10} {'Date'}")
    for i, s in enumerate(scores, 1):
        print(f"{i:<5} {s['wpm']:<10} {s['accuracy']}%     {s['date']}")

def get_sentence():
    # Using 'austen-emma.txt' for a different flavor this time
    sentences = gutenberg.sents('austen-emma.txt')
    valid = [" ".join(s) for s in sentences if 12 < len(s) < 20]
    return random.choice(valid)

def run_test():
    target = get_sentence()
    display_leaderboard()
    
    print(f"\nPROMPT:\n{target}")
    input("\nREADY? (Press Enter)")
    
    start = time.time()
    attempt = input("GO: ")
    end = time.time()
    
    # Logic
    elapsed = end - start
    wpm = round((len(attempt) / 5) / (elapsed / 60), 2)
    
    # Basic Accuracy calculation
    orig_words = target.split()
    att_words = attempt.split()
    matches = sum(1 for a, b in zip(orig_words, att_words) if a == b)
    acc = round((matches / len(orig_words)) * 100, 1) if orig_words else 0

    print(f"\n>> Result: {wpm} WPM | {acc}% Accuracy")
    
    if acc > 70:  # Only save if reasonably accurate
        save_score(wpm, acc)
        print("Score saved to leaderboard!")
    else:
        print("Accuracy too low to save score. Slow down to speed up!")

if __name__ == "__main__":
    try:
        while True:
            run_test()
            if input("\nAgain? (y/n): ").lower() != 'y':
                break
    except KeyboardInterrupt:
        print("\nSession ended.")
