import tkinter as tk
from tkinter import messagebox
import json

contacts = []


def load_contacts():
    try:
        with open('contacts.json', 'r') as file:
            contacts.extend(json.load(file))
    except FileNotFoundError:
        pass


def save_contacts():
    with open('contacts.json', 'w') as file:
        json.dump(contacts, file, indent=4)


def add_contact():
    name = name_entry.get()
    phone = phone_entry.get()

    if name and phone:
        contacts.append({'name': name, 'phone': phone})
        save_contacts()
        update_contact_list()
        clear_entries()
    else:
        messagebox.showerror('Error', 'Please enter both name and phone number.')


def edit_contact():
    selected_contact = contact_listbox.curselection()

    if not selected_contact:
        return

    selected_contact = selected_contact[0]
    contact = contacts[selected_contact]

    name = name_entry.get()
    phone = phone_entry.get()

    if name and phone:
        contact['name'] = name
        contact['phone'] = phone
        save_contacts()
        update_contact_list()
        clear_entries()
    else:
        messagebox.showerror('Error', 'Please enter both name and phone number.')


def delete_contact():
    selected_contact = contact_listbox.curselection()

    if not selected_contact:
        return

    selected_contact = selected_contact[0]
    del contacts[selected_contact]
    save_contacts()
    update_contact_list()
    clear_entries()


def search_contact():
    keyword = search_entry.get().lower()

    if keyword:
        filtered_contacts = [
            contact for contact in contacts
            if keyword in contact['name'].lower() or keyword in contact['phone']
        ]
        update_contact_list(filtered_contacts)
    else:
        update_contact_list()


def update_contact_list(contacts_list=None):
    contact_listbox.delete(0, tk.END)

    if contacts_list is None:
        contacts_list = contacts

    for contact in contacts_list:
        contact_listbox.insert(tk.END, f"{contact['name']}: {contact['phone']}")


def clear_entries():
    name_entry.delete(0, tk.END)
    phone_entry.delete(0, tk.END)


def on_select_contact(event):
    selected_contact = contact_listbox.curselection()

    if not selected_contact:
        return

    selected_contact = selected_contact[0]
    contact = contacts[selected_contact]

    name_entry.delete(0, tk.END)
    name_entry.insert(tk.END, contact['name'])

    phone_entry.delete(0, tk.END)
    phone_entry.insert(tk.END, contact['phone'])


if __name__ == '__main__':
    load_contacts()

    root = tk.Tk()
    root.title('Contact Manager')

    # Contact List
    contact_listbox = tk.Listbox(root, width=50)
    contact_listbox.pack(pady=10)
    contact_listbox.bind('<<ListboxSelect>>', on_select_contact)

    # Contact Details
    details_frame = tk.Frame(root)
    details_frame.pack()

    name_label = tk.Label(details_frame, text='Name:')
    name_label.grid(row=0, column=0, sticky=tk.W, padx=5)

    name_entry = tk.Entry(details_frame)
    name_entry.grid(row=0, column=1, padx=5)

    phone_label = tk.Label(details_frame, text='Phone:')
    phone_label.grid(row=1, column=0, sticky=tk.W, padx=5)

    phone_entry = tk.Entry(details_frame)
    phone_entry.grid(row=1, column=1, padx=5)

    # Buttons
    button_frame = tk.Frame(root)
    button_frame.pack(pady=10)

    add_button = tk.Button(button_frame, text='Add', command=add_contact)
    add_button.grid(row=0, column=0, padx=5)

    edit_button = tk.Button(button_frame, text='Edit', command=edit_contact)
    edit_button.grid(row=0, column=1, padx=5)

    delete_button = tk.Button(button_frame, text='Delete', command=delete_contact)
    delete_button.grid(row=0, column=2, padx=5)

    # Search
    search_frame = tk.Frame(root)
    search_frame.pack()

    search_label = tk.Label(search_frame, text='Search:')
    search_label.grid(row=0, column=0, sticky=tk.W, padx=5)

    search_entry = tk.Entry(search_frame)
    search_entry.grid(row=0, column=1, padx=5)

    search_button = tk.Button(search_frame, text='Search', command=search_contact)
    search_button.grid(row=0, column=2, padx=5)

    update_contact_list()

    root.mainloop()