import random
import os
import sys
import time  # Import time for the timer functionality

# Print ASCII Art Banner
ascii_art = """
██╗    ██╗ ██████╗ ██████╗ ██████╗      ██████╗  █████╗ ███╗   ███╗███████╗
██║    ██║██╔═══██╗██╔══██╗██╔══██╗    ██╔════╝ ██╔══██╗████╗ ████║██╔════╝
██║ █╗ ██║██║   ██║██████╔╝██║  ██║    ██║  ███╗███████║██╔████╔██║█████╗  
██║███╗██║██║   ██║██╔══██╗██║  ██║    ██║   ██║██╔══██║██║╚██╔╝██║██╔══╝  
╚███╔███╔╝╚██████╔╝██║  ██║██████╔╝    ╚██████╔╝██║  ██║██║ ╚═╝ ██║███████╗
 ╚══╝╚══╝  ╚═════╝ ╚═╝  ╚═╝╚═════╝      ╚═════╝ ╚═╝  ╚═╝╚═╝     ╚═╝╚══════╝
"""
print(ascii_art)

# Constants
HIGH_SCORES_FILE = 'data/high_scores.txt'
USER_DATA_FILE = 'data/user_data.txt'

# word lists for different difficulty levels
DIFFICULTY_WORDS = {
    'easy': ['cat', 'fish', 'dog', 'bird', 'frog', 'apple', 'table', 'chair', 'book', 'lamp'],
    'medium': ['giraffe', 'monkey', 'penguin', 'squirrel', 'elephant', 'dolphin', 'computer', 'pencil', 'candle', 'window'],
    'hard': ['chimpanzee', 'extraordinary', 'microorganism', 'unbelievable', 'determination', 'superintendent', 'phenomenon', 'incomprehensible', 'electromagnetic', 'characteristic']
}

# Set number of tries based on difficulty
TRIES = {
    'easy': 5,
    'medium': 7,
    'hard': 10
}

def ensure_data_directory():
    """Ensure the data directory exists."""
    if not os.path.exists('data'):
        os.makedirs('data')

def load_user_data():
    """Load user data from a file."""
    if not os.path.exists(USER_DATA_FILE):
        return {}
    
    with open(USER_DATA_FILE, 'r') as file:
        user_data = {}
        for line in file:
            username = line.strip()
            user_data[username] = True  # Using a dictionary to track registered users
        return user_data

def register_user(username):
    """Register a new user."""
    with open(USER_DATA_FILE, 'a') as file:
        file.write(username + '\n')

def user_login():
    """Handle user login or registration."""
    user_data = load_user_data()
    
    while True:
        try:
            print("Login (l) or Register (r): ", end='', flush=True)
            choice = sys.stdin.readline().strip().lower()  # Using sys.stdin.readline()
            print("Enter your username: ", end='', flush=True)
            username = sys.stdin.readline().strip()  # Using sys.stdin.readline()

            if choice == 'l':
                if username in user_data:
                    print(f"Welcome back, {username}!")
                    return username
                else:
                    print("Username does not exist. Please register.")
            
            elif choice == 'r':
                if username not in user_data:
                    register_user(username)
                    print(f"User {username} registered successfully!")
                    return username
                else:
                    print("Username already exists. Please choose a different one.")
            else:
                print("Invalid choice. Please enter 'l' for Login or 'r' for Register.")
        
        except EOFError:
            print("\nInput error: Please ensure you're running this in an interactive console.")
            break
        except KeyboardInterrupt:
            print("\nInput interrupted. Exiting user login.")
            break
        except Exception as e: 
            print(f"An error occurred: {e}")
            break

def load_high_scores():
    """Load high scores from a file."""
    if not os.path.exists(HIGH_SCORES_FILE):
        return {}
    
    with open(HIGH_SCORES_FILE, 'r') as file:
        high_scores = {}
        for line in file:
            difficulty, name, score = line.strip().split(',')
            high_scores[difficulty] = (name, int(score))
        return high_scores

def save_high_score(name, score, difficulty):
    """Save player's name and score to a file."""
    ensure_data_directory()  # Ensure data directory exists
    with open(HIGH_SCORES_FILE, 'a') as file:
        file.write(f"{difficulty},{name},{score}\n")

