"""
Jeu 2025
Author: Stéphane Pasquet
Date: 2024/12/30
URL: https://www.mathweb.fr/euclide/2024/12/30/le-jeu-du-2025-en-python/
"""


from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QPushButton, QLabel, QVBoxLayout
from PyQt5.QtGui import QFont, QIcon, QPixmap, QPalette, QBrush, QColor
from PyQt5.QtCore import Qt
import os
from random import randint, shuffle

class dmvc:
    def __init__(self):
        self.result = 2025
        self.list = []
        while sum( self.list ) != 2025:
            self.list = self.newlist()
        self.matrix = self.matrice()

    def newlist(self):
        n = randint(5, 20)

        # Initialiser la liste avec des valeurs aléatoires entre 1 et self.result - 1
        mylist = []
        current_sum = 0
        unique_numbers = set()

        while len(mylist) < n - 1:
            new_number = randint(1, self.result - 1)
            if new_number not in unique_numbers:
                mylist.append(new_number)
                unique_numbers.add(new_number)
                current_sum += new_number

        # Ajuster le dernier nombre pour que la somme soit égale à self.result
        last_number = self.result - current_sum
        if last_number > 0 and last_number not in unique_numbers:
            mylist.append(last_number)
            unique_numbers.add(last_number)
        else:
            # Si last_number est négatif ou déjà dans unique_numbers, cela signifie que la somme actuelle dépasse self.result
            # Dans ce cas, ajustons la liste en retirant des éléments jusqu'à ce que la somme soit correcte
            while current_sum > self.result:
                index_to_remove = randint(0, len(mylist) - 1)
                removed_number = mylist.pop(index_to_remove)
                unique_numbers.remove(removed_number)
                current_sum -= removed_number

            # Ajouter le dernier élément pour atteindre self.result
            last_number = self.result - current_sum
            mylist.append(last_number)
            unique_numbers.add(last_number)

        # Assurer que la liste contient entre 5 et 20 éléments
        while len(mylist) < 5:
            new_number = randint(1, self.result - 1)
            if new_number not in unique_numbers:
                mylist.append(new_number)
                unique_numbers.add(new_number)
                current_sum += new_number
            while current_sum > self.result:
                index_to_remove = randint(0, len(mylist) - 1)
                removed_number = mylist.pop(index_to_remove)
                unique_numbers.remove(removed_number)
                current_sum -= removed_number

        while len(mylist) > 20:
            index_to_remove = randint(0, len(mylist) - 1)
            removed_number = mylist.pop(index_to_remove)
            unique_numbers.remove(removed_number)
            current_sum -= removed_number
            while current_sum < self.result:
                new_number = randint(1, self.result - current_sum)
                if new_number not in unique_numbers:
                    mylist.append(new_number)
                    unique_numbers.add(new_number)
                    current_sum += new_number

        return mylist

    def matrice(self):
        # Créer une copie de self.list
        list_copy = self.list.copy()

        for _ in range(25-len(list_copy)):
            n = list_copy[0]
            while n in list_copy:
                n = randint(1,self.result)
            list_copy.append(n)

        shuffle(list_copy)

        return [list_copy[i:i+5] for i in range(0, 25, 5)]

    def plateau(self):
        self.count = 0
        app = QApplication([])
        window = QWidget()
        window.setWindowTitle("2025")
        window.setGeometry(100, 100, 400, 400)

        # Ajouter l'icône de la fenêtre
        window.setWindowIcon(QIcon('icone_2025.png'))

        # Chemin de l'image de fond
        background_image_path = 'icone_2025.png'

        # Vérifier si le fichier existe
        if os.path.exists(background_image_path):
            # Définir l'image de fond comme arrière-plan du QLabel
            background_label = QLabel(window)
            background_label.setPixmap(QPixmap(background_image_path).scaled(400, 400))
            background_label.setGeometry(0, 0, 400, 400)
        else:
            print(f"Le fichier {background_image_path} n'existe pas.")
            background_label = QLabel(window)
            background_label.setStyleSheet("background-color: white;")  # Fond blanc par défaut

        # Définir un layout principal pour superposer les autres widgets
        main_layout = QVBoxLayout(window)
        main_layout.addWidget(background_label)

        layout = QVBoxLayout()
        grid_layout = QGridLayout()

        self.buttons = []
        self.current_sum = 0

        for i in range(5):
            row = []
            for j in range(5):
                button = QPushButton(str(self.matrix[i][j]))
                button.setFont(QFont('Arial', 16))
                button.setProperty("added", False)  # Propriété pour suivre si le nombre a été ajouté
                button.clicked.connect(self.create_button_click_handler(button))
                grid_layout.addWidget(button, i, j)
                row.append(button)
            self.buttons.append(row)

        layout.addLayout(grid_layout)

        # Ajouter le label pour le nombre de nombres à ajouter
        self.info_label = QLabel(f"{len(self.list)} nombres à ajouter pour obtenir {self.result}")
        self.info_label.setFont(QFont('Arial', 16))
        self.info_label.setAlignment(Qt.AlignCenter)
        layout.addWidget(self.info_label)

        self.sum_label = QLabel("Somme: 0")
        self.sum_label.setFont(QFont('Arial', 16))
        self.sum_label.setAlignment(Qt.AlignCenter)
        layout.addWidget(self.sum_label)

        # Ajouter le label pour le message de victoire
        self.win_label = QLabel("")
        self.win_label.setFont(QFont('Arial', 16))
        self.win_label.setAlignment(Qt.AlignCenter)
        layout.addWidget(self.win_label)

        # Ajouter le layout principal au QLabel de fond
        main_layout.addLayout(layout)

        window.setLayout(main_layout)
        window.show()
        app.exec_()

    def create_button_click_handler(self, button):
        def handler():
            value = int(button.text())
            added = button.property("added")
            if added:
                self.count -= 1
                self.current_sum -= value
                button.setProperty("added", False)
                button.setStyleSheet("background-color: white;")  # Réactiver le bouton et changer la couleur
            else:
                self.count += 1
                self.current_sum += value
                button.setProperty("added", True)
                button.setStyleSheet("background-color: gray;")  # Désactiver le bouton et changer la couleur
            self.update_sum_label()
            if self.current_sum == self.result:
                self.end_game()
        return handler

    def update_sum_label(self):
        if self.current_sum > self.result:
            self.sum_label.setStyleSheet("color: red;")
        else:
            self.sum_label.setStyleSheet("color: green;")
        self.sum_label.setText(f"Somme: {self.current_sum}")
        if len(self.list)-self.count < 2:
            terminaison = ''
        else:
            terminaison = 's'
        self.info_label.setText(f"{len(self.list)-self.count} nombre{terminaison} à ajouter pour obtenir {self.result}")

    def end_game(self):
        for row in self.buttons:
            for button in row:
                if not button.property("added"):
                    button.setStyleSheet("background-color: rgba(255, 255, 255, 0.5);")  # Rendre les boutons non sélectionnés plus transparents
                    button.setEnabled(False)
        self.win_label.setText("Vous avez gagné!")
        self.win_label.setStyleSheet("color: green;")

# Exemple d'utilisation
plateau = dmvc()
print( plateau.list )
plateau.plateau()
