"""
Système de logging pour Lescopr SDK
"""

import os
import sys
import logging
import threading
from datetime import datetime
from pathlib import Path
from typing import Optional, Union

# Configuration par défaut
DEFAULT_LOG_LEVEL = 'INFO'
DEFAULT_LOG_FORMAT = '[%(asctime)s] %(levelname)s [%(name)s] %(message)s'
DEFAULT_DATE_FORMAT = '%Y-%m-%d %H:%M:%S'

# Lock pour thread-safety
_logger_lock = threading.RLock()
_loggers = {}

class LescoprFormatter(logging.Formatter):
    """Formatter personnalisé pour Lescopr avec couleurs"""
    
    # Codes couleurs ANSI
    COLORS = {
        'DEBUG': '\033[36m',    # Cyan
        'INFO': '\033[32m',     # Vert
        'WARNING': '\033[33m',  # Jaune
        'ERROR': '\033[31m',    # Rouge
        'CRITICAL': '\033[35m', # Magenta
        'RESET': '\033[0m'      # Reset
    }
    
    def __init__(self, fmt=None, datefmt=None, use_colors: bool = True):
        # ✅ CORRECTION : Utiliser les paramètres corrects pour logging.Formatter
        super().__init__(fmt or DEFAULT_LOG_FORMAT, datefmt or DEFAULT_DATE_FORMAT)
        self.use_colors = use_colors and hasattr(sys.stderr, 'isatty') and sys.stderr.isatty()
    
    def format(self, record):
        """Formate le message avec couleurs si activées"""
        if self.use_colors:
            level_color = self.COLORS.get(record.levelname, self.COLORS['RESET'])
            record.levelname = f"{level_color}{record.levelname}{self.COLORS['RESET']}"
        
        return super().format(record)

def get_log_directory() -> Path:
    """Retourne le répertoire racine du projet (où créer .lescopr.log)"""
    
    current_dir = Path.cwd()
    lescopr_config = current_dir / '.lescopr.json'
    
    if lescopr_config.exists():
        try:
            if os.access(current_dir, os.W_OK):
                return current_dir
        except (OSError, PermissionError):
            pass
    
    search_dir = current_dir
    for _ in range(5):
        lescopr_config = search_dir / '.lescopr.json'
        if lescopr_config.exists():
            try:
                if os.access(search_dir, os.W_OK):
                    return search_dir
            except (OSError, PermissionError):
                pass
        
        parent = search_dir.parent
        if parent == search_dir:
            break
        search_dir = parent
    
    candidates = [
        os.environ.get('LESCOPR_LOG_DIR'),
        os.path.expanduser('~/.lescopr'),
        '/tmp/lescopr',
        '.'
    ]
    
    for log_dir in candidates:
        if log_dir:
            log_path = Path(log_dir)
            try:
                log_path.mkdir(parents=True, exist_ok=True)
                if os.access(log_path, os.W_OK):
                    return log_path
            except (OSError, PermissionError):
                continue    
    return Path('')

def create_logger(name: str, level: str = None, log_to_file: bool = True, console_output: bool = False) -> logging.Logger:
    """
    Crée un logger configuré pour Lescopr
    
    Args:
        name: Nom du logger
        level: Niveau de log
        log_to_file: Si True, log dans un fichier
        console_output: Si True, log aussi dans la console (pour debug seulement)
    """
    with _logger_lock:
        if name in _loggers:
            return _loggers[name]
        
        logger_instance = logging.getLogger(f"lescopr.{name}")
        logger_instance.setLevel(getattr(logging, (level or DEFAULT_LOG_LEVEL).upper()))
        
        if logger_instance.handlers:
            logger_instance.handlers.clear()
        
        # ✅ Handler console SEULEMENT si explicitement demandé
        if console_output:
            console_handler = logging.StreamHandler(sys.stdout)
            console_handler.setFormatter(LescoprFormatter(use_colors=True))
            logger_instance.addHandler(console_handler)
        
        # ✅ Handler fichier (par défaut)
        if log_to_file:
            try:
                log_dir = get_log_directory()
                log_file = log_dir / f"lescopr_{name}.log"
                
                file_handler = logging.FileHandler(log_file, encoding='utf-8')
                file_handler.setFormatter(LescoprFormatter(use_colors=False))
                logger_instance.addHandler(file_handler)
                
            except Exception:
                pass
        
        logger_instance.propagate = False
        _loggers[name] = logger_instance
        return logger_instance

def logger(level: str, message: str, logger_name: str = "main") -> None:
    """Fonction de logging principale SANS doublon"""
    global _loggers
    
    daemon_mode = os.environ.get('LESCOPR_DAEMON_MODE') == 'true'
    
    if daemon_mode and logger_name == "main":
        logger_name = "lescopr_daemon"
    
    try:
        if logger_name in _loggers:
            target_logger = _loggers[logger_name]
        else:
            if daemon_mode and logger_name == "lescopr_daemon":
                target_logger = setup_daemon_logging()
            else:
                target_logger = create_logger(logger_name)
        
        level_method = getattr(target_logger, level.lower(), target_logger.info)
        level_method(message)
        
        for handler in target_logger.handlers:
            try:
                handler.flush()
            except:
                pass
                
    except Exception as e:
        print(f"[LOGGER-ERROR] {level.upper()} - {message} (Erreur: {e})")


