import os
import zipfile
import tkinter as tk
from tkinter import filedialog, messagebox

DEFAULT_EXTENSIONS = ".py, .yml"
DEFAULT_MAX_SIZE_KB = 100


def browse_directory(entry):
    path = filedialog.askdirectory()
    if path:
        entry.delete(0, tk.END)
        entry.insert(0, path)


def create_zip():
    input_dir = input_dir_entry.get().strip()
    extensions = ext_entry.get().strip()
    max_size_kb = size_entry.get().strip()
    excluded_folders = exclude_entry.get().strip()

    if not input_dir or not os.path.isdir(input_dir):
        messagebox.showerror("Error", "Please select a valid input directory.")
        return

    try:
        max_size_bytes = int(max_size_kb) * 1024
    except ValueError:
        messagebox.showerror("Error", "Max file size must be a number.")
        return

    ext_list = [e.strip().lower() for e in extensions.split(",") if e.strip()]
    exclude_list = [e.strip() for e in excluded_folders.split(",") if e.strip()]

    zip_path = filedialog.asksaveasfilename(
        defaultextension=".zip",
        filetypes=[("ZIP files", "*.zip")]
    )

    if not zip_path:
        return

    file_count = 0

    try:
        with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zipf:
            for root, dirs, files in os.walk(input_dir):
                # Remove excluded directories in-place
                dirs[:] = [
                    d for d in dirs
                    if d not in exclude_list
                ]

                for file in files:
                    file_path = os.path.join(root, file)
                    rel_path = os.path.relpath(file_path, input_dir)

                    if ext_list and not any(file.lower().endswith(ext) for ext in ext_list):
                        continue

                    if os.path.getsize(file_path) > max_size_bytes:
                        continue

                    zipf.write(file_path, rel_path)
                    file_count += 1

        messagebox.showinfo(
            "Success",
            f"ZIP created successfully!\nFiles added: {file_count}"
        )

    except Exception as e:
        messagebox.showerror("Error", str(e))


# ---- GUI SETUP ----

root = tk.Tk()
root.title("Selective Directory Zipper")
root.geometry("680x240")
root.resizable(False, False)

pad = {"padx": 10, "pady": 5}

tk.Label(root, text="Input Directory:").grid(row=0, column=0, sticky="w", **pad)
input_dir_entry = tk.Entry(root, width=45)
input_dir_entry.grid(row=0, column=1, **pad)
tk.Button(root, text="Browse", command=lambda: browse_directory(input_dir_entry)).grid(row=0, column=2, **pad)

tk.Label(root, text="File Extensions (comma-separated):").grid(row=1, column=0, sticky="w", **pad)
ext_entry = tk.Entry(root, width=45)
ext_entry.insert(0, DEFAULT_EXTENSIONS)
ext_entry.grid(row=1, column=1, columnspan=2, **pad)

tk.Label(root, text="Max File Size (KB):").grid(row=2, column=0, sticky="w", **pad)
size_entry = tk.Entry(root, width=45)
size_entry.insert(0, str(DEFAULT_MAX_SIZE_KB))
size_entry.grid(row=2, column=1, columnspan=2, **pad)

tk.Label(root, text="Exclude Subfolders (comma-separated):").grid(row=3, column=0, sticky="w", **pad)
exclude_entry = tk.Entry(root, width=45)
exclude_entry.grid(row=3, column=1, columnspan=2, **pad)

tk.Button(
    root,
    text="Create ZIP",
    command=create_zip,
    bg="#4CAF50",
    fg="white",
    height=2
).grid(row=4, column=0, columnspan=3, pady=20)

root.mainloop()
