"""
Cliente para POS MIG - Consumir archivos desde UpdaterMIG
Este archivo debe estar en el proyecto POS MIG
"""

import requests
import os
from datetime import datetime

class UpdaterMIGClient:
    def __init__(self, server_url="http://localhost:5000"):
        """
        Inicializar cliente de UpdaterMIG
        
        Args:
            server_url: URL del servidor UpdaterMIG (ej: http://192.168.1.100:5000)
        """
        self.server_url = server_url.rstrip('/')
        self.download_path = "downloads"  # Carpeta donde se guardarán los archivos
        
        # Crear carpeta de descargas si no existe
        if not os.path.exists(self.download_path):
            os.makedirs(self.download_path)
    
    def check_server(self):
        """Verificar si el servidor está disponible"""
        try:
            response = requests.get(f"{self.server_url}/api/info", timeout=5)
            if response.status_code == 200:
                data = response.json()
                print(f"✅ Servidor conectado: {data['server']} v{data['version']}")
                print(f"   Estado: {data['status']}")
                print(f"   Timestamp: {data['timestamp']}")
                return True
            else:
                print("❌ Servidor no disponible")
                return False
        except requests.exceptions.RequestException as e:
            print(f"❌ Error de conexión: {e}")
            return False
    
    def get_available_files(self):
        """Obtener lista de todos los archivos disponibles para descargar"""
        try:
            response = requests.get(f"{self.server_url}/api/available-files")
            if response.status_code == 200:
                data = response.json()
                print(f"\n📦 Archivos disponibles: {data['total']}")
                return data['files']
            else:
                print("❌ Error al obtener lista de archivos")
                return []
        except requests.exceptions.RequestException as e:
            print(f"❌ Error: {e}")
            return []
    
    def download_file(self, file_path, save_path=None):
        """
        Descargar un archivo específico
        
        Args:
            file_path: Ruta del archivo en el servidor (ej: "updates/app.exe")
            save_path: Ruta donde guardar el archivo (opcional)
        """
        try:
            url = f"{self.server_url}/api/download/{file_path}"
            response = requests.get(url, stream=True)
            
            if response.status_code == 200:
                # Determinar donde guardar el archivo
                if save_path is None:
                    filename = os.path.basename(file_path)
                    save_path = os.path.join(self.download_path, filename)
                
                # Crear directorios si no existen
                os.makedirs(os.path.dirname(save_path), exist_ok=True)
                
                # Descargar archivo
                total_size = int(response.headers.get('content-length', 0))
                downloaded = 0
                
                with open(save_path, 'wb') as f:
                    for chunk in response.iter_content(chunk_size=8192):
                        if chunk:
                            f.write(chunk)
                            downloaded += len(chunk)
                            if total_size > 0:
                                progress = (downloaded / total_size) * 100
                                print(f"\r⬇️ Descargando: {progress:.1f}%", end='')
                
                print(f"\n✅ Archivo descargado: {save_path}")
                return save_path
            else:
                print(f"❌ Error al descargar: {response.status_code}")
                return None
        except Exception as e:
            print(f"❌ Error: {e}")
            return None
    
    def download_all_files(self, filter_extension=None):
        """
        Descargar todos los archivos disponibles
        
        Args:
            filter_extension: Filtrar solo archivos con esta extensión (ej: ".exe", ".apk")
        """
        files = self.get_available_files()
        
        if not files:
            print("No hay archivos disponibles")
            return
        
        downloaded_count = 0
        
        for file_info in files:
            file_path = file_info['path']
            file_name = file_info['name']
            
            # Filtrar por extensión si se especifica
            if filter_extension and not file_name.endswith(filter_extension):
                continue
            
            print(f"\n📥 Descargando: {file_name}")
            print(f"   Tamaño: {self._format_size(file_info['size'])}")
            print(f"   Modificado: {file_info['modified']}")
            
            save_path = os.path.join(self.download_path, file_path.replace('/', os.sep))
            
            if self.download_file(file_path, save_path):
                downloaded_count += 1
        
        print(f"\n✅ {downloaded_count} archivo(s) descargado(s)")
    
    def download_folder(self, folder_name):
        """
        Descargar todos los archivos de una carpeta específica
        
        Args:
            folder_name: Nombre de la carpeta (ej: "updates", "configs")
        """
        files = self.get_available_files()
        folder_files = [f for f in files if f['path'].startswith(folder_name)]
        
        print(f"\n📁 Descargando carpeta: {folder_name}")
        print(f"   Archivos encontrados: {len(folder_files)}")
        
        for file_info in folder_files:
            file_path = file_info['path']
            save_path = os.path.join(self.download_path, file_path.replace('/', os.sep))
            self.download_file(file_path, save_path)
    
    def _format_size(self, bytes):
        """Formatear tamaño de archivo"""
        for unit in ['B', 'KB', 'MB', 'GB']:
            if bytes < 1024.0:
                return f"{bytes:.2f} {unit}"
            bytes /= 1024.0
        return f"{bytes:.2f} TB"


# Ejemplo de uso
if __name__ == "__main__":
    print("=" * 50)
    print("  UpdaterMIG Client - POS MIG")
    print("=" * 50)
    
    # Crear cliente (cambiar la URL según tu servidor)
    client = UpdaterMIGClient(server_url="http://localhost:5000")
    
    # Verificar conexión
    if not client.check_server():
        print("\n⚠️ No se pudo conectar al servidor UpdaterMIG")
        exit(1)
    
    # Menú de opciones
    while True:
        print("\n" + "=" * 50)
        print("Opciones:")
        print("1. Ver archivos disponibles")
        print("2. Descargar todos los archivos")
        print("3. Descargar archivos .exe solamente")
        print("4. Descargar carpeta específica")
        print("5. Descargar archivo específico")
        print("0. Salir")
        print("=" * 50)
        
        opcion = input("\nSelecciona una opción: ").strip()
        
        if opcion == "1":
            files = client.get_available_files()
            if files:
                print("\n📋 Lista de archivos:")
                for i, file_info in enumerate(files, 1):
                    print(f"{i}. {file_info['name']}")
                    print(f"   Ruta: {file_info['path']}")
                    print(f"   Tamaño: {client._format_size(file_info['size'])}")
                    print(f"   Modificado: {file_info['modified']}")
                    print()
        
        elif opcion == "2":
            client.download_all_files()
        
        elif opcion == "3":
            client.download_all_files(filter_extension=".exe")
        
        elif opcion == "4":
            folder = input("Nombre de la carpeta: ").strip()
            client.download_folder(folder)
        
        elif opcion == "5":
            file_path = input("Ruta del archivo (ej: updates/app.exe): ").strip()
            client.download_file(file_path)
        
        elif opcion == "0":
            print("\n👋 ¡Hasta luego!")
            break
        
        else:
            print("❌ Opción inválida")