import json

class Book:
    def __init__(self, title: str, author: str):
        self.title = title
        self.author = author

    def __repr__(self):
        return f"{self.title} de {self.author}"

    def __eq__(self, other: "Book"):
        """Pour comparer un objet de classe à un autre au lieu de l'ID par défaut"""
        return self.title == other.title and self.author == other.author

    def __gt__(self, other: "Book"):
        return self.title > other.title

    def __lt__(self, other: "Book"):
        return self.title.lower() < other.title.lower()

    def serialized(self):
        """Converti la classe en dictionnaire JSONable"""
        return {"Title": self.title, "Author": self.author}

    @classmethod
    def deserialized(cls, dictionnary):
        """Lis un JSON pour le retranscrire en classe Book"""
        return cls(title= dictionnary["Title"], author= dictionnary["Author"])

class Library:
    """Gère un contenu de livres"""
    def __init__(self, name: str):
        self.name = name
        self.books = self.load()

    def add_new_book(self, book: Book):
        """Ajoute un nouveau livre"""
        if book in self.books:
            return f"{book.title.capitalize()} y est déjà."
        self.books.append(book)
        self.save()
        return f"{book.title.capitalize()} a été ajouté."

    def take_out_book(self, book_name: str):
        """Retire un livre déjà présent"""
        for book in self.books:
            if book.title.lower() == book_name.lower():
                self.books.remove(book)
                self.save()
                return f"{book.title.capitalize()} a été retiré."
        return f"{book.title.capitalize()} n'y est pas."

    def list_books_in_list(self):
        """Liste les livres présents"""
        return self.books

    def sort_books_by_name(self):
        """Tri les livres par ordre alphabétique"""
        self.books.sort()

    def display_number_of_books(self) -> int:
        """Donne le nombre de livres présents"""
        return len(self.books)

    def search_book_by_word(self, word: str):
        """Cherche un livre par mot de départ"""
        results = []
        for book in self.books:
            if word.lower() in book.title.lower():
                results.append(book)
        return results if len(results) > 0 else "Pas de résultat."

    def search_book_by_letter(self, letter: str):
        """Cherche un livre par lettre de départ"""
        results = []
        for book in self.books:
            if book.title.lower().startswith(letter.lower()):
                results.append(book)
        return results if len(results) > 0 else "Pas de résultat."

    # Sauvegarde des livres dans un JSON pour persistance des données

    def save(self):
        """Inscris dans un fichier JSON le contenu de la bibliothèque"""
        book_dict = [book.serialized() for book in self.books]
        with open("books.json", "w", encoding= "utf-8") as json_file: # a pour append, w pour write
            json.dump(book_dict, json_file, indent= 4)

    def load(self) -> list[Book]:
        """Récupère le contenu d'un fichier JSON"""
        with open("books.json", encoding= "utf-8") as json_file:
            return json.load(json_file, object_hook= Book.deserialized)
