"""
NoteManager
Generated by Eden via recursive self-improvement
2025-10-28 04:43:12.631426
"""

class NoteManager:
    """
    A class to manage and organize user notes or ideas.
    
    Attributes:
        notes (dict): Stores notes with their titles as keys and content as values.
        categories (dict): Stores predefined categories for notes.
        
    Methods:
        create_note(title, content): Creates a new note with a unique ID.
        retrieve_note_by_title(title): Retrieves a note by its title.
        retrieve_note_by_content(content): Retrieves a note by content keywords.
        update_note(note_id, new_content): Updates an existing note's content.
        delete_note(note_id): Deletes a specific note.
        add_category(category_name): Adds a new category for notes.
        assign_category(note_id, category): Assigns a category to a note.
        search_notes(search_criteria): Searches notes based on categories or keywords.
        display_notes(): Displays all stored notes.
    """

    def __init__(self):
        self.notes = {}
        self.categories = {}
        self.note_ids = 0

    def create_note(self, title: str, content: str) -> int:
        """Create a new note with a unique ID."""
        self.note_ids += 1
        self.notes[self.note_ids] = {"title": title, "content": content}
        return self.note_ids

    def retrieve_note_by_title(self, title: str) -> dict | None:
        """Retrieve a note by its title."""
        for note_id, note in self.notes.items():
            if note["title"] == title:
                return note
        return None

    def retrieve_note_by_content(self, content_keywords: list[str]) -> dict | None:
        """Retrieve a note by keywords in its content."""
        for note in self.notes.values():
            if any(keyword in note["content"] for keyword in content_keywords):
                return note
        return None

    def update_note(self, note_id: int, new_content: str) -> bool:
        """Update the content of an existing note."""
        if note_id in self.notes:
            self.notes[note_id]["content"] = new_content
            return True
        return False

    def delete_note(self, note_id: int) -> bool:
        """Delete a specific note."""
        if note_id in self.notes:
            del self.notes[note_id]
            return True
        return False

    def add_category(self, category_name: str) -> None:
        """Add a new category for notes."""
        self.categories[category_name] = []

    def assign_category(self, note_id: int, category: str) -> bool:
        """Assign a category to a specific note."""
        if note_id in self.notes and category in self.categories:
            self.categories[category].append(note_id)
            return True
        return False

    def search_notes(self, search_criteria: list[str]) -> list[dict]:
        """Search notes based on categories or keywords."""
        results = []
        for criteria in search_criteria:
            if criteria in self.categories:
                note_ids = self.categories[criteria]
                for note_id in note_ids:
                    results.append(self.notes[note_id])
            else:
                for note in self.notes.values():
                    if criteria.lower() in note["content"].lower():
                        results.append(note)
        return results

    def display_notes(self) -> None:
        """Display all stored notes with their titles."""
        print("\nStored Notes:")
        for note_id, note in self.notes.items():
            print(f"Note #{note_id}: {note['title']}")
            print(f"- {note['content']}\n")

# Example Usage:
if __name__ == "__main__":
    # Initialize the NoteManager
    note_manager = NoteManager()

    # Create notes
    note1 = note_manager.create_note("Welcome Message", "Hello, this is a test note.")
    note2 = note_manager.create_note("Meeting Notes", "Discuss project timeline and deliverables.")

    # Assign categories
    note_manager.add_category("Personal")
    note_manager.add_category("Work")
    note_manager.assign_category(note1, "Personal")
    note_manager.assign_category(note2, "Work")

    # Search notes by category
    work_notes = note_manager.search_notes(["Work"])
    print("\nWork Notes:")
    for note in work_notes:
        print(f"Note #{note['id']} - {note['title']}: {note['content']}")

    # Display all notes
    note_manager.display_notes()