import os
import shutil
import tkinter as tk
from tkinter import messagebox, simpledialog
from tkinter import ttk
import subprocess

def start(window, app_manager=None, **kwargs):
    top_frame = tk.Frame(window, bg="lightgray")
    top_frame.pack(side="top", fill="x")
    
    icon_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "icons")
    window.icons = {}
    for iname in ['menu_new_folder', 'menu_new_file', 'menu_rename', 'menu_delete', 'icon_folder', 'icon_file_txt', 'icon_file_py', 'icon_file_img', 'icon_file_generic', 'btn_search', 'btn_network', 'btn_disconnect', 'btn_paste', 'btn_print', 'btn_refresh']:
        ipath = os.path.join(icon_dir, iname + ".png")
        if os.path.exists(ipath):
            window.icons[iname] = tk.PhotoImage(file=ipath)

    # Initialize Clipboard on Desktop
    if app_manager and not hasattr(app_manager.desktop, "file_clipboard"):
        app_manager.desktop.file_clipboard = {"action": None, "path": None}

    def go_up():
        current = path_var.get()
        parent = os.path.dirname(current)
        if parent != current:
            path_var.set(parent)
            refresh_list()
    
    path_var = tk.StringVar(value=os.path.expanduser("~"))
    path_entry = tk.Entry(top_frame, textvariable=path_var)
    path_entry.pack(side="left", fill="x", expand=True, padx=2, pady=2)

    def connect_network():
        pwd = app_manager.desktop.settings.get("sudo_pwd") if app_manager else None
        if not pwd:
            messagebox.showerror("Erreur", "Veuillez configurer votre mot de passe système dans Paramètres.")
            return
            
        dialog = tk.Toplevel(window)
        dialog.title("Connecter Réseau (SMB)")
        dialog.geometry("600x480")
        dialog.transient(window)
        dialog.grab_set()
        
        frame_top = tk.Frame(dialog)
        frame_top.pack(fill="both", expand=True, padx=10, pady=5)
        
        tk.Label(frame_top, text="Adresses découvertes sur le réseau :").pack(anchor="w")
        
        tree_frame = tk.Frame(frame_top)
        tree_frame.pack(fill="both", expand=True, pady=5)
        
        scroll = tk.Scrollbar(tree_frame)
        scroll.pack(side="right", fill="y")
        
        tree_shares = ttk.Treeview(tree_frame, show="tree", yscrollcommand=scroll.set, height=8)
        tree_shares.pack(side="left", fill="both", expand=True)
        scroll.config(command=tree_shares.yview)
        
        def scan_network():
            import socket
            import threading
            
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            try:
                s.connect(('10.255.255.255', 1))
                local_ip = s.getsockname()[0]
            except Exception:
                local_ip = "192.168.1.1"
            finally:
                s.close()
                
            subnet = ".".join(local_ip.split(".")[:3]) + "."
            found_ips = []
            
            def check_ip(ip):
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(0.3)
                try:
                    if sock.connect_ex((ip, 445)) == 0:
                        found_ips.append(ip)
                except Exception: pass
                finally: sock.close()

            threads = []
            for i in range(1, 255):
                t = threading.Thread(target=check_ip, args=(subnet + str(i),))
                threads.append(t)
                t.start()
                
            for t in threads:
                t.join()
                
            # Now extract shares and hostnames using smbclient if installed
            detailed_shares = {}
            for ip in found_ips:
                hostname = ""
                try:
                    res_nmb = subprocess.run(['nmblookup', '-A', ip], capture_output=True, text=True, timeout=1)
                    if res_nmb.returncode == 0:
                        for line in res_nmb.stdout.split('\n'):
                            if '<00>' in line and 'GROUP' not in line:
                                hostname = line.split('<00>')[0].strip()
                                break
                except: pass
                
                display_name = f"{hostname} ({ip})" if hostname else f"[{ip}]"
                detailed_shares[display_name] = []
                
                try:
                    res_smb = subprocess.run(['smbclient', '-L', ip, '-N', '-g'], capture_output=True, text=True, timeout=2)
                    if res_smb.returncode == 0:
                        has_shares = False
                        for line in res_smb.stdout.split('\n'):
                            if line.startswith('Disk|'):
                                parts = line.split('|')
                                if len(parts) >= 2:
                                    share_name = parts[1]
                                    if share_name not in ('print$', 'IPC$'):
                                        detailed_shares[display_name].append(f"//{ip}/{share_name}")
                                        has_shares = True
                        if not has_shares:
                            detailed_shares[display_name].append(f"//{ip}/Partage")
                    else:
                        detailed_shares[display_name].append(f"//{ip}/Partage")
                except:
                    detailed_shares[display_name].append(f"//{ip}/Partage")
                    
            return detailed_shares
            
        def on_scan(auto=False):
            btn_scan.config(state="disabled", text="Recherche...")
            dialog.update()
            shares = scan_network()
            btn_scan.config(state="normal", text=" Actualiser", image=window.icons.get('btn_search'), compound="left")
            tree_shares.delete(*tree_shares.get_children())
            if shares:
                icon_folder = window.icons.get('icon_folder')
                for machine, share_list in shares.items():
                    machine_id = tree_shares.insert("", "end", text=f" {machine}", open=False)
                    for share in share_list:
                        share_name = share.split('/')[-1]
                        
                        # Check if already mounted
                        parts = share.strip("/").split("/")
                        if len(parts) >= 2:
                            ip_addr = parts[0]
                            mount_p = os.path.expanduser(f"~/Réseau/{ip_addr}/{share_name}")
                            disp_text = f" {share_name} (Connecté ✅)" if os.path.ismount(mount_p) else f" {share_name}"
                        else:
                            disp_text = f" {share_name}"
                            
                        if icon_folder:
                            tree_shares.insert(machine_id, "end", text=disp_text, image=icon_folder, values=(share,))
                        else:
                            tree_shares.insert(machine_id, "end", text=disp_text, values=(share,))
                first = tree_shares.get_children()[0]
                tree_shares.selection_set(first)
                on_tree_select(None)
                if not auto:
                    msg = f"{len(shares)} partage(s) trouvé(s) sur le réseau !"
                    if not shutil.which("smbclient"):
                        msg += "\n\n(Note: Installez 'smbclient' via le terminal système pour afficher les noms exacts des dossiers)."
                    messagebox.showinfo("Scanner", msg)
            else:
                if not auto:
                    messagebox.showinfo("Scanner", "Aucune machine trouvée.")

        def on_tree_select(e):
            selected = tree_shares.selection()
            if selected:
                item = tree_shares.item(selected[0])
                if item.get('values'):
                    share_path = item['values'][0]
                    try:
                        machine_name = tree_shares.item(tree_shares.parent(selected[0]))['text'].strip()
                        entry_share_var.set(f"{machine_name} -> {share_path}")
                    except:
                        entry_share_var.set(share_path)

        tree_shares.bind("<<TreeviewSelect>>", on_tree_select)
        
        btn_scan = tk.Button(frame_top, text=" Actualiser", image=window.icons.get('btn_search'), compound="left", command=on_scan, bg="#ffeb3b")
        btn_scan.pack(anchor="e", pady=5)
        
        tk.Label(dialog, text="Adresse du partage sélectionné (ex: NAS -> //192.168.1.10/Data):").pack(pady=(10,0))
        entry_share_var = tk.StringVar()
        entry_share = tk.Entry(dialog, textvariable=entry_share_var, width=50)
        entry_share.pack(pady=5)
        
        tk.Label(dialog, text="Nom d'utilisateur (laisser vide si invité) :").pack(pady=5)
        entry_user = tk.Entry(dialog, width=30)
        entry_user.pack(pady=5)
        
        tk.Label(dialog, text="Mot de passe :").pack(pady=5)
        entry_pass = tk.Entry(dialog, width=30, show="*")
        entry_pass.pack(pady=5)
        
        def on_connect():
            share_input = entry_share_var.get().strip()
            user = entry_user.get()
            passw = entry_pass.get()
            if not share_input: return
            
            if " -> " in share_input:
                machine_str, share = share_input.split(" -> ", 1)
            else:
                machine_str, share = "", share_input
                
            if not share.startswith("//"):
                messagebox.showerror("Erreur", "Le format doit être //IP/Partage")
                return
                
            share_parts = share.strip("/").split("/")
            if len(share_parts) < 2:
                messagebox.showerror("Erreur", "Veuillez préciser le nom du dossier à la fin (ex: //192.168.1.10/Documents)")
                return
                
            server_ip = share_parts[0]
            share_name = share_parts[1]
            
            machine_clean = machine_str.split(" (")[0]
            machine_clean = "".join(c for c in machine_clean if c.isalnum() or c in ('-','_','.')).strip()
            machine_dir = f"{machine_clean}_{server_ip}" if machine_clean and machine_clean.lower() != "inconnu" else server_ip
            
            mount_point = os.path.expanduser(f"~/Réseau/{machine_dir}/{share_name}")
            os.makedirs(mount_point, exist_ok=True)
            
            if os.path.ismount(mount_point):
                messagebox.showinfo("Information", f"Ce partage est déjà connecté dans :\n{mount_point}")
                path_var.set(mount_point)
                refresh_list()
                dialog.destroy()
                return
            
            opts = f"username={user},password={passw}" if user else "guest"
            cmd = f"mount -t cifs '{share}' '{mount_point}' -o {opts},uid=$(id -u),gid=$(id -g)"
            
            res = subprocess.run(['sudo', '-S', 'bash', '-c', cmd], input=pwd+'\n', capture_output=True, text=True)
            if res.returncode == 0:
                messagebox.showinfo("Succès", f"Partage monté dans :\n{mount_point}")
                path_var.set(mount_point)
                refresh_list()
                dialog.destroy()
            else:
                messagebox.showerror("Erreur", f"Échec du montage:\n{res.stderr}\n\nAvez-vous installé cifs-utils ?")
                
        btn_frame = tk.Frame(dialog)
        btn_frame.pack(pady=15)
        
        tk.Button(btn_frame, text="Annuler", command=dialog.destroy).pack(side="left", padx=5)
        tk.Button(btn_frame, text="Connecter", bg="lightgreen", command=on_connect).pack(side="left", padx=5)
        
        dialog.bind("<Escape>", lambda e: dialog.destroy())
        
        dialog.after(200, lambda: on_scan(auto=True))

    btn_network = tk.Button(top_frame, text=" Réseau", image=window.icons.get('btn_network'), compound="left", relief="flat", bg="lightblue", command=connect_network)
    btn_network.pack(side="right", padx=5, pady=5)
    
    def umount_all():
        pwd = app_manager.desktop.settings.get("sudo_pwd") if app_manager else None
        if not pwd: return
        reseau_dir = os.path.expanduser("~/Réseau")
        if not os.path.exists(reseau_dir): return
        
        has_unmounted = False
        for root, dirs, files in os.walk(reseau_dir, topdown=False):
            for d in dirs:
                full_path = os.path.join(root, d)
                if os.path.ismount(full_path):
                    subprocess.run(['sudo', '-S', 'umount', full_path], input=pwd+'\n', text=True)
                    has_unmounted = True
        
        subprocess.run(['sudo', '-S', 'find', reseau_dir, '-type', 'd', '-empty', '-delete'], input=pwd+'\n', text=True)
        if has_unmounted and app_manager:
            app_manager.desktop.show_toast("Tous les partages ont été déconnectés.")
            
        def finish_umount():
            if path_var.get().startswith(os.path.expanduser("~/Réseau")):
                path_var.set(os.path.expanduser("~"))
            refresh_list()
            
        window.after(500, finish_umount)

    btn_umount = tk.Button(top_frame, text=" Tout démonter", image=window.icons.get('btn_disconnect'), compound="left", relief="flat", bg="#ffcccc", command=umount_all)
    btn_umount.pack(side="right", padx=5, pady=5)
    
    btn_go = tk.Button(top_frame, text="Aller", relief="flat", command=lambda: refresh_list())
    btn_go.pack(side="right", padx=5, pady=5)
    
    show_hidden = tk.BooleanVar(value=False)
    
    list_frame = tk.Frame(window)
    list_frame.pack(fill="both", expand=True)
    
    scrollbar = tk.Scrollbar(list_frame)
    scrollbar.pack(side="right", fill="y")
    
    style = ttk.Style()
    style.configure("Explorateur.Treeview", rowheight=24, font=("Arial", 10))
    
    tree = ttk.Treeview(list_frame, show="tree", yscrollcommand=scrollbar.set, style="Explorateur.Treeview")
    tree.pack(side="left", fill="both", expand=True)
    scrollbar.config(command=tree.yview)

    def refresh_list(event=None):
        current_path = path_var.get()
        if not os.path.exists(current_path) or not os.path.isdir(current_path):
            return
            
        tree.delete(*tree.get_children())
        tree.insert("", "end", iid="..", text="   .. (Dossier parent)", image=window.icons.get('icon_folder'))
        
        try:
            items = os.listdir(current_path)
            items.sort(key=lambda x: (not os.path.isdir(os.path.join(current_path, x)), x.lower()))
            for item in items:
                if not show_hidden.get() and item.startswith('.'):
                    continue
                is_dir = os.path.isdir(os.path.join(current_path, item))
                if is_dir:
                    icon = window.icons.get('icon_folder')
                else:
                    ext = os.path.splitext(item)[1].lower()
                    if ext in ['.png', '.jpg', '.jpeg', '.gif', '.bmp']:
                        icon = window.icons.get('icon_file_img')
                    elif ext in ['.txt', '.md', '.log', '.csv']:
                        icon = window.icons.get('icon_file_txt')
                    elif ext in ['.py']:
                        icon = window.icons.get('icon_file_py')
                    else:
                        icon = window.icons.get('icon_file_generic')
                tree.insert("", "end", iid=item, text="   " + item, image=icon)
        except PermissionError:
            tree.insert("", "end", iid="ACCESS_DENIED", text="   <Accès refusé>", image=window.icons.get('icon_file_generic'))

    def get_selected_item_path(item_id):
        if not item_id or item_id == ".." or item_id == "ACCESS_DENIED":
            return None
        return os.path.join(path_var.get(), item_id)

    def on_double_click(event):
        selection = tree.selection()
        if not selection:
            return
        
        item_id = selection[0]
        current_path = path_var.get()
        
        if item_id == "..":
            new_path = os.path.dirname(current_path)
            path_var.set(new_path)
            refresh_list()
        elif item_id == "ACCESS_DENIED":
            return
        else:
            new_path = os.path.join(current_path, item_id)
            if os.path.isdir(new_path):
                path_var.set(new_path)
                refresh_list()
            else:
                ext = os.path.splitext(item_id)[1].lower()
                if ext in ['.png', '.jpg', '.jpeg', '.gif', '.bmp']:
                    if app_manager:
                        app_manager.launch_app({"name": "Visionneuse", "module": "apps.visionneuse.app"}, filepath=new_path)
                elif ext in ['.html', '.htm']:
                    if app_manager:
                        app_manager.launch_app({"name": "Navigateur Web", "module": "apps.navigateur.app"}, filepath=new_path)
                elif ext in ['.py', '.json', '.sh', '.c', '.cpp', '.h', '.js', '.css', '.md']:
                    if app_manager:
                        app_manager.launch_app({"name": "Éditeur de Code", "module": "apps.editeur.app"}, filepath=new_path)
                else:
                    if app_manager:
                        app_manager.launch_app({"name": "Bloc-notes", "module": "apps.blocnotes.app"}, filepath=new_path)

    # --- Actions de gestion de fichiers ---
    def ask_string_dialog(title, prompt, callback, initialvalue=""):
        dialog_frame = tk.Frame(window, bg="white", highlightbackground="black", highlightthickness=2)
        dialog_frame.place(relx=0.5, rely=0.5, anchor="center", width=300, height=130)
        
        tk.Label(dialog_frame, text=title, bg="lightgray", font=("Arial", 10, "bold")).pack(fill="x")
        tk.Label(dialog_frame, text=prompt, bg="white").pack(pady=5)
        
        entry_var = tk.StringVar(value=initialvalue)
        entry = tk.Entry(dialog_frame, textvariable=entry_var)
        entry.pack(padx=10, fill="x")
        
        def on_ok(event=None):
            val = entry_var.get()
            dialog_frame.destroy()
            if val:
                callback(val)
                
        def on_cancel(event=None):
            dialog_frame.destroy()
            
        btn_frame = tk.Frame(dialog_frame, bg="white")
        btn_frame.pack(pady=10)
        tk.Button(btn_frame, text="OK", command=on_ok, width=8).pack(side="left", padx=5)
        tk.Button(btn_frame, text="Annuler", command=on_cancel, width=8).pack(side="left", padx=5)
        
        entry.bind("<Return>", on_ok)
        entry.bind("<Escape>", on_cancel)
        
        window.after(100, lambda: entry.focus_set())

    def new_file():
        def on_name(name):
            try:
                new_path = os.path.join(path_var.get(), name)
                if not os.path.exists(new_path):
                    open(new_path, 'a').close()
                    refresh_list()
                else:
                    messagebox.showerror("Erreur", "Un fichier avec ce nom existe déjà.")
            except Exception as e:
                messagebox.showerror("Erreur", f"Impossible de créer le fichier :\n{e}")
        ask_string_dialog("Nouveau Fichier", "Nom du nouveau fichier texte :", on_name)

    def new_folder():
        def on_name(name):
            try:
                new_path = os.path.join(path_var.get(), name)
                os.makedirs(new_path, exist_ok=False)
                refresh_list()
            except Exception as e:
                messagebox.showerror("Erreur", f"Impossible de créer le dossier :\n{e}")
        ask_string_dialog("Nouveau Dossier", "Nom du nouveau dossier :", on_name)

    def rename_item(item_id):
        old_path = get_selected_item_path(item_id)
        if not old_path: return
        old_name = os.path.basename(old_path)
        
        def on_name(new_name):
            if new_name != old_name:
                try:
                    new_path = os.path.join(os.path.dirname(old_path), new_name)
                    os.rename(old_path, new_path)
                    refresh_list()
                except Exception as e:
                    messagebox.showerror("Erreur", f"Impossible de renommer :\n{e}")
                    
        ask_string_dialog("Renommer", "Nouveau nom :", on_name, initialvalue=old_name)

    def delete_item(item_id):
        target_path = get_selected_item_path(item_id)
        if not target_path: return
        
        if target_path.startswith(os.path.expanduser("~/Réseau")):
            messagebox.showerror("Interdit", "La suppression est interdite sur les partages réseau montés par sécurité.")
            return
            
        target_name = os.path.basename(target_path)
        is_dir = os.path.isdir(target_path)
        
        msg = f"Voulez-vous vraiment supprimer définitivement le {'dossier' if is_dir else 'fichier'} '{target_name}' ?"
        if is_dir:
            msg += "\n\nATTENTION: Tout le contenu du dossier sera supprimé !"
            
        if messagebox.askyesno("Confirmer la suppression", msg, icon='warning'):
            try:
                if is_dir:
                    shutil.rmtree(target_path)
                else:
                    os.remove(target_path)
                refresh_list()
            except Exception as e:
                messagebox.showerror("Erreur", f"Impossible de supprimer :\n{e}")

    def create_shortcut(item_id):
        target_path = get_selected_item_path(item_id)
        if not target_path: return
        
        target_name = os.path.basename(target_path)
        
        import json
        desktop_config_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "config", "desktop.json")
        try:
            icons = []
            if os.path.exists(desktop_config_path):
                with open(desktop_config_path, "r") as f:
                    icons = json.load(f)
            
            x = 20 + (len(icons) % 10) * 80
            y = 20 + (len(icons) // 10) * 80
            
            icons.append({"name": target_name, "path": target_path, "x": x, "y": y})
            
            with open(desktop_config_path, "w") as f:
                json.dump(icons, f, indent=4)
                
            if app_manager and hasattr(app_manager, "desktop"):
                app_manager.desktop.load_desktop_icons()
                app_manager.desktop.show_toast(f"Raccourci '{target_name}' créé.")
        except Exception as e:
            messagebox.showerror("Erreur", f"Impossible de créer le raccourci :\n{e}")

    def print_item(item_id):
        target_path = get_selected_item_path(item_id)
        if not target_path or os.path.isdir(target_path): return
        
        try:
            res = subprocess.run(['lp', target_path], capture_output=True, text=True)
            if res.returncode == 0:
                if app_manager and hasattr(app_manager, "desktop"):
                    app_manager.desktop.show_toast(f"Impression lancée pour '{os.path.basename(target_path)}'")
                else:
                    messagebox.showinfo("Impression", f"Fichier envoyé à l'imprimante :\n{os.path.basename(target_path)}")
            else:
                messagebox.showerror("Erreur Impression", f"Impossible d'imprimer:\n{res.stderr}\n\nAvez-vous configuré une imprimante par défaut ?")
        except FileNotFoundError:
            messagebox.showerror("Erreur", "La commande 'lp' est introuvable. Installez 'cups' pour imprimer.")

    def copy_item(item_id):
        if not app_manager: return
        target_path = get_selected_item_path(item_id)
        if target_path:
            app_manager.desktop.file_clipboard = {"action": "copy", "path": target_path}
            app_manager.desktop.show_toast(f"Copié : {os.path.basename(target_path)}")

    def cut_item(item_id):
        if not app_manager: return
        target_path = get_selected_item_path(item_id)
        if target_path:
            app_manager.desktop.file_clipboard = {"action": "cut", "path": target_path}
            app_manager.desktop.show_toast(f"Coupé : {os.path.basename(target_path)}")

    def paste_item():
        if not app_manager or not hasattr(app_manager.desktop, "file_clipboard"): return
        clip = app_manager.desktop.file_clipboard
        if not clip.get("path"): return
        
        src = clip["path"]
        action = clip["action"]
        dst_dir = path_var.get()
        dst = os.path.join(dst_dir, os.path.basename(src))
        
        if not os.path.exists(src):
            messagebox.showerror("Erreur", "Le fichier source n'existe plus.")
            return
            
        if os.path.exists(dst):
            messagebox.showerror("Erreur", "Un fichier ou dossier de ce nom existe déjà ici.")
            return
            
        try:
            if action == "copy":
                if os.path.isdir(src):
                    shutil.copytree(src, dst)
                else:
                    shutil.copy2(src, dst)
                app_manager.desktop.show_toast(f"Collé : {os.path.basename(src)}")
            elif action == "cut":
                shutil.move(src, dst)
                app_manager.desktop.file_clipboard = {"action": None, "path": None}
                app_manager.desktop.show_toast(f"Déplacé : {os.path.basename(src)}")
            refresh_list()
        except Exception as e:
            messagebox.showerror("Erreur", f"Erreur :\n{e}")

    def disconnect_network(m_path):
        pwd = app_manager.desktop.settings.get("sudo_pwd") if app_manager else None
        if not pwd: return
        
        has_unmounted = False
        if os.path.ismount(m_path):
            subprocess.run(['sudo', '-S', 'umount', m_path], input=pwd+'\n', text=True)
            has_unmounted = True
        else:
            for root, dirs, files in os.walk(m_path, topdown=False):
                for d in dirs:
                    full_p = os.path.join(root, d)
                    if os.path.ismount(full_p):
                        subprocess.run(['sudo', '-S', 'umount', full_p], input=pwd+'\n', text=True)
                        has_unmounted = True
                        
        if has_unmounted:
            subprocess.run(['sudo', '-S', 'find', m_path, '-type', 'd', '-empty', '-delete'], input=pwd+'\n', text=True)
            if not os.path.exists(m_path):
                # Clean up parent if it became empty
                parent = os.path.dirname(m_path)
                subprocess.run(['sudo', '-S', 'find', parent, '-type', 'd', '-empty', '-delete'], input=pwd+'\n', text=True)
                
            if app_manager: app_manager.desktop.show_toast(f"Déconnecté : {os.path.basename(m_path)}")
            
            def finish_disconnect():
                if not os.path.exists(path_var.get()):
                    path_var.set(os.path.expanduser("~/Réseau"))
                refresh_list()
                
            window.after(500, finish_disconnect)
        else:
            messagebox.showerror("Erreur", "Aucun point de montage actif trouvé ici.")

    # --- Menu Contextuel ---
    context_menu = tk.Menu(window, tearoff=0)
    
    def show_context_menu(event):
        item_id = tree.identify_row(event.y)
        
        tree.selection_remove(tree.selection())
        context_menu.delete(0, tk.END)
        
        if item_id:
            tree.selection_set(item_id)
            target_path = get_selected_item_path(item_id)
            
            if item_id not in ("..", "ACCESS_DENIED"):
                context_menu.add_command(label=" Copier", command=lambda: window.after(50, copy_item, item_id))
                
                if not target_path.startswith(os.path.expanduser("~/Réseau")):
                    context_menu.add_command(label=" Couper", command=lambda: window.after(50, cut_item, item_id))
                    context_menu.add_separator()
                    context_menu.add_command(label=" Renommer", image=window.icons.get('menu_rename'), compound="left", command=lambda: window.after(50, rename_item, item_id))
                    context_menu.add_command(label=" Supprimer", image=window.icons.get('menu_delete'), compound="left", command=lambda: window.after(50, delete_item, item_id))
                else:
                    context_menu.add_separator()
                    
                context_menu.add_command(label=" Raccourci Bureau", command=lambda: window.after(50, create_shortcut, item_id))
                
                if target_path and os.path.isfile(target_path):
                    ext = os.path.splitext(target_path)[1].lower()
                    if ext in ['.txt', '.py', '.md', '.json', '.log', '.csv', '.png', '.jpg', '.jpeg']:
                        context_menu.add_command(label=" Imprimer", image=window.icons.get('btn_print'), compound="left", command=lambda: window.after(50, print_item, item_id))
                        
                if target_path and target_path.startswith(os.path.expanduser("~/Réseau")) and target_path != os.path.expanduser("~/Réseau"):
                    rel_path = os.path.relpath(target_path, os.path.expanduser("~/Réseau"))
                    if len(rel_path.split(os.sep)) <= 2:
                        context_menu.add_command(label=" Déconnecter", image=window.icons.get('menu_delete'), compound="left", command=lambda p=target_path: window.after(50, disconnect_network, p))
                    
                context_menu.add_separator()
        
        if app_manager and hasattr(app_manager.desktop, "file_clipboard") and app_manager.desktop.file_clipboard.get("path"):
            context_menu.add_command(label=" Coller", image=window.icons.get('btn_paste'), compound="left", command=lambda: window.after(50, paste_item))
            context_menu.add_separator()
            
        context_menu.add_command(label=" Nouveau dossier", image=window.icons.get('menu_new_folder'), compound="left", command=lambda: window.after(50, new_folder))
        context_menu.add_command(label=" Nouveau fichier texte", image=window.icons.get('menu_new_file'), compound="left", command=lambda: window.after(50, new_file))
        
        try:
            context_menu.tk_popup(event.x_root, event.y_root)
        finally:
            context_menu.grab_release()

    # Bindings
    tree.bind("<Double-Button-1>", on_double_click)
    tree.bind("<Button-3>", show_context_menu) # Clic droit
    
    # Fermer le menu si on clique ailleurs
    window.bind("<Button-1>", lambda e: context_menu.unpost(), add="+")
    tree.bind("<Button-1>", lambda e: context_menu.unpost(), add="+")
    
    path_entry.bind("<Return>", refresh_list)
    
    # Boutons d'accès rapide
    btn_go = tk.Button(top_frame, text="Aller", command=refresh_list, relief="flat")
    btn_go.pack(side="right", padx=2, pady=2)
    
    btn_term = tk.Button(top_frame, text=">_ Terminal", command=lambda: app_manager.launch_app({"name": "Terminal", "module": "apps.terminal.app"}, filepath=path_var.get()) if app_manager else None, relief="flat", bg="#e0e0e0")
    btn_term.pack(side="right", padx=5, pady=2)
    
    chk_hidden = tk.Checkbutton(top_frame, text="Fichiers cachés", variable=show_hidden, command=refresh_list, bg="lightgray")
    chk_hidden.pack(side="right", padx=5)
    
    def show_help():
        msg = (
            "Aide de l'Explorateur\n\n"
            "Navigation :\n"
            "• Double-cliquez sur un dossier pour y entrer.\n"
            "• Double-cliquez sur '.. (Dossier parent)' pour remonter.\n"
            "• Double-cliquez sur un fichier pour l'ouvrir.\n\n"
            "Actions :\n"
            "• Clic-droit sur un élément pour le renommer ou le supprimer.\n"
            "• Le menu Clic-droit permet aussi de créer des fichiers/dossiers."
        )
        messagebox.showinfo("Aide Explorateur", msg)
        
    btn_help = tk.Button(top_frame, text=" Aide", image=(app_manager.desktop.icons.get("btn_help") if app_manager else None), compound="left", command=show_help, relief="flat", bg="lightblue")
    btn_help.pack(side="right", padx=5, pady=2)
    
    refresh_list()

