align to the middle the options and fix restart quize button to work correctly and return to start "import random
import os
import sys
import tkinter as tk
from tkinter import messagebox, ttk
from PIL import Image, ImageTk, ImageSequence

# ---------- Attempt to Import Resampling (Pillow 10.0.0+) ----------
try:
    from PIL import Resampling

    resample_filter = Resampling.LANCZOS
except ImportError:
    # For older Pillow versions, use Image.LANCZOS if available
    try:
        resample_filter = Image.LANCZOS
    except AttributeError:
        # As a last resort, use Image.ANTIALIAS (deprecated in newer versions)
        resample_filter = Image.ANTIALIAS

# ---------- Initialize Global Variables ----------
start_button = None  # Initialize as None for global access


# ---------- Utility Functions ----------

def funny_message(fun_facts):
    return random.choice(fun_facts)


def create_quiz(words, meanings, examples, num_questions):
    question_set = set()
    quiz = []
    while len(quiz) < num_questions and len(question_set) < len(words):
        index = random.randint(0, len(words) - 1)
        if index in question_set:
            continue
        question_set.add(index)
        word = words[index]
        meaning = meanings[index]
        example = examples[index]
        options = [meaning]
        wrong_meanings = random.sample([m for m in meanings if m != meaning], min(2, len(meanings) - 1))
        options.extend(wrong_meanings)
        random.shuffle(options)
        correct_index = options.index(meaning)
        quiz.append((word, options, example, correct_index))
    random.shuffle(quiz)
    return quiz


