import tkinter as tk
from tkinter import messagebox, font
import json

class Note:
    def __init__(self, title, content):
        self.title = title
        self.content = content

class NoteTakingApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Note Taking App")
        self.notes = []
        self.selected_note = None

        self.create_widgets()

    def create_widgets(self):
        # Create and configure the notes listbox
        self.listbox = tk.Listbox(self.root, width=50)
        self.listbox.pack(side=tk.LEFT, fill=tk.BOTH)
        self.listbox.bind('<<ListboxSelect>>', self.select_note)

        # Create a scrollbar for the listbox
        scrollbar = tk.Scrollbar(self.root)
        scrollbar.pack(side=tk.LEFT, fill=tk.Y)
        self.listbox.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.listbox.yview)

        # Create and configure the text widget for note content
        self.text_widget = tk.Text(self.root, font=('Arial', 12), wrap=tk.WORD)
        self.text_widget.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        # Create buttons for creating, editing, and deleting notes
        create_button = tk.Button(self.root, text="Create Note", command=self.create_note)
        create_button.pack()
        edit_button = tk.Button(self.root, text="Edit Note", command=self.edit_note)
        edit_button.pack()
        delete_button = tk.Button(self.root, text="Delete Note", command=self.delete_note)
        delete_button.pack()

        # Create a search entry and button
        self.search_entry = tk.Entry(self.root)
        self.search_entry.pack()
        search_button = tk.Button(self.root, text="Search", command=self.search_notes)
        search_button.pack()

        # Load notes from a file
        self.load_notes()

    def select_note(self, event):
        selected_index = self.listbox.curselection()
        if selected_index:
            index = int(selected_index[0])
            self.selected_note = self.notes[index]
            self.text_widget.delete('1.0', tk.END)
            self.text_widget.insert(tk.END, self.selected_note.content)

    def create_note(self):
        title = messagebox.askstring("Create Note", "Enter a title:")
        if title:
            content = self.text_widget.get('1.0', tk.END)
            new_note = Note(title, content)
            self.notes.append(new_note)
            self.listbox.insert(tk.END, title)
            self.text_widget.delete('1.0', tk.END)
            self.save_notes()

    def edit_note(self):
        if self.selected_note:
            new_content = self.text_widget.get('1.0', tk.END)
            self.selected_note.content = new_content
            self.save_notes()
            messagebox.showinfo("Note Updated", "Note has been updated.")
        else:
            messagebox.showwarning("No Note Selected", "Select a note to edit.")

    def delete_note(self):
        if self.selected_note:
            confirm = messagebox.askyesno("Confirm Delete", "Are you sure you want to delete the note?")
            if confirm:
                index = self.notes.index(self.selected_note)
                self.listbox.delete(index)
                self.notes.remove(self.selected_note)
                self.selected_note = None
                self.text_widget.delete('1.0', tk.END)
                self.save_notes()
        else:
            messagebox.showwarning("No Note Selected", "Select a note to delete.")

    def search_notes(self):
        query = self.search_entry.get()
        self.listbox.delete(0, tk.END)
        for note in self.notes:
            if query.lower() in note.title.lower() or query.lower() in note.content.lower():
                self.listbox.insert(tk.END, note.title)

    def load_notes(self):
        try:
            with open('notes.json', 'r') as file:
                data = json.load(file)
                for note_data in data:
                    note = Note(note_data['title'], note_data['content'])
                    self.notes.append(note)
                    self.listbox.insert(tk.END, note.title)
        except FileNotFoundError:
            pass

    def save_notes(self):
        data = []
        for note in self.notes:
            note_data = {'title': note.title, 'content': note.content}
            data.append(note_data)
        with open('notes.json', 'w') as file:
            json.dump(data, file)

root = tk.Tk()
app = NoteTakingApp(root)
root.mainloop()