def get_word(difficulty):
    """Select a random word from a given difficulty level."""
    return random.choice(DIFFICULTY_WORDS[difficulty])

def display_progress(selected_word, guessed_letters):
    """Display the current state of the guessed word."""
    display_word = ''
    for letter in selected_word:
        if letter in guessed_letters:
            display_word += letter + ' '
        else:
            display_word += '_ '
    print("\nCurrent word:", display_word.strip())

def guess_the_word(username):
    """Guess the word game."""
    while True:  # Loop for playing the game until user decides to exit
        print("Welcome to 'Guess the Word'!")
        difficulty = input("Choose difficulty (easy, medium, hard): ").lower()
        
        if difficulty not in DIFFICULTY_WORDS:
            print("Invalid difficulty. Please try again.")
            continue

        selected_word = get_word(difficulty)
        guessed_letters = []
        score = 100
        remaining_tries = TRIES[difficulty]  # Set tries based on selected difficulty

        while remaining_tries > 0:
            display_progress(selected_word, guessed_letters)
            print(f"Remaining tries: {remaining_tries}")
            guess = input("Guess a letter: ").lower()

            if guess in guessed_letters:
                print("You've already guessed that letter!")
                continue

            guessed_letters.append(guess)

            if guess in selected_word:
                print("Good guess!")
            else:
                remaining_tries -= 1  # Deduct one attempt for incorrect guess
                score -= 10
                print("Wrong guess! -10 points")

            if all(letter in guessed_letters for letter in selected_word):
                print(f"You guessed the word '{selected_word}'! Congratulations!")  # Show word on win
                break
            
            if remaining_tries <= 0:
                print(f"Game over! The correct word was '{selected_word}'.")  # Show correct word on loss
                score = 0  # Zero score if they fail to guess

        save_high_score(username, score, difficulty)

        # Asking the player if they want to play again
        play_again = input("Do you wish to play again? (yes/no): ").lower()
        if play_again != 'yes':
            break  # Exit the loop to stop the game

def display_shark(shark):
    """Display the shark's position."""
    print("Shark's position:", shark)

def beat_the_shark(username):
    """A simple race game where player guesses letters and compares to a shark opponent."""
    while True:  # Loop for playing the game until user decides to exit
        print("\nWelcome to 'Beat the Shark'!")
        difficulty = input("Choose difficulty (easy, medium, hard): ").lower()
        
        if difficulty not in DIFFICULTY_WORDS:
            print("Invalid difficulty. Please try again.")
            continue

        selected_word = get_word(difficulty)
        guessed_letters = []
        score = 100
        remaining_tries = TRIES[difficulty]  # Set tries based on selected difficulty

        # Initialize shark string based on difficulty
        if difficulty == 'easy':
            shark = "﹏﹏﹏𓂁"  # 3 underscores for easy
        elif difficulty == 'medium':
            shark = "﹏﹏﹏﹏﹏𓂁"  # 5 underscores for medium
        else:
            shark = "﹏﹏﹏﹏﹏﹏﹏﹏𓂁"  # 7 underscores for hard

        # Display initial shark position
        display_shark(shark)

        while remaining_tries > 0:  # The loop continues as long as there are remaining tries
            display_progress(selected_word, guessed_letters)
            print(f"Remaining tries: {remaining_tries}")
            guess = input("Guess a letter: ").lower()

            if guess in guessed_letters:
                print("You've already guessed that letter!")
                continue

            guessed_letters.append(guess)

            if guess in selected_word:
                print("Good guess! The shark is still behind!")
            else:
                remaining_tries -= 1  # Deduct one attempt for incorrect guess
                score -= 10
                print("Wrong guess! -10 points. The shark moves forward!")

                # Remove one '﹏' from the shark to show it moving closer
                shark = shark[:-1]  # Slice off the last character
                if len(shark) <= 1:  # If we only have the shark emoji left
                    shark = '𓂁'  # Replace with only the shark emoji
            
            # Display updated shark position
            display_shark(shark)

            # If the player successfully guesses all letters in the word, they win
            if all(letter in guessed_letters for letter in selected_word):
                print(f"You guessed the word '{selected_word}'! The shark couldn't catch you!")  # Show word on win
                break

        # If player runs out of tries, the shark catches them
        if remaining_tries <= 0:
            print(f"The shark caught you! Game over! The correct word was '{selected_word}'.")  # Show correct word on loss
            score = 0  # Score is zero if caught

        save_high_score(username, score, difficulty)

        # Asking the player if they want to play again
        play_again = input("Do you wish to play again? (yes/no): ").lower()
        if play_again != 'yes':
            break  # Exit the loop to stop the game

