
import tkinter as tk
import sqlite3

connection = sqlite3.connect("users.db")
cursor = connection.cursor()

cursor.execute("""
CREATE TABLE IF NOT EXISTS USERS(
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    username TEXT UNIQUE,
    password TEXT
)
""")


cursor.execute("""
CREATE TABLE IF NOT EXISTS TASKS(
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id INTEGER,
    task TEXT,
    checked BOOLEAN DEFAULT 0
)
""")

connection.commit()

root = tk.Tk()

root.title("Todo App")
root.geometry("950x650")
root.configure(bg="#1e1e1e")

root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

current_user_id = 0

BG = "#1e1e1e"
CARD = "#2a2a2a"
ACCENT = "#06a099"
TEXT = "white"

login_frame = tk.Frame(root, bg=BG)
signup_frame = tk.Frame(root, bg=BG)
app_frame = tk.Frame(root, bg=BG)

for frame in (login_frame, signup_frame, app_frame):
    frame.grid(row=0, column=0, sticky="nsew")

def show_login():
    login_frame.tkraise()
    login_label.config(text="")
    login_username_entry.delete(0, tk.END)
    login_password_entry.delete(0, tk.END)
    login_username_entry.focus()

def show_signup():
    signup_frame.tkraise()
    signup_label.config(text="")
    signup_username_entry.delete(0, tk.END)
    signup_password_entry.delete(0, tk.END)
    signup_username_entry.focus()

def show_app():
    app_frame.tkraise()


#login
login_card = tk.Frame(
    login_frame,
    bg=CARD,
    padx=40,
    pady=40
)

login_card.place(relx=0.5, rely=0.5, anchor="center")


login_title = tk.Label(
    login_card,
    text="LOGIN",
    bg=CARD,
    fg=ACCENT,
    font=("Arial", 28, "bold")
)

login_title.pack(pady=(0, 20))


login_label = tk.Label(
    login_card,
    text="",
    bg=CARD,
    fg="red",
    font=("Arial", 12)
)

login_label.pack()


login_username_entry = tk.Entry(
    login_card,
    width=30,
    font=("Arial", 14),
    relief="flat"
)

login_username_entry.pack(pady=10, ipady=8)


login_password_entry = tk.Entry(
    login_card,
    width=30,
    font=("Arial", 14),
    show="*",
    relief="flat"
)

login_password_entry.pack(pady=10, ipady=8)


#signup
signup_card = tk.Frame(
    signup_frame,
    bg=CARD,
    padx=40,
    pady=40
)

signup_card.place(relx=0.5, rely=0.5, anchor="center")


signup_title = tk.Label(
    signup_card,
    text="SIGN UP",
    bg=CARD,
    fg=ACCENT,
    font=("Arial", 28, "bold")
)

signup_title.pack(pady=(0, 20))


signup_label = tk.Label(
    signup_card,
    text="",
    bg=CARD,
    fg="red",
    font=("Arial", 12)
)

signup_label.pack()


signup_username_entry = tk.Entry(
    signup_card,
    width=30,
    font=("Arial", 14),
    relief="flat"
)

signup_username_entry.pack(pady=10, ipady=8)


signup_password_entry = tk.Entry(
    signup_card,
    width=30,
    font=("Arial", 14),
    show="*",
    relief="flat"
)

signup_password_entry.pack(pady=10, ipady=8)

#app
app_frame.grid_rowconfigure(2, weight=1)
app_frame.grid_columnconfigure(0, weight=1)


app_title = tk.Label(
    app_frame,
    text="TODO APP",
    bg=BG,
    fg=ACCENT,
    font=("Arial", 30, "bold")
)

app_title.grid(row=0, column=0, pady=20)


input_frame = tk.Frame(app_frame, bg=BG)
input_frame.grid(row=1, column=0, pady=10)


todo_entry = tk.Entry(
    input_frame,
    width=40,
    font=("Arial", 14),
    relief="flat"
)


todo_entry.grid(row=0, column=0, ipady=8, padx=5)

canvas = tk.Canvas(
    app_frame,
    bg=BG,
    highlightthickness=0
)

scrollbar = tk.Scrollbar(
    app_frame,
    orient="vertical",
    command=canvas.yview
)


tasks_container = tk.Frame(canvas, bg=BG)


canvas.configure(yscrollcommand=scrollbar.set)

canvas.grid(row=2, column=0, sticky="nsew")
scrollbar.grid(row=2, column=1, sticky="ns")


canvas.create_window(
    (0, 0),
    window=tasks_container,
    anchor="nw"
)

def refresh_scroll_region(event=None):
    canvas.configure(scrollregion=canvas.bbox("all"))



tasks_container.bind("<Configure>", refresh_scroll_region)



