import tkinter as tk
from tkinter import messagebox

class NoteTakingApp:
    def __init__(self, master):
        self.master = master
        self.master.title("Note Taking App")
        self.notes = []
        self.selected_note_index = None

        # Create UI elements
        self.note_listbox = tk.Listbox(master, width=50)
        self.note_listbox.grid(row=0, column=0, padx=10, pady=10, rowspan=6)

        self.title_label = tk.Label(master, text="Title:")
        self.title_label.grid(row=0, column=1, padx=10, pady=10)

        self.title_entry = tk.Entry(master, width=50)
        self.title_entry.grid(row=0, column=2, padx=10, pady=10)

        self.content_label = tk.Label(master, text="Content:")
        self.content_label.grid(row=1, column=1, padx=10, pady=10)

        self.content_text = tk.Text(master, width=50, height=10)
        self.content_text.grid(row=1, column=2, padx=10, pady=10)

        self.new_button = tk.Button(master, text="New Note", command=self.create_note)
        self.new_button.grid(row=2, column=2, padx=10, pady=10)

        self.save_button = tk.Button(master, text="Save Note", command=self.save_note)
        self.save_button.grid(row=3, column=2, padx=10, pady=10)

        self.delete_button = tk.Button(master, text="Delete Note", command=self.delete_note)
        self.delete_button.grid(row=4, column=2, padx=10, pady=10)

        self.search_entry = tk.Entry(master, width=50)
        self.search_entry.grid(row=5, column=2, padx=10, pady=10)

        self.search_button = tk.Button(master, text="Search", command=self.search_note)
        self.search_button.grid(row=6, column=2, padx=10, pady=10)

        # Load notes from file
        self.load_notes()

        # Bind double click event on note listbox
        self.note_listbox.bind("<Double-1>", self.load_selected_note)

    def create_note(self):
        title = self.title_entry.get().strip()
        content = self.content_text.get("1.0", tk.END).strip()

        if title and content:
            self.notes.append({"title": title, "content": content})
            self.update_note_listbox()
            self.clear_fields()
        else:
            messagebox.showwarning("Warning", "Title and content cannot be empty.")

    def save_note(self):
        if self.selected_note_index is not None:
            self.notes[self.selected_note_index] = {"title": self.title_entry.get().strip(),
                                                    "content": self.content_text.get("1.0", tk.END).strip()}
            self.update_note_listbox()
            self.clear_fields()
        else:
            messagebox.showwarning("Warning", "No note selected to save.")

    def delete_note(self):
        if self.selected_note_index is not None:
            del self.notes[self.selected_note_index]
            self.update_note_listbox()
            self.clear_fields()
        else:
            messagebox.showwarning("Warning", "No note selected to delete.")

    def search_note(self):
        search_query = self.search_entry.get().strip().lower()
        if search_query:
            matching_notes = [note for note in self.notes if search_query in note["title"].lower() or
                                                         search_query in note["content"].lower()]
            self.update_note_listbox(matching_notes)
        else:
            self.update_note_listbox()

    def load_notes(self):
        try:
            with open("notes.txt", "r") as file:
                self.notes = eval(file.read())
        except FileNotFoundError:
            pass
        self.update_note_listbox()

    def update_note_listbox(self, notes=None):
        self.note_listbox.delete(0, tk.END)
        if notes is None:
            notes = self.notes
        for note in notes:
            self.note_listbox.insert(tk.END, note["title"])

    def load_selected_note(self, event):
        if self.note_listbox.curselection():
            index = self.note_listbox.curselection()[0]
            self.selected_note_index = index
            note = self.notes[index]
            self.title_entry.delete(0, tk.END)
            self.title_entry.insert(0, note["title"])
            self.content_text.delete("1.0", tk.END)
            self.content_text.insert(tk.END, note["content"])

    def clear_fields(self):
        self.title_entry.delete(0, tk.END)
        self.content_text.delete("1.0", tk.END)

    def save_notes_to_file(self):
        with open("notes.txt", "w") as file:
            file.write(repr(self.notes))

def main():
    root = tk.Tk()
    app = NoteTakingApp(root)
    root.mainloop()
    app.save_notes_to_file()

if __name__ == "__main__":
    main()
