"""
Interface graphique d'installation pour MyMind Portable
Affiche la progression de l'installation sans console
"""
import tkinter as tk
from tkinter import ttk
import subprocess
import sys
import os
from pathlib import Path
import threading

class InstallUI:
    """Interface d'installation avec progression"""
    
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("Installation MyMind")
        self.root.geometry("500x400")
        self.root.resizable(False, False)
        
        # Style
        self.root.configure(bg='#ffffff')
        style = ttk.Style()
        style.theme_use('clam')
        
        # Variables
        self.status_var = tk.StringVar(value="Initialisation...")
        self.progress_var = tk.DoubleVar(value=0.0)
        self.detail_var = tk.StringVar(value="")
        self.install_success = False
        
        self.setup_ui()
        
        # Centrer la fenêtre
        self.center_window()
    
    def center_window(self):
        """Centre la fenêtre à l'écran"""
        self.root.update_idletasks()
        width = self.root.winfo_width()
        height = self.root.winfo_height()
        x = (self.root.winfo_screenwidth() // 2) - (width // 2)
        y = (self.root.winfo_screenheight() // 2) - (height // 2)
        self.root.geometry(f'{width}x{height}+{x}+{y}')
    
    def setup_ui(self):
        """Configure l'interface utilisateur"""
        # Frame principal
        main_frame = tk.Frame(self.root, bg='#ffffff', padx=30, pady=30)
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # Titre
        title_label = tk.Label(
            main_frame,
            text="MyMind Portable",
            font=('Segoe UI', 24, 'bold'),
            bg='#ffffff',
            fg='#667eea'
        )
        title_label.pack(pady=(0, 10))
        
        subtitle_label = tk.Label(
            main_frame,
            text="Installation en cours...",
            font=('Segoe UI', 12),
            bg='#ffffff',
            fg='#64748b'
        )
        subtitle_label.pack(pady=(0, 30))
        
        # Barre de progression
        progress_frame = tk.Frame(main_frame, bg='#ffffff')
        progress_frame.pack(fill=tk.X, pady=(0, 20))
        
        self.progress_bar = ttk.Progressbar(
            progress_frame,
            variable=self.progress_var,
            maximum=100,
            length=440,
            mode='determinate'
        )
        self.progress_bar.pack(fill=tk.X)
        
        # Statut
        status_label = tk.Label(
            main_frame,
            textvariable=self.status_var,
            font=('Segoe UI', 11, 'bold'),
            bg='#ffffff',
            fg='#111827',
            wraplength=440,
            justify=tk.LEFT
        )
        status_label.pack(anchor=tk.W, pady=(0, 10))
        
        # Détails
        detail_label = tk.Label(
            main_frame,
            textvariable=self.detail_var,
            font=('Segoe UI', 9),
            bg='#ffffff',
            fg='#64748b',
            wraplength=440,
            justify=tk.LEFT
        )
        detail_label.pack(anchor=tk.W)
        
        # Zone de texte pour les logs (scrollable)
        log_frame = tk.Frame(main_frame, bg='#f8fafc', relief=tk.SUNKEN, borderwidth=1)
        log_frame.pack(fill=tk.BOTH, expand=True, pady=(20, 0))
        
        scrollbar = tk.Scrollbar(log_frame)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        self.log_text = tk.Text(
            log_frame,
            font=('Consolas', 8),
            bg='#ffffff',
            fg='#374151',
            wrap=tk.WORD,
            yscrollcommand=scrollbar.set,
            state=tk.DISABLED
        )
        self.log_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.config(command=self.log_text.yview)
        
        # Bouton (caché au début, affiché à la fin)
        self.close_btn = tk.Button(
            main_frame,
            text="Fermer",
            command=self.close_window,
            font=('Segoe UI', 10),
            bg='#667eea',
            fg='white',
            activebackground='#764ba2',
            activeforeground='white',
            relief='flat',
            cursor='hand2',
            padx=20,
            pady=8,
            state=tk.DISABLED
        )
        self.close_btn.pack(pady=(10, 0))
    
    def log(self, message):
        """Ajoute un message dans la zone de logs"""
        self.log_text.config(state=tk.NORMAL)
        self.log_text.insert(tk.END, message + "\n")
        self.log_text.see(tk.END)
        self.log_text.config(state=tk.DISABLED)
        self.root.update()
    
    def update_status(self, status, detail="", progress=None):
        """Met à jour le statut et la progression"""
        self.status_var.set(status)
        self.detail_var.set(detail)
        if progress is not None:
            self.progress_var.set(progress)
        self.log(f"[{progress or 0:.0f}%] {status}")
        if detail:
            self.log(f"  → {detail}")
        self.root.update()
    
    def run_installation(self):
        """Lance l'installation dans un thread séparé"""
        threading.Thread(target=self._install_thread, daemon=True).start()
    
    def _install_thread(self):
        """Thread d'installation"""
        try:
            base_dir = Path(__file__).parent
            
            # Étape 0: Préparer les fichiers nécessaires
            self.update_status("Préparation des fichiers...", progress=2)
            
            # Copier requirements.txt si nécessaire
            requirements_file = base_dir / "requirements.txt"
            if not requirements_file.exists():
                parent_requirements = base_dir.parent / "requirements.txt"
                if parent_requirements.exists():
                    import shutil
                    shutil.copy(parent_requirements, requirements_file)
                    self.log("✓ requirements.txt copié")
            
            # Créer le dossier images si nécessaire
            images_dir = base_dir / "images"
            if not images_dir.exists():
                images_dir.mkdir()
                self.log("✓ Dossier images créé")
            
            # Copier les icônes depuis chrome-extension si disponibles
            chrome_ext_dir = base_dir.parent.parent / "chrome-extension"
            if chrome_ext_dir.exists():
                icons = ['icon32.png', 'icon16.png', 'icon48.png', 'icon128.png', 'logo.png']
                for icon in icons:
                    src = chrome_ext_dir / icon
                    dst = images_dir / icon
                    if src.exists() and not dst.exists():
                        import shutil
                        shutil.copy(src, dst)
                self.log("✓ Icônes copiées")
            
            # Créer le dossier app et copier les fichiers si nécessaire
            app_dir = base_dir / "app"
            if not app_dir.exists():
                app_dir.mkdir()
                self.log("✓ Dossier app créé")
                
                # Copier les fichiers depuis le répertoire parent
                parent_dir = base_dir.parent
                files_to_copy = ['main.py', 'config.py', 'api_client.py', 'shortcut_handler.py', 'gui.py']
                for file in files_to_copy:
                    src = parent_dir / file
                    dst = app_dir / file
                    if src.exists() and not dst.exists():
                        import shutil
                        shutil.copy(src, dst)
                        self.log(f"✓ {file} copié")
            
            # Étape 1: Vérifier Python portable
            self.update_status("Vérification de Python portable...", progress=5)
            python_exe = base_dir / "python" / "python.exe"
            if not python_exe.exists():
                self.update_status(
                    "ERREUR: Python portable non trouvé",
                    "Veuillez installer Python portable (voir INSTALL_PYTHON.md)",
                    progress=0
                )
                self.close_btn.config(state=tk.NORMAL)
                return False
            
            # Étape 2: Créer le venv si nécessaire (ou recréer si invalide après déplacement)
            venv_dir = base_dir / "venv"
            venv_python = venv_dir / "Scripts" / "python.exe"
            venv_ok = False
            if venv_python.exists():
                creation_flags = subprocess.CREATE_NO_WINDOW if sys.platform == 'win32' else 0
                test_result = subprocess.run(
                    [str(venv_python), "--version"],
                    cwd=str(base_dir),
                    capture_output=True,
                    text=True,
                    creationflags=creation_flags
                )
                if test_result.returncode == 0:
                    venv_ok = True
            
            if not venv_ok and venv_dir.exists():
                self.update_status("Venv invalide (dossier déplacé?), suppression...", progress=8)
                self.log("Suppression du venv invalide (chemins absolus obsolètes)")
                import shutil
                try:
                    shutil.rmtree(venv_dir)
                    self.log("✓ Venv supprimé")
                except Exception as e:
                    self.log(f"Erreur: {e}")
                    self.update_status("ERREUR: Impossible de supprimer l'ancien venv", str(e), progress=0)
                    self.close_btn.config(state=tk.NORMAL)
                    return False
                venv_python = venv_dir / "Scripts" / "python.exe"
            
            if not venv_python.exists():
                self.update_status("Création de l'environnement virtuel...", progress=10)
                self.log("Exécution: python -m venv venv")
                creation_flags = subprocess.CREATE_NO_WINDOW if sys.platform == 'win32' else 0
                result = subprocess.run(
                    [str(python_exe), "-m", "venv", "venv"],
                    cwd=str(base_dir),
                    capture_output=True,
                    text=True,
                    creationflags=creation_flags
                )
                if result.returncode != 0:
                    self.update_status(
                        "ERREUR: Impossible de créer l'environnement virtuel",
                        result.stderr or result.stdout,
                        progress=0
                    )
                    self.close_btn.config(state=tk.NORMAL)
                    return False
                self.log("✓ Environnement virtuel créé")
            else:
                self.update_status("Environnement virtuel trouvé", progress=15)
                self.log("✓ Environnement virtuel existant")
            
            # Étape 3: Mettre à jour pip
            self.update_status("Mise à jour de pip...", progress=20)
            self.log("Exécution: python -m pip install --upgrade pip")
            creation_flags = subprocess.CREATE_NO_WINDOW if sys.platform == 'win32' else 0
            result = subprocess.run(
                [str(venv_python), "-m", "pip", "install", "--upgrade", "pip"],
                cwd=str(base_dir),
                capture_output=True,
                text=True,
                creationflags=creation_flags
            )
            if result.returncode != 0:
                self.log(f"⚠ Avertissement: {result.stderr}")
            else:
                self.log("✓ pip mis à jour")
            
            # Étape 4: Vérifier requirements.txt (déjà fait en étape 0, mais on vérifie)
            self.update_status("Vérification des dépendances...", progress=30)
            requirements_file = base_dir / "requirements.txt"
            if not requirements_file.exists():
                self.update_status(
                    "ERREUR: requirements.txt introuvable",
                    "Le fichier doit être dans le dossier portable\\",
                    progress=0
                )
                self.close_btn.config(state=tk.NORMAL)
                return False
            
            # Étape 5: Installer les dépendances
            self.update_status("Installation des dépendances...", "Cela peut prendre plusieurs minutes...", progress=40)
            self.log("Exécution: pip install -r requirements.txt")
            
            # Lire le fichier requirements pour afficher la progression
            with open(requirements_file, 'r') as f:
                requirements = [line.strip() for line in f if line.strip() and not line.startswith('#')]
            
            total_packages = len(requirements)
            installed = 0
            
            # Installer les packages
            creation_flags = subprocess.CREATE_NO_WINDOW if sys.platform == 'win32' else 0
            result = subprocess.run(
                [str(venv_python), "-m", "pip", "install", "-r", str(requirements_file)],
                cwd=str(base_dir),
                capture_output=True,
                text=True,
                bufsize=1,
                creationflags=creation_flags
            )
            
            if result.returncode != 0:
                self.update_status(
                    "ERREUR: Échec de l'installation des dépendances",
                    result.stderr or "Vérifiez votre connexion Internet",
                    progress=0
                )
                self.log(f"Erreur: {result.stderr}")
                self.close_btn.config(state=tk.NORMAL)
                return False
            
            self.log("✓ Dépendances installées")
            
            # Étape 6: Vérifier les packages essentiels
            self.update_status("Vérification de l'installation...", progress=80)
            essential_packages = ['requests', 'keyboard', 'pyperclip', 'pystray', 'Pillow']
            creation_flags = subprocess.CREATE_NO_WINDOW if sys.platform == 'win32' else 0
            for package in essential_packages:
                result = subprocess.run(
                    [str(venv_python), "-c", f"import {package.split('.')[0]}"],
                    capture_output=True,
                    text=True,
                    creationflags=creation_flags
                )
                if result.returncode == 0:
                    self.log(f"✓ {package} installé")
                else:
                    self.log(f"⚠ {package} non trouvé")
            
            # Étape 7: Vérifier les fichiers de l'application
            self.update_status("Vérification des fichiers de l'application...", progress=90)
            app_dir = base_dir / "app"
            required_files = ['main.py', 'config.py', 'api_client.py', 'gui.py', 'shortcut_handler.py']
            all_present = True
            for file in required_files:
                if (app_dir / file).exists():
                    self.log(f"✓ {file} trouvé")
                else:
                    self.log(f"✗ {file} manquant")
                    all_present = False
            
            if not all_present:
                self.update_status(
                    "ERREUR: Fichiers de l'application manquants",
                    "Veuillez copier les fichiers dans le dossier app\\",
                    progress=0
                )
                self.close_btn.config(state=tk.NORMAL)
                return False
            
            # Installation terminée
            self.update_status("Installation terminée avec succès !", "L'application va démarrer...", progress=100)
            self.log("✓ Installation complète")
            self.install_success = True
            
            # Attendre un peu puis fermer et lancer l'application
            self.root.after(2000, self.launch_application)
            
        except Exception as e:
            self.update_status(
                "ERREUR: Exception lors de l'installation",
                str(e),
                progress=0
            )
            self.log(f"Erreur: {e}")
            import traceback
            self.log(traceback.format_exc())
            self.close_btn.config(state=tk.NORMAL)
            return False
    
    def launch_application(self):
        """Lance l'application principale"""
        base_dir = Path(__file__).parent
        venv_python = base_dir / "venv" / "Scripts" / "pythonw.exe"
        
        # Essayer pythonw.exe, sinon python.exe
        if not venv_python.exists():
            venv_python = base_dir / "venv" / "Scripts" / "python.exe"
        
        app_main = base_dir / "app" / "main.py"
        
        try:
            # Lancer l'application en arrière-plan (sans console)
            creation_flags = subprocess.CREATE_NO_WINDOW if sys.platform == 'win32' else 0
            subprocess.Popen(
                [str(venv_python), str(app_main)],
                cwd=str(base_dir),
                creationflags=creation_flags
            )
            # Fermer la fenêtre d'installation
            self.root.after(500, self.close_window)
        except Exception as e:
            self.update_status(
                "ERREUR: Impossible de lancer l'application",
                str(e),
                progress=0
            )
            self.close_btn.config(state=tk.NORMAL)
    
    def close_window(self):
        """Ferme la fenêtre"""
        self.root.quit()
        self.root.destroy()
    
    def run(self):
        """Lance l'interface"""
        self.run_installation()
        self.root.mainloop()
        return self.install_success

if __name__ == "__main__":
    app = InstallUI()
    app.run()