def setup_daemon_logging(log_level: str = 'INFO') -> logging.Logger:
    """Configure le logging pour le daemon dans lescopr.log"""
    global _logger_lock, _loggers
    
    with _logger_lock:
        try:
            daemon_logger_name = 'lescopr_daemon'
            
            if daemon_logger_name in _loggers:
                return _loggers[daemon_logger_name]
            
            daemon_logger = logging.getLogger(daemon_logger_name)
            daemon_logger.handlers.clear()
            
            level = getattr(logging, log_level.upper(), logging.INFO)
            daemon_logger.setLevel(level)
            
            try:
                log_dir = get_log_directory()
                log_file = log_dir / '.lescopr.log'
                
                file_handler = logging.FileHandler(log_file, mode='a', encoding='utf-8')
                file_formatter = LescoprFormatter(
                    fmt='[%(asctime)s] %(levelname)s - %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S',
                    use_colors=False
                )
                file_handler.setFormatter(file_formatter)
                daemon_logger.addHandler(file_handler)
                
                print(f"[LOGGER] Daemon logger: fichier {log_file}")
                
            except Exception as e:
                print(f"[LOGGER] Erreur fichier log: {e}, utilisation console")
                
                console_handler = logging.StreamHandler(sys.stdout)
                console_formatter = LescoprFormatter(
                    fmt='%(levelname)s - %(message)s',
                    use_colors=True
                )
                console_handler.setFormatter(console_formatter)
                daemon_logger.addHandler(console_handler)
            
            daemon_logger.propagate = False
            _loggers[daemon_logger_name] = daemon_logger
            
            print(f"[LOGGER] Daemon logger créé avec {len(daemon_logger.handlers)} handler(s)")
            return daemon_logger
            
        except Exception as e:
            print(f"[LOGGER] ERREUR setup_daemon_logging: {e}")
            return logging.getLogger('lescopr_daemon_fallback')

def setup_custom_logging(
    name: str,
    level: str = 'INFO',
    log_file: Optional[str] = None,
    format_string: Optional[str] = None
) -> logging.Logger:
    """
    Configuration de logging personnalisée
    
    Args:
        name: Nom du logger
        level: Niveau de log
        log_file: Fichier de log spécifique (optionnel)
        format_string: Format personnalisé (optionnel)
        
    Returns:
        logging.Logger: Logger personnalisé
    """
    logger_instance = logging.getLogger(f"lescopr.{name}")
    logger_instance.setLevel(getattr(logging, level.upper()))
    
    # Nettoyer les handlers existants
    if logger_instance.handlers:
        logger_instance.handlers.clear()
    
    # Formatter personnalisé
    formatter = logging.Formatter(
        format_string or DEFAULT_LOG_FORMAT,
        DEFAULT_DATE_FORMAT
    )
    
    # Handler console
    console_handler = logging.StreamHandler()
    console_handler.setFormatter(formatter)
    logger_instance.addHandler(console_handler)
    
    # Handler fichier personnalisé
    if log_file:
        try:
            file_handler = logging.FileHandler(log_file, encoding='utf-8')
            file_handler.setFormatter(formatter)
            logger_instance.addHandler(file_handler)
        except Exception as e:
            logger_instance.warning(f"Impossible de créer le fichier {log_file}: {e}")
    
    logger_instance.propagate = False
    return logger_instance

def get_logger_stats() -> dict:
    """
    Retourne les statistiques des loggers actifs
    
    Returns:
        dict: Statistiques des loggers
    """
    with _logger_lock:
        return {
            'active_loggers': len(_loggers),
            'logger_names': list(_loggers.keys()),
            'log_directory': str(get_log_directory())
        }

def cleanup_loggers():
    """Nettoie tous les loggers actifs"""
    with _logger_lock:
        for logger_name, logger_instance in _loggers.items():
            for handler in logger_instance.handlers[:]:
                handler.close()
                logger_instance.removeHandler(handler)
        _loggers.clear()

# Créer le logger principal par défaut
main_logger = create_logger('main')

# Fonction pratique pour compatibilité
def log(level: str, message: str):
    """Alias pour la fonction logger principale"""
    logger(level, message)

if __name__ == "__main__":
    # Tests du système de logging
    print("=== Test du système de logging Lescopr ===")
    
    # Test de la fonction logger simple
    logger('debug', 'Message de debug')
    logger('info', 'Message d\'information')
    logger('warning', 'Message d\'avertissement')
    logger('error', 'Message d\'erreur')
    logger('critical', 'Message critique')
    
    # Test avec différents loggers
    logger('info', 'Message réseau', 'network')
    logger('error', 'Erreur base de données', 'database')
    
    # Test du daemon logger
    daemon_logger = setup_daemon_logging('DEBUG')
    daemon_logger.info('Test du daemon logger')
    
    # Afficher les stats
    stats = get_logger_stats()
    print(f"\nStatistiques: {stats}")