def check_task(task_id, check_var):

    checked = check_var.get()

    cursor.execute(
        "UPDATE TASKS SET checked=? WHERE id=?",
        (checked, task_id)
    )

    connection.commit()



def remove_task(task_frame, task_id):

    task_frame.destroy()

    cursor.execute(
        "DELETE FROM TASKS WHERE id=?",
        (task_id,)
    )

    connection.commit()



def edit_task(label, task_id):

    current_text = label.cget("text")

    edit_entry = tk.Entry(
        label.master,
        width=30,
        font=("Arial", 12)
    )

    edit_entry.insert(0, current_text)

    label.pack_forget()

    edit_entry.pack(side="left", padx=10)

    def save_edit(event=None):

        new_text = edit_entry.get()

        label.config(text=new_text)

        cursor.execute(
            "UPDATE TASKS SET task=? WHERE id=?",
            (new_text, task_id)
        )

        connection.commit()

        edit_entry.destroy()

        label.pack(side="left", padx=10)

    edit_entry.bind("<Return>", save_edit)
    edit_entry.bind("<FocusOut>", save_edit)

    edit_entry.focus()



def create_task(task_text, task_id, checked):

    task_frame = tk.Frame(
        tasks_container,
        bg=CARD,
        pady=10,
        padx=10
    )

    task_frame.pack(
        fill="x",
        padx=20,
        pady=5
    )

    check_var = tk.BooleanVar(value=checked)

    checkbox = tk.Checkbutton(
        task_frame,
        variable=check_var,
        bg=CARD,
        command=lambda: check_task(task_id, check_var)
    )

    checkbox.pack(side="left")


    task_label = tk.Label(
        task_frame,
        text=task_text,
        bg=CARD,
        fg=TEXT,
        font=("Arial", 13)
    )

    task_label.pack(side="left", padx=10)


    task_label.bind(
        "<Double-Button-1>",
        lambda e: edit_task(task_label, task_id)
    )


    remove_button = tk.Button(
        task_frame,
        text="X",
        bg="#ff4d4d",
        fg="white",
        relief="flat",
        command=lambda: remove_task(task_frame, task_id)
    )

    remove_button.pack(side="right")



def add_task(event=None):

    task = todo_entry.get()

    if task == "":
        return

    cursor.execute(
        "INSERT INTO TASKS(user_id, task, checked) VALUES(?, ?, ?)",
        (current_user_id, task, False)
    )

    connection.commit()

    task_id = cursor.lastrowid

    create_task(task, task_id, False)

    todo_entry.delete(0, tk.END)

def login_app():

    global current_user_id

    cursor.execute(
        "SELECT * FROM USERS WHERE username=? AND password=?",
        (
            login_username_entry.get(),
            login_password_entry.get()
        )
    )

    result = cursor.fetchone()

    if result:

        current_user_id = result[0]

        show_app()

        for widget in tasks_container.winfo_children():
            widget.destroy()

        cursor.execute(
            "SELECT * FROM TASKS WHERE user_id=?",
            (current_user_id,)
        )

        tasks = cursor.fetchall()

        for task in tasks:

            create_task(
                task[2],
                task[0],
                task[3]
            )

    else:

        login_label.config(
            text="Incorrect details"
        )



def signup_app():

    username = signup_username_entry.get()
    password = signup_password_entry.get()

    if not username or not password:

        signup_label.config(
            text="Fill all fields"
        )

        return

    try:

        cursor.execute(
            "INSERT INTO USERS(username, password) VALUES(?, ?)",
            (username, password)
        )

        connection.commit()

        signup_label.config(
            text="Account created!",
            fg="lightgreen"
        )

        show_login()

    except:

        signup_label.config(
            text="Username already exists"
        )

login_button = tk.Button(
    login_card,
    text="Login",
    bg=ACCENT,
    fg="white",
    width=20,
    relief="flat",
    command=login_app
)

login_button.pack(pady=10, ipady=5)


signup_page_button = tk.Button(
    login_card,
    text="Create Account",
    bg="#444",
    fg="white",
    relief="flat",
    command=show_signup
)

signup_page_button.pack()


signup_button = tk.Button(
    signup_card,
    text="Sign Up",
    bg=ACCENT,
    fg="white",
    width=20,
    relief="flat",
    command=signup_app
)

signup_button.pack(pady=10, ipady=5)


back_button = tk.Button(
    signup_card,
    text="Back To Login",
    bg="#444",
    fg="white",
    relief="flat",
    command=show_login
)

back_button.pack()


add_button = tk.Button(
    input_frame,
    text="ADD",
    bg=ACCENT,
    fg="white",
    relief="flat",
    command=add_task
)

add_button.grid(row=0, column=1, padx=5, ipady=5)

def app_loop():
    todo_entry.bind("<Return>", add_task)

    show_login()
    root.mainloop()

app_loop()



