import random
import tkinter as tk
from tkinter import messagebox


class MultiplicationTrainer:
    def __init__(self, root):
        self.root = root
        self.root.title("Найди ошибку в таблице умножения")
        self.root.geometry("760x640")
        self.root.minsize(640, 560)
        self.root.configure(bg="#f5f6fa")
        self.buttons = {}
        self.wrong_cell = None
        self.attempts = 0
        self.found = 0
        self.build_interface()
        self.new_round()

    def report_error(self, exc_type, exc_value, exc_traceback):
        messagebox.showerror("Ошибка", f"{exc_type.__name__}: {exc_value}")

    def build_interface(self):
        self.root.report_callback_exception = self.report_error

        top = tk.Frame(self.root, bg="#f5f6fa")
        top.pack(fill="x", padx=12, pady=(12, 4))
        tk.Label(top, text="Найди ошибку в таблице умножения", font=("Segoe UI", 16, "bold"),
                 bg="#f5f6fa").pack()
        self.status = tk.Label(top, text="", font=("Segoe UI", 11), bg="#f5f6fa",
                               wraplength=700, justify="center")
        self.status.pack(pady=(6, 0))

        table = tk.Frame(self.root, bg="#f5f6fa")
        table.pack(expand=True, fill="both", padx=12, pady=8)
        for index in range(8):
            table.columnconfigure(index, weight=1, uniform="cell")
            table.rowconfigure(index, weight=1, uniform="cell")

        tk.Label(table, text="×", font=("Segoe UI", 15, "bold"), bg="#dcdde1").grid(
            row=0, column=0, sticky="nsew", padx=1, pady=1)
        for i in range(1, 8):
            tk.Label(table, text=str(i), font=("Segoe UI", 15, "bold"), bg="#dcdde1").grid(
                row=0, column=i, sticky="nsew", padx=1, pady=1)
            tk.Label(table, text=str(i), font=("Segoe UI", 15, "bold"), bg="#dcdde1").grid(
                row=i, column=0, sticky="nsew", padx=1, pady=1)
        for i in range(1, 8):
            for j in range(1, 8):
                button = tk.Button(table, text="", font=("Segoe UI", 13, "bold"), bg="#ffffff",
                                   activebackground="#e3f2fd", bd=2, relief="raised", cursor="hand2",
                                   command=lambda a=i, b=j: self.on_cell_click(a, b))
                button.grid(row=i, column=j, sticky="nsew", padx=1, pady=1)
                self.buttons[(i, j)] = button

        bottom = tk.Frame(self.root, bg="#f5f6fa")
        bottom.pack(fill="x", padx=12, pady=(0, 12))
        self.info = tk.Label(bottom, text="", font=("Segoe UI", 10), bg="#f5f6fa")
        self.info.pack(side="left")
        tk.Button(bottom, text="Начать заново", font=("Segoe UI", 10), command=self.restart).pack(side="right")

    def new_round(self):
        self.attempts = 0
        cells = [(i, j) for i in range(1, 8) for j in range(1, 8)]
        self.wrong_cell = random.choice(cells)
        for cell in cells:
            i, j = cell
            correct = i * j
            value = self.make_wrong_value(i, j, correct) if cell == self.wrong_cell else correct
            button = self.buttons[cell]
            button.config(text=str(value), bg="#ffffff", fg="#111111", state="normal",
                          relief="raised", disabledforeground="#ffffff")
        self.status.config(text="Нажми на число, которое посчитано неверно.", fg="#1b5e20")
        self.update_info()

    def make_wrong_value(self, a, b, correct):
        candidates = [a * (b + 1), a * (b - 1), (a + 1) * b, (a - 1) * b,
                      correct + 1, correct - 1, correct + 10, correct - 10]
        options = [value for value in candidates if value > 0 and value != correct]
        return random.choice(options)

    def on_cell_click(self, a, b):
        try:
            button = self.buttons[(a, b)]
            if str(button["state"]) == "disabled":
                return
            self.attempts += 1
            if (a, b) == self.wrong_cell:
                self.found += 1
                button.config(bg="#1b5e20", fg="#ffffff", state="disabled", relief="sunken")
                self.status.config(text=f"Молодец! {a} * {b} = {a * b} — правильно!", fg="#1b5e20")
                self.update_info()
                self.root.after(120, lambda: self.finish_round(a, b))
            else:
                button.config(bg="#2e8b57", fg="#ffffff", state="disabled", relief="sunken")
                self.status.config(
                    text=f"Это не ошибка: {a} * {b} = {a * b}. Ищи дальше!", fg="#b71c1c")
                self.update_info()
        except Exception as error:
            messagebox.showerror("Ошибка", str(error))

    def finish_round(self, a, b):
        if not self.root.winfo_exists():
            return
        messagebox.showinfo(
            "Молодец!",
            f"Молодец!\n\n{a} * {b} = {a * b} — правильно!\n\n"
            "Игра продолжается: в таблице снова спрятана одна ошибка.")
        self.new_round()

    def update_info(self):
        self.info.config(text=f"Попыток: {self.attempts}    Ошибок найдено: {self.found}")

    def restart(self):
        self.found = 0
        self.new_round()


def main():
    root = tk.Tk()
    MultiplicationTrainer(root)
    root.mainloop()


if __name__ == "__main__":
    try:
        main()
    except Exception as error:
        messagebox.showerror("Ошибка", str(error))