def hex_to_rgb(hex_color):
    hex_color = hex_color.lstrip('#')
    h_len = len(hex_color)
    return tuple(int(hex_color[i:i + h_len // 3], 16) for i in range(0, h_len, h_len // 3))


def rgb_to_hex(rgb_tuple):
    return '#%02x%02x%02x' % rgb_tuple


def resource_path(relative_path):
    try:
        base_path = sys._MEIPASS  # For PyInstaller
    except Exception:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)


# ---------- Loading Screen Class ----------

class LoadingScreen(tk.Toplevel):
    def __init__(self, parent, gif_path):
        super().__init__(parent)
        self.parent = parent
        self.title("Loading...")
        self.geometry("300x300")
        self.overrideredirect(True)
        self.configure(bg="#f0f8ff")

        # Center the loading screen
        self.update_idletasks()
        x = parent.winfo_x() + (parent.winfo_width() // 2) - 150
        y = parent.winfo_y() + (parent.winfo_height() // 2) - 150
        # Ensure x and y are integers
        self.geometry(f"300x300+{int(x)}+{int(y)}")

        # Load the animated GIF
        try:
            self.gif = Image.open(gif_path)
            self.frames = [ImageTk.PhotoImage(frame.copy().resize((100, 100), resample_filter)) for frame in
                           ImageSequence.Iterator(self.gif)]
        except Exception as e:
            messagebox.showerror("Error", f"Failed to load loading spinner GIF.\nError: {e}")
            self.destroy()
            return

        self.frame_index = 0

        # Create a label to display the frames
        self.label = tk.Label(self, image=self.frames[self.frame_index], bg="#f0f8ff")
        self.label.pack(expand=True)

        self.animate()

    def animate(self):
        self.frame_index = (self.frame_index + 1) % len(self.frames)
        self.label.config(image=self.frames[self.frame_index])
        self.after(100, self.animate)


# ---------- Custom HoverButton Class with Enhanced Features ----------

class HoverButton(tk.Canvas):
    def __init__(self, master, width=200, height=50, corner_radius=15, padding=10,
                 bg_color="#E3F2FD", hover_color="#90CAF9", active_color="#1976D2",
                 text="", font=("Arial", 12, "bold"), command=None, image=None, **kwargs):
        super().__init__(master, width=width, height=height, highlightthickness=0, bg=master['bg'], **kwargs)
        self.width = width
        self.height = height
        self.corner_radius = corner_radius
        self.padding = padding
        self.bg_color = bg_color
        self.hover_color = hover_color
        self.active_color = active_color
        self.text = text
        self.font = font
        self.command = command
        self.current_color = bg_color
        self.state = "normal"  # Track the state: "normal" or "disabled"

        # Create rounded rectangle
        self.rect = self.create_round_rect(0, 0, width, height, corner_radius, fill=self.bg_color, outline="")

        # If an image is provided, display it
        if image:
            # Ensure image is loaded correctly
            try:
                self.icon = ImageTk.PhotoImage(image.resize((30, 30), resample_filter))
                self.create_image(self.padding + 15, int(self.height / 2), image=self.icon, anchor='w')
            except Exception as e:
                messagebox.showerror("Error", f"Failed to load button icon.\nError: {e}")
                self.icon = None

            # Create text with wraplength to handle longer texts, adjusted for icon
            self.label = self.create_text(int(self.width / 2), int(self.height / 2), text=self.text, font=self.font,
                                          fill="black",
                                          width=int(self.width - 3 * self.padding - 30), anchor='w')
        else:
            # Create text with wraplength to handle longer texts
            self.label = self.create_text(int(self.width / 2), int(self.height / 2), text=self.text, font=self.font,
                                          fill="black",
                                          width=int(self.width - 2 * self.padding))

        # Bind events only if the button is not disabled
        self.bind("<Enter>", self.on_enter)
        self.bind("<Leave>", self.on_leave)
        self.bind("<Button-1>", self.on_click)

        # Variables for color transition
        self.transition_steps = 10
        self.transition_delay = 30  # ms
        self.current_step = 0
        self.transitioning = False

    def create_round_rect(self, x1, y1, x2, y2, r=25, **kwargs):
        points = [
            x1 + r, y1,
            x2 - r, y1,
            x2, y1,
            x2, y1 + r,
            x2, y2 - r,
            x2, y2,
            x2 - r, y2,
            x1 + r, y2,
            x1, y2,
            x1, y2 - r,
            x1, y1 + r,
            x1, y1
        ]
        return self.create_polygon(points, smooth=True, **kwargs)

    def on_enter(self, event):
        if self.state == "normal" and not self.transitioning:
            self.transitioning = True
            self.current_step = 0
            self.animate_color_transition(self.bg_color, self.hover_color)

    def on_leave(self, event):
        if self.state == "normal" and not self.transitioning:
            self.transitioning = True
            self.current_step = 0
            self.animate_color_transition(self.hover_color, self.bg_color)

    def on_click(self, event):
        if self.command and self.state == "normal":
            self.command()

    def animate_color_transition(self, from_color, to_color):
        if self.current_step > self.transition_steps:
            self.transitioning = False
            return
        # Calculate intermediate color
        r1, g1, b1 = hex_to_rgb(from_color)
        r2, g2, b2 = hex_to_rgb(to_color)
        ratio = self.current_step / self.transition_steps
        r = int(r1 + (r2 - r1) * ratio)
        g = int(g1 + (g2 - g1) * ratio)
        b = int(b1 + (b2 - b1) * ratio)
        intermediate_color = rgb_to_hex((r, g, b))
        self.itemconfig(self.rect, fill=intermediate_color)
        self.current_step += 1
        self.after(self.transition_delay, lambda: self.animate_color_transition(from_color, to_color))

    def update_text(self, new_text):
        self.text = new_text
        if hasattr(self, 'label'):
            self.itemconfig(self.label, text=new_text)

    def set_state(self, state):
        self.state = state
        if state == "disabled":
            self.itemconfig(self.rect, fill='#E0E0E0')
            self.itemconfig(self.label, fill="#A0A0A0")
        else:
            self.itemconfig(self.rect, fill=self.bg_color)
            self.itemconfig(self.label, fill="black")

    def invoke(self):
        if self.state == "normal" and self.command:
            self.command()


# ---------- File Reading Functions ----------

def read_words_meanings(file_path):
    words = []
    meanings = []
    examples = []
    with open(file_path, 'r', encoding='utf-8') as file:
        content = file.read().strip().split('\n\n')
        for entry in content:
            lines = [line.strip() for line in entry.strip().split('\n') if line.strip()]
            if len(lines) < 3:
                print(f"Skipping entry due to incorrect format: {entry}")
                continue
            word = lines[0].replace(":", "").strip()
            meaning_line = lines[1]
            example_line = lines[2]
            if not meaning_line.startswith("Meaning: ") or not example_line.startswith("Example: "):
                print(f"Skipping entry due to incorrect format: {entry}")
                continue
            meaning = meaning_line.replace("Meaning: ", "").strip()
            example = example_line.replace("Example: ", "").strip()
            words.append(word)
            meanings.append(meaning)
            examples.append(example)
    return words, meanings, examples


def read_fun_facts_from_file(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        fun_facts = [line.strip().strip('"').strip(',') for line in file if line.strip()]
    return fun_facts


# ---------- Fade-In Animation Function ----------

def fade_in(widget, target="#1976D2", step=0, max_steps=10):
    if step > max_steps:
        return
    r_target, g_target, b_target = hex_to_rgb(target)
    r_current = int(r_target * (step / max_steps))
    g_current = int(g_target * (step / max_steps))
    b_current = int(b_target * (step / max_steps))
    intermediate_color = rgb_to_hex((r_current, g_current, b_current))
    try:
        widget.config(fg=intermediate_color)
    except:
        pass
    widget.after(50, lambda: fade_in(widget, target, step + 1, max_steps))


# ---------- Quiz Logic Functions ----------

def select_question_count(count):
    global num_questions
    num_questions = count
    print(f"Selected number of questions: {num_questions}")
    # Show loading screen
    loading = LoadingScreen(root, resource_path('loading_spinner.gif'))
    # Simulate loading delay (e.g., fetching data)
    root.after(2000, lambda: [loading.destroy(), show_quiz_interface()])


def check_answer(selected_index):
    global question_number, score, quiz
    word, options, example, correct_index = quiz[question_number]
    funny_threshold = 0.5
    funny = random.random() < funny_threshold

    # Disable all options temporarily
    disable_all_options()

    if selected_index == correct_index:
        score += 1
        feedback = "✅ Correct!"
        color = "#C8E6C9"  # Greenish
        print(f"Question {question_number + 1}: Correct")
    else:
        score -= 1
        feedback = f"❌ Wrong! The correct answer was: '{options[correct_index]}'."
        color = "#FFCDD2"  # Reddish
        print(
            f"Question {question_number + 1}: Wrong (Selected: {options[selected_index]}, Correct: {options[correct_index]})")

    # Highlight the selected and correct options
    if selected_index != correct_index:
        highlight_option(selected_index, "#FFCDD2")  # Wrong selection
    highlight_option(correct_index, "#C8E6C9")  # Correct answer

    # Show feedback
    message = f"{feedback}\n\nExample:\n{example}"
    if funny:
        message += f"\n\n💡 Fun Fact: {funny_message(fun_facts)}"
    messagebox.showinfo("Result", message)

    # Update score label
    calculate_score()

    question_number += 1
    administer_quiz()


def calculate_score():
    global score_label
    percentage = max(score, 0)  # Prevent negative scores
    rounded_percentage = round((percentage / len(quiz)) * 100) if len(quiz) > 0 else 0
    score_label.config(text=f"Score: {rounded_percentage}% ({score})")
    print(f"Updated Score: {score_label.cget('text')}")


def use_joker():
    global joker_used
    if not joker_used and question_number < len(quiz):
        word, options, example, correct_index = quiz[question_number]
        print(f"Using Joker on Question {question_number + 1}: {word}")
        incorrect_indices = [i for i in range(len(options)) if i != correct_index]
        if incorrect_indices:
            option_to_remove = random.choice(incorrect_indices)
            disable_option_button(option_to_remove)
            joker_used = True
            joker_button.set_state("disabled")
            print(f"Joker used. Disabled option {option_to_remove + 1}")
    else:
        print("Joker cannot be used.")


def disable_option_button(index):
    if index == 0:
        option1_button.set_state("disabled")
    elif index == 1:
        option2_button.set_state("disabled")
    elif index == 2:
        option3_button.set_state("disabled")


def disable_all_options():
    option1_button.set_state("disabled")
    option2_button.set_state("disabled")
    option3_button.set_state("disabled")


def highlight_option(index, color):
    if index == 0:
        option1_button.itemconfig(option1_button.rect, fill=color)
    elif index == 1:
        option2_button.itemconfig(option2_button.rect, fill=color)
    elif index == 2:
        option3_button.itemconfig(option3_button.rect, fill=color)


def start_quiz():
    global question_number, score, quiz, joker_used, start_button
    question_number = 0
    score = 0
    joker_used = False
    print(f"Starting quiz with {num_questions} questions.")
    quiz = create_quiz(words, meanings, examples, num_questions)
    if not quiz:
        messagebox.showerror("Error", "No valid quiz questions available.")
        create_question_count_selection()
        return
    administer_quiz()

    # Update the start_button to "Restart Quiz" and change its command
    if start_button:
        start_button.update_text("Restart Quiz")
        start_button.command = restart_quiz


def restart_quiz():
    global question_number, score, quiz, joker_used, start_button
    question_number = 0
    score = 0
    joker_used = False
    print("Restarting the quiz.")
    quiz = create_quiz(words, meanings, examples, num_questions)
    if not quiz:
        messagebox.showerror("Error", "No valid quiz questions available.")
        create_question_count_selection()
        return
    administer_quiz()

    # Reset the start_button to "Start Quiz" and change its command back
    if start_button:
        start_button.update_text("Start Quiz")
        start_button.command = start_quiz
        print("Start button reset to 'Start Quiz'.")


def administer_quiz():
    global question_number, score, quiz, joker_used
    if question_number < len(quiz):
        word, options, example, correct_index = quiz[question_number]
        print(f"Administering Question {question_number + 1}: {word}")
        print(f"Options: {options}, Correct Index: {correct_index}")

        # Update Question Label with Fade-In Effect
        question_text = f"🔍 Question {question_number + 1}: What is the meaning of '{word}'?"
        question_label.config(text=question_text)
        fade_in(question_label)

        # Reset button states and update texts
        option1_button.update_text(options[0])
        option2_button.update_text(options[1])
        option3_button.update_text(options[2])

        option1_button.set_state("normal")
        option2_button.set_state("normal")
        option3_button.set_state("normal")

        # Reset button colors
        option1_button.itemconfig(option1_button.rect, fill=option1_button.bg_color)
        option2_button.itemconfig(option2_button.rect, fill=option2_button.bg_color)
        option3_button.itemconfig(option3_button.rect, fill=option3_button.bg_color)

        # Update commands
        option1_button.command = lambda i=0: check_answer(i)
        option2_button.command = lambda i=1: check_answer(i)
        option3_button.command = lambda i=2: check_answer(i)

        # Update Progress Bar with smooth animation
        progress_percentage = ((question_number + 1) / len(quiz)) * 100
        animate_progress_bar(progress_percentage)

        # Update Remaining Questions Label
        remaining_questions = len(quiz) - (question_number + 1)
        remaining_label.config(text=f"Remaining: {remaining_questions}")
        print(f"Progress: {progress_percentage}%, Remaining: {remaining_questions}")

        # Handle Joker Button State
        if not joker_used:
            joker_button.set_state("normal")
            joker_button.itemconfig(joker_button.rect, fill=joker_button.bg_color)
            joker_button.itemconfig(joker_button.label, fill="black")
            print("Joker is available.")
        else:
            joker_button.set_state("disabled")
            joker_button.itemconfig(joker_button.rect, fill='#E0E0E0')
            joker_button.itemconfig(joker_button.label, fill="#A0A0A0")
            print("Joker has been used.")

    else:
        finalize_quiz()


def animate_progress_bar(target):
    global progress_var
    current = progress_var.get()
    if current < target:
        current += 1
        progress_var.set(current)
        root.after(10, lambda: animate_progress_bar(target))
    else:
        progress_var.set(target)


def finalize_quiz():
    percentage_score = (score / len(quiz)) * 100 if len(quiz) > 0 else 0
    rounded_percentage = round(percentage_score)
    joker_message = "🎉 You used the joker. 🎉" if joker_used else "👍 You did not use the joker."
    final_message = (
        f"🎉 Congratulations! 🎉\n\n"
        f"Your final score is {score}/{len(quiz)}.\n"
        f"That's {rounded_percentage}%!\n\n"
        f"{joker_message}\n\n"
        f"Thank you for taking the quiz with Sadra!"
    )
    # Add a final fun fact
    if fun_facts:
        final_message += f"\n\n💡 Last Fun Fact: {funny_message(fun_facts)}"
    messagebox.showinfo("Quiz Completed", final_message)
    print("Quiz completed. Exiting application.")
    root.destroy()


# ---------- Main Interface Functions ----------

def show_quiz_interface():
    global question_label, option1_button, option2_button, option3_button
    global joker_button, progress_bar, score_label, remaining_label, progress_var
    global start_button  # Declare as global

    # Clear existing widgets
    for widget in root.winfo_children():
        widget.destroy()

    # Set background image
    try:
        bg_image = Image.open(resource_path('background.png'))
        bg_image = bg_image.resize((900, 700), resample_filter)
        bg_photo = ImageTk.PhotoImage(bg_image)
    except Exception as e:
        messagebox.showerror("Error", f"Failed to load background image.\nError: {e}")
        root.destroy()
        return

    bg_label = tk.Label(root, image=bg_photo)
    bg_label.image = bg_photo  # Keep a reference
    bg_label.place(x=0, y=0, relwidth=1, relheight=1)

    # Create main container frame centered in the window
    container = tk.Frame(root, bg='#f0f8ff', bd=0)
    container.grid(row=0, column=0, sticky="nsew", padx=20, pady=20)

    # Configure grid weights for the container to expand
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)
    container.grid_rowconfigure(0, weight=1)
    container.grid_rowconfigure(1, weight=3)
    container.grid_rowconfigure(2, weight=2)
    container.grid_columnconfigure(0, weight=1)

    # Create sub-frames for layout management
    top_frame = tk.Frame(container, bg="#f0f8ff")
    top_frame.grid(row=0, column=0, sticky="ew", pady=(0, 20))
    top_frame.grid_columnconfigure(0, weight=1)

    middle_frame = tk.Frame(container, bg="#f0f8ff")
    middle_frame.grid(row=1, column=0, sticky="nsew", pady=20)
    middle_frame.grid_columnconfigure(0, weight=1)

    bottom_frame = tk.Frame(container, bg="#f0f8ff")
    bottom_frame.grid(row=2, column=0, sticky="ew", pady=(20, 0))
    bottom_frame.grid_columnconfigure(0, weight=1)

    # Question Label with Fade-In Effect
    question_label = tk.Label(top_frame, text="Press Start to begin the quiz",
                              wraplength=800, justify="center",
                              font=("Helvetica", 18, "bold"), bg="#f0f8ff", fg="#1976D2")
    question_label.pack(pady=10)
    fade_in(question_label)

    # Option Buttons Creation with Dynamic Width and Icons
    # Arrange buttons in a single column with consistent spacing
    option_buttons = []
    options_info = [
        {"text": "Option 1", "bg_color": "#E3F2FD", "hover_color": "#90CAF9", "active_color": "#1976D2"},
        {"text": "Option 2", "bg_color": "#FFCDD2", "hover_color": "#EF9A9A", "active_color": "#D32F2F"},
        {"text": "Option 3", "bg_color": "#C8E6C9", "hover_color": "#A5D6A7", "active_color": "#388E3C"},
    ]

    for idx, option in enumerate(options_info):
        btn = HoverButton(middle_frame, width=800, height=60, corner_radius=15, text=option["text"],
                          font=("Helvetica", 14), bg_color=option["bg_color"],
                          hover_color=option["hover_color"], active_color=option["active_color"],
                          command=lambda i=idx: check_answer(i))
        btn.grid(row=idx, column=0, pady=10, sticky="ew")
        option_buttons.append(btn)

    global option1_button, option2_button, option3_button
    if len(option_buttons) >= 3:
        option1_button, option2_button, option3_button = option_buttons[:3]
    else:
        option1_button = option_buttons[0] if len(option_buttons) > 0 else None
        option2_button = option_buttons[1] if len(option_buttons) > 1 else None
        option3_button = option_buttons[2] if len(option_buttons) > 2 else None

    # Control Buttons Creation with Icons
    control_frame = tk.Frame(bottom_frame, bg="#f0f8ff")
    control_frame.grid(row=0, column=0, sticky="ew")
    control_frame.grid_columnconfigure(0, weight=1)
    control_frame.grid_columnconfigure(1, weight=1)

    # Load button icons
    try:
        start_icon = Image.open(resource_path('start_icon.png'))
    except Exception as e:
        messagebox.showerror("Error", f"Failed to load start button icon.\nError: {e}")
        start_icon = None

    try:
        joker_icon = Image.open(resource_path('joker_icon.png'))
    except Exception as e:
        messagebox.showerror("Error", f"Failed to load joker button icon.\nError: {e}")
        joker_icon = None

    # Initialize start_button as a global variable
    start_button = HoverButton(control_frame, width=200, height=50, corner_radius=15,
                               text="Start Quiz", font=("Helvetica", 12, "bold"),
                               bg_color='#4CAF50', hover_color='#43A047', active_color='#388E3C',
                               command=start_quiz, image=start_icon)
    start_button.grid(row=0, column=1, pady=5, padx=(10, 0), sticky="e")

    joker_button = HoverButton(control_frame, width=200, height=50, corner_radius=15,
                               text="Use Joker", font=("Helvetica", 12, "bold"),
                               bg_color='#FFC107', hover_color='#FFB300', active_color='#FFA000',
                               command=use_joker, image=joker_icon)
    joker_button.grid(row=0, column=0, pady=5, padx=(0, 10), sticky="w")

    # Progress Bar Styling
    style = ttk.Style()
    style.theme_use('clam')
    style.configure("Custom.Horizontal.TProgressbar",
                    troughcolor='#E3F2FD',
                    background='#2196F3',
                    thickness=20,
                    borderwidth=0)
    style.configure("TLabel", background="#f0f8ff", foreground="#1976D2", font=("Helvetica", 14, "bold"))

    # Progress Bar with Animation
    progress_var = tk.DoubleVar()
    progress_bar = ttk.Progressbar(bottom_frame,
                                   style="Custom.Horizontal.TProgressbar",
                                   variable=progress_var,
                                   maximum=100,
                                   length=800)
    progress_bar.grid(row=1, column=0, pady=10, padx=50, sticky="ew")

    # Score Label
    score_label = tk.Label(bottom_frame, text="Score: 0",
                           font=("Helvetica", 14, "bold"),
                           fg="#1976D2",
                           bg="#f0f8ff")
    score_label.grid(row=2, column=0, pady=5, padx=50, sticky="w")

    # Remaining Questions Label
    remaining_label = tk.Label(bottom_frame, text="Remaining: 0",
                               font=("Helvetica", 14, "bold"),
                               fg="#1976D2",
                               bg="#f0f8ff")
    remaining_label.grid(row=3, column=0, pady=5, padx=50, sticky="w")


# ---------- Create Question Count Selection Screen ----------

def create_question_count_selection():
    # Clear any existing widgets
    for widget in root.winfo_children():
        widget.destroy()

    # Set background image
    try:
        bg_image = Image.open(resource_path('background.png'))
        bg_image = bg_image.resize((900, 700), resample_filter)
        bg_photo = ImageTk.PhotoImage(bg_image)
    except Exception as e:
        messagebox.showerror("Error", f"Failed to load background image.\nError: {e}")
        root.destroy()
        return

    bg_label = tk.Label(root, image=bg_photo)
    bg_label.image = bg_photo  # Keep a reference
    bg_label.place(x=0, y=0, relwidth=1, relheight=1)

    # Create main container frame centered in the window
    container = tk.Frame(root, bg='#f0f8ff', bd=0)
    container.grid(row=0, column=0, sticky="nsew", padx=40, pady=40)

    # Configure grid weights for the container to expand
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)
    container.grid_rowconfigure(0, weight=1)
    container.grid_rowconfigure(1, weight=3)
    container.grid_columnconfigure(0, weight=1)

    # Title Label with Fade-In Effect
    title_label = tk.Label(container,
                           text="How many questions would you like to answer?",
                           font=("Helvetica", 24, "bold"),
                           fg="#1976D2",
                           bg="#f0f8ff",
                           pady=20)
    title_label.pack()
    fade_in(title_label)

    # Frame for Buttons
    button_frame = tk.Frame(container, bg="#f0f8ff")
    button_frame.pack(expand=True)

    # Question Count Options with Enhanced Design and Icons
    questions_options = [
        {"count": 5, "bg": "#E3F2FD", "hover_color": "#90CAF9", "active_color": "#64B5F6"},
        {"count": 10, "bg": "#FFCDD2", "hover_color": "#EF9A9A", "active_color": "#E57373"},
        {"count": 15, "bg": "#C8E6C9", "hover_color": "#A5D6A7", "active_color": "#81C784"},
        {"count": 20, "bg": "#FFF9C4", "hover_color": "#FFF59D", "active_color": "#FFF176"},
    ]

    for option in questions_options:
        btn = HoverButton(button_frame,
                          width=400,
                          height=60,
                          corner_radius=20,
                          text=f"{option['count']} Questions",
                          font=("Helvetica", 14, "bold"),
                          bg_color=option['bg'],
                          hover_color=option['hover_color'],
                          active_color=option['active_color'],
                          command=lambda c=option['count']: select_question_count(c))
        btn.pack(pady=10, fill='x')


# ---------- Main Application Setup ----------

if __name__ == '__main__':
    # Create the main application window
    root = tk.Tk()
    root.title("🧠 Vocabulary Quiz")
    root.geometry("900x700")
    root.config(bg="#f0f8ff")
    root.resizable(True, True)  # Allow window to be resizable

    # Center the window on the screen
    root.update_idletasks()
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    x = (screen_width - 900) // 2
    y = (screen_height - 700) // 2
    # Ensure x and y are integers
    root.geometry(f"900x700+{int(x)}+{int(y)}")

    # Add window icon (if available)
    try:
        root.iconbitmap(resource_path('quiz_icon.ico'))
    except:
        pass  # Skip if icon file is not available

    # Configure custom styles for the application
    style = ttk.Style()
    style.theme_use('clam')

    # Configure a custom style for the progress bar
    style.configure("Custom.Horizontal.TProgressbar",
                    troughcolor='#E3F2FD',
                    background='#2196F3',
                    thickness=20,
                    borderwidth=0)

    # Load resources
    funny_message_file_path = resource_path('funny_message.txt')
    words_meanings_file_path = resource_path('words_meanings.txt')
    loading_spinner_path = resource_path('loading_spinner.gif')
    background_image_path = resource_path('background.png')
    start_icon_path = resource_path('start_icon.png')
    joker_icon_path = resource_path('joker_icon.png')

    # Verify resource files
    missing_files = []
    for file_path in [words_meanings_file_path, funny_message_file_path, loading_spinner_path, background_image_path,
                      start_icon_path, joker_icon_path]:
        if not os.path.exists(file_path):
            missing_files.append(file_path)

    if missing_files:
        messagebox.showerror("Error", f"Error: The following required files are missing:\n" + "\n".join(missing_files))
        sys.exit(1)

    # Read Words, Meanings, and Examples
    words, meanings, examples = read_words_meanings(words_meanings_file_path)
    if not words:
        messagebox.showerror("Error", "No valid entries found in the words_meanings.txt file.")
        sys.exit(1)

    # Read Fun Facts
    fun_facts = read_fun_facts_from_file(funny_message_file_path)

    # Initialize variables
    question_number = 0
    score = 0
    joker_used = False
    quiz = []
    num_questions = 10  # Default value, will be updated by user selection

    # Configure grid weights for responsive layout
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)


    # ---------- Keyboard Shortcuts ----------

    def handle_keyboard_input(event):
        global question_number
        if question_number < len(quiz):
            if event.char in ['1', '2', '3']:
                index = int(event.char) - 1
                # Check if the option button is enabled before invoking
                if index == 0 and option1_button and option1_button.state != 'disabled':
                    option1_button.invoke()
                elif index == 1 and option2_button and option2_button.state != 'disabled':
                    option2_button.invoke()
                elif index == 2 and option3_button and option3_button.state != 'disabled':
                    option3_button.invoke()
            elif event.char.lower() == 'j' and not joker_used and joker_button and joker_button.state != 'disabled':
                joker_button.invoke()


    root.bind('<Key>', handle_keyboard_input)


    # ---------- Error Handling ----------

    def on_error(exception_type, value, traceback_info):
        messagebox.showerror("Error",
                             "An unexpected error occurred. The application will exit.\n\n"
                             f"Error: {str(value)}")
        root.destroy()
        sys.exit(1)


    root.report_callback_exception = on_error

    # ---------- Start with Question Count Selection ----------

    create_question_count_selection()

    # ---------- Start the Main Event Loop ----------

    try:
        root.mainloop()
    except Exception as e:
        print(f"Error in main loop: {str(e)}")
        sys.exit(1)"