def timed_guess_the_word(username):
    """Timed Guess the Word game."""
    while True:  # Loop for playing the game until user decides to exit
        print("Welcome to 'Timed Guess the Word'!")
        print("You have infinite guesses but must guess the word within the time limit.")

        # Select time limit
        while True:
            print("Choose a time limit:")
            print("1. 30 seconds")
            print("2. 1 minute (60 seconds)")
            print("3. 1 minute and 30 seconds (90 seconds)")
            time_choice = input("Select a time limit (1, 2, 3): ").strip()

            if time_choice == '1':
                timer_duration = 30
                break
            elif time_choice == '2':
                timer_duration = 60
                break
            elif time_choice == '3':
                timer_duration = 90
                break
            else:
                print("Invalid choice. Please select 1, 2, or 3.")

        difficulty = input("Choose difficulty (easy, medium, hard): ").lower()
        
        if difficulty not in DIFFICULTY_WORDS:
            print("Invalid difficulty. Please try again.")
            continue

        selected_word = get_word(difficulty)
        guessed_letters = []
        score = 100
        remaining_tries = TRIES[difficulty]

        start_time = time.time()  # Start the timer

        while remaining_tries > 0:
            display_progress(selected_word, guessed_letters)
            print(f"Remaining tries: {remaining_tries}")
            elapsed_time = time.time() - start_time  # Calculate elapsed time
            remaining_time = max(0, timer_duration - elapsed_time)  # Calculate remaining time (cannot be negative)

            print(f"Time remaining: {int(remaining_time)} seconds")

            if remaining_time <= 0:
                print(f"Time's up! The correct word was '{selected_word}'.")  # Show correct word on loss
                score = 0
                break

            guess = input("Guess a letter: ").lower()

            if guess in guessed_letters:
                print("You've already guessed that letter!")
                continue

            guessed_letters.append(guess)

            if guess in selected_word:
                print("Good guess!")
            else:
                remaining_tries -= 1
                score -= 10
                print("Wrong guess! -10 points")

            if all(letter in guessed_letters for letter in selected_word):
                print(f"You guessed the word '{selected_word}'! Congratulations!")  # Show word on win
                break

        save_high_score(username, score, 'timed')  # Save high score for timed game

        # Asking the player if they want to play again
        play_again = input("Do you wish to play again? (yes/no): ").lower()
        if play_again != 'yes':
            break  # Exit the loop to stop the game

def display_high_scores(high_scores):
    """Display the high scores."""
    print("\nHigh Scores:")
    for difficulty in DIFFICULTY_WORDS.keys():
        if difficulty in high_scores:
            name, score = high_scores[difficulty]
            print(f"High Score [Difficulty: {difficulty}]: {name} with {score} points")
        else:
            print(f"High Score [Difficulty: {difficulty}]: No scores yet")

def start_menu():
    """Display the start menu and handle user choices."""
    while True:  # Loop for displaying the main menu
        print("Pick a game mode!")
        print("1. Guess the Word: Earn points by guessing the correct letters.")
        print("2. Beat the Shark: Race against a shark by guessing the word correctly.")
        print("3. Timed Guess the Word: Infinite guesses but beat the timer!")
        try:
            choice = input("Select a game (1, 2, or 3), or 'q' to quit: ")
            
            if choice == '1':
                guess_the_word(username)
            elif choice == '2':
                beat_the_shark(username)
            elif choice == '3':
                timed_guess_the_word(username)
            elif choice.lower() == 'q':
                print("Thank you for playing! Goodbye!")
                break
            else:
                print("Invalid choice. Please try again.")
        except KeyboardInterrupt:
            print("\nInput interrupted. Exiting the game.")
            break

# Load high scores at the start
high_scores = load_high_scores()

# Display high scores if available
display_high_scores(high_scores)

# Load users and handle login/registration
username = user_login()

# Start the game
if __name__ == "__main__":
    start_menu() make it so in the log in page make a section that says highscores and in this highscores section save every gamemodes highscores