import tkinter as tk
from tkinter import messagebox
from datetime import datetime
from tkinter import ttk 

class list_box:
    

    def __init__(self, master):
        self.master = master
        self.master.title("To-Do List App")
        
        
        self.primary_color = "#225"  
        self.secondary_color = "#00CCFF"
        
        self.tasks = []
        
        self.master.configure(bg=self.primary_color)
        
        self.task_entry = ttk.Entry(master, width=40)
        self.task_entry.grid(row=0, column=0, padx=10, pady=10)
        
        self.add_butt = ttk.Button(master, text="Add Task", command=self.add_task)
        self.add_butt.grid(row=0, column=1, padx=5, pady=10)
        
        self.task_listbox = tk.Listbox(master, width=50)
        self.task_listbox.grid(row=1, column=0, columnspan=2, padx=10, pady=10)
        
        self.remove_butt = ttk.Button(master, text="Remove Task", command=self.remove_task)
        self.remove_butt.grid(row=2, column=1, padx=10, pady=10, sticky="we")

        self.sort_by_priority_butt = ttk.Button(master, text="Sort by Priority", command=self.sort_by_priority) 
        self.sort_by_priority_butt.grid(row=2, column=0, padx=10, pady=10, sticky="we")  

        self.sort_by_due_date_butt = tk.Button(master, text="Sort by Due Date", command=self.sort_by_due_date)
        self.sort_by_due_date_butt.grid(row=3, column=0, padx=10, pady=10, sticky="we")
        
        
        self.add_butt.configure(style='Primary.TButton')
        self.remove_butt.configure(style='Primary.TButton')
        self.sort_by_priority_butt.configure(style='Primary.TButton')
        
        
        self.style = ttk.Style()
        self.style.configure('Primary.TButton', background=self.secondary_color)
        
        self.complete_butt = ttk.Button(master, text="Mark as Completed", command=self.mark_complete)
        self.complete_butt.grid(row=3, column=1, padx=10, pady=10, sticky="we") 
        
        self.search_entry = ttk.Entry(master,width=40)
        self.search_entry.grid(row=4, column=0, padx=10, pady=10)
        
        self.search_button = ttk.Button(master, text="Search", command=self.search_task)
        self.search_button.grid(row=4, column=1, padx=5, pady=10, sticky="we")
        
        self.save_button = ttk.Button(master, text="Save Tasks", command=self.save_tasks)
        self.save_button.grid(row=5, column=0, columnspan=2, padx=10, pady=10, sticky="we")
        
        
        self.style.configure('TFrame', background=self.primary_color)
        
        self.load_tasks()

    def add_task(self): 
        task = self.task_entry.get().strip()
        if task:
            due_date = datetime.now()
            priority = ""  
            self.tasks.append({"task": task , "completed": False ,"due_date": due_date , "priority": priority})
            self.update_task_listbox()
            self.task_entry.delete(0, tk.END)
            self.save_tasks()
        else:
            messagebox.showwarning("Warning", "Task cannot be empty!")

    def remove_task(self): 
        selected_index = self.task_listbox.curselection()
        if selected_index:
            self.tasks.pop(selected_index[0])
            self.update_task_listbox()
            self.save_tasks()

    def mark_complete(self):
        selected_index = self.task_listbox.curselection()
        if selected_index:
         self.tasks[selected_index[0]]["completed"] = True
         self.update_task_listbox()
         self.save_tasks()
        self.task_listbox.itemconfig(selected_index, fg="green", text=f"✅ {self.tasks[selected_index[0]]['task']}")


    def sort_by_priority(self):
        try:
            self.tasks.sort(key=lambda x: x["priority"])
            self.update_task_listbox()
        except Exception as e:
            print(f"Error sorting by priority: {e}")

    def sort_by_due_date(self):
        try:
            self.tasks.sort(key=lambda x: x.get("due_date",datetime.max))
            self.update_task_listbox()
        except Exception as e:
            print(f"Error sorting by due date: {e}")

    def update_task_listbox(self):
        self.task_listbox.delete(0, tk.END)
        for task in self.tasks:
            if task["completed"]:
            
                self.task_listbox.insert(tk.END, f"{task['task']} (Completed ✅)")
            else:
                self.task_listbox.insert(tk.END, task["task"])

    def save_tasks(self):
        try:
            with open("tasks.txt", "w") as f:
                for task in self.tasks:
                    f.write(f"{task['task']},{task['completed']},{task['priority']}\n")
        except Exception as e:
            messagebox.showerror("Error", f"Failed to save tasks: {str(e)}")

    def load_tasks(self):
        try:
            with open("tasks.txt", "r") as f:
                for line in f:
                    task, completed, priority = line.strip().split(",")
                    self.tasks.append({"task": task, "completed": bool(completed), "priority": priority})
                self.update_task_listbox()
        except FileNotFoundError:
            pass
        except Exception as e:
            print(f"Error loading tasks: {e}")

    def search_task(self):
        search_text = self.search_entry.get().strip()
        if search_text:
           matching_tasks = [task for task in self.tasks if search_text.lower() in task['task'].lower()]
           self.display_search_results(matching_tasks)
           self.search_entry.config(foreground="green")
        else:
           self.update_task_listbox()
           self.search_entry.config(foreground="black")
        

    def display_search_results(self, matching_tasks):
        self.task_listbox.delete(0, tk.END)
        for task in matching_tasks:
            if task["completed"]:
                self.task_listbox.insert(tk.END, f"{task['task']} (Completed)")
            else:
                self.task_listbox.insert(tk.END, task["task"])

root = tk.Tk()
app = list_box(root)
root.mainloop()
















