import os
import shutil
from typing import List, Dict, Any
from fastapi import UploadFile
from .base_storage import StorageInterface

class LocalStorage(StorageInterface):
    def __init__(self, base_path: str = None):
        if base_path is None:
            # Usar la misma ruta que el código existente
            self.base_path = os.getenv('ftp_path_files', '/var/www/dev.api.imparables.cic-ware.com/crm/files')
        else:
            self.base_path = base_path
    
    async def save_files(self, folder_path: str, files: List[UploadFile]) -> Dict[str, Any]:
        full_path = os.path.join(self.base_path, folder_path)
        uploaded_files = []
        
        try:
            # Crear carpeta si no existe
            if not os.path.exists(full_path):
                os.makedirs(full_path)
            
            # Obtener archivos existentes para el límite de 5 archivos
            existing_files = []
            if os.path.exists(full_path):
                existing_files = [
                    (file, os.path.getmtime(os.path.join(full_path, file)))
                    for file in os.listdir(full_path)
                    if os.path.isfile(os.path.join(full_path, file))
                ]
            
            # Calcular cuántos archivos eliminar si exceden el límite
            num_archivos_existentes = len(existing_files)
            num_archivos_nuevos = len(files)
            total_despues = num_archivos_existentes + num_archivos_nuevos
            excedente = max(total_despues - 5, 0)
            
            # Eliminar los archivos más antiguos si exceden el límite
            if excedente > 0 and existing_files:
                existing_files.sort(key=lambda x: x[1])  # ordenar por fecha de modificación
                files_to_remove = existing_files[:excedente]
                
                for file, _ in files_to_remove:
                    file_path = os.path.join(full_path, file)
                    os.remove(file_path)
            
            # Guardar nuevos archivos
            for file in files:
                local_filename = file.filename
                local_file_path = os.path.join(full_path, local_filename)
                
                # Leer contenido del archivo
                content = await file.read()
                
                with open(local_file_path, 'wb') as destination_file:
                    destination_file.write(content)
                
                # Generar URL local (para compatibilidad)
                file_url = f"file://{local_file_path}"
                uploaded_files.append({
                    'filename': file.filename,
                    'local_path': local_file_path,
                    'url': file_url,
                    'size': len(content)
                })
            
            return {
                "success": True,
                "message": "Archivos guardados exitosamente",
                "files": uploaded_files
            }
            
        except Exception as e:
            return {
                "success": False,
                "message": f"Error al guardar los archivos: {str(e)}"
            }
    
    async def get_file_url(self, file_path: str) -> str:
        full_path = os.path.join(self.base_path, file_path)
        return f"file://{full_path}"
    
    async def delete_file(self, file_path: str) -> bool:
        try:
            full_path = os.path.join(self.base_path, file_path)
            if os.path.exists(full_path):
                os.remove(full_path)
                return True
            return False
        except Exception:
            return False
    
    async def list_files(self, folder_path: str) -> List[str]:
        try:
            full_path = os.path.join(self.base_path, folder_path)
            if os.path.exists(full_path):
                return [f for f in os.listdir(full_path) if os.path.isfile(os.path.join(full_path, f))]
            return []
        except Exception:
            return []
    
    async def list_files_with_metadata(self, folder_path: str, max_files: int = 5) -> Dict[str, Any]:
        """
        Lista archivos locales con metadatos (sin generar URLs).
        """
        try:
            full_path = os.path.join(self.base_path, folder_path)
            
            if not os.path.exists(full_path):
                return {
                    "success": True,
                    "message": "No se encontraron archivos en la carpeta",
                    "files": []
                }
            
            files_info = []
            for filename in os.listdir(full_path):
                file_path = os.path.join(full_path, filename)
                if os.path.isfile(file_path):
                    stat = os.stat(file_path)
                    files_info.append({
                        'key': os.path.join(folder_path, filename),
                        'filename': filename,
                        'size': stat.st_size,
                        'last_modified': stat.st_mtime,
                        'file_path': file_path
                    })
            
            files_info.sort(key=lambda x: x['last_modified'], reverse=True)
            latest_files = files_info[:max_files]
            
            files_with_metadata = []
            for file_info in latest_files:
                from datetime import datetime
                files_with_metadata.append({
                    'filename': file_info['filename'],
                    's3_key': file_info['key'],
                    'size': file_info['size'],
                    'last_modified': datetime.fromtimestamp(file_info['last_modified']).isoformat()
                })
            
            return {
                "success": True,
                "message": f"Archivos locales listados: {len(files_with_metadata)} archivos",
                "folder_path": folder_path,
                "files": files_with_metadata,
                "total_files_in_folder": len(files_info),
                "files_returned": len(files_with_metadata)
            }
            
        except Exception as e:
            return {
                "success": False,
                "message": f"Error al listar archivos locales: {str(e)}",
                "files": []
            }
    
    async def get_signed_url(self, s3_key: str, expiration: int = 3600) -> Dict[str, Any]:
        """
        Para storage local, simula una URL firmada retornando la ruta local.
        """
        try:
            full_path = os.path.join(self.base_path, s3_key)
            
            if not os.path.exists(full_path):
                return {
                    "success": False,
                    "message": "Archivo no encontrado",
                    "data": {}
                }
            
            # Para storage local, retornar ruta local como "URL firmada"
            local_url = f"file://{full_path}"
            
            # Calcular tiempo de expiración simulado
            from datetime import datetime, timedelta
            expires_at = datetime.now() + timedelta(seconds=expiration)
            
            return {
                "success": True,
                "message": "URL local generada exitosamente",
                "signed_url": local_url,
                "expires_at": expires_at.isoformat(),
                "expires_in": expiration
            }
            
        except Exception as e:
            return {
                "success": False,
                "message": f"Error al generar URL local: {str(e)}",
                "data": {}
            }
