"""
Gallery logging wrapper using Python's built-in logging module with tree-like output.
"""

import logging
import sys


class Colors:
    """ANSI color codes for terminal output"""
    RESET = '\033[0m'
    BOLD = '\033[1m'

    # Standard colors
    RED = '\033[31m'
    GREEN = '\033[32m'
    YELLOW = '\033[33m'
    BLUE = '\033[34m'
    MAGENTA = '\033[35m'
    CYAN = '\033[36m'
    WHITE = '\033[37m'

    # Bright colors
    BRIGHT_GREEN = '\033[92m'
    BRIGHT_YELLOW = '\033[93m'
    BRIGHT_BLUE = '\033[94m'
    BRIGHT_CYAN = '\033[96m'


class TreeFormatter(logging.Formatter):
    """Custom formatter that creates clean output with colors"""
    
    def __init__(self, use_colors: bool = True):
        super().__init__()
        self.use_colors = use_colors and sys.stdout.isatty()
        
    def _colorize(self, text: str, color: str) -> str:
        """Apply color to text if colors are enabled"""
        if not self.use_colors:
            return text
        return f"{color}{text}{Colors.RESET}"
    
    def format(self, record):
        # Extract custom attributes from the record
        indent = getattr(record, 'indent', 0)
        
        # Create simple indentation
        prefix = "  " * indent
        
        # Apply colors based on level and content
        message = record.getMessage()
        
        if record.levelname == 'INFO':
            if 'Processing:' in message:
                # Main source headers
                message = self._colorize(message, Colors.BOLD + Colors.MAGENTA)
            elif 'Generated' in message:
                message = self._colorize(message, Colors.GREEN)
            elif 'PDF files' in message:
                message = self._colorize(message, Colors.BLUE)
            elif 'Converting' in message:
                message = self._colorize(message, Colors.CYAN)
            elif 'Completed' in message and 'sources' in message:
                message = self._colorize(message, Colors.BOLD + Colors.GREEN)
            else:
                message = self._colorize(message, Colors.WHITE)
        elif record.levelname == 'WARNING':
            message = self._colorize(f"WARNING: {message}", Colors.YELLOW)
        elif record.levelname == 'ERROR':
            message = self._colorize(f"ERROR: {message}", Colors.RED)
        elif record.levelname == 'DEBUG':
            message = self._colorize(message, Colors.CYAN)
        else:
            message = message
        
        return f"{prefix}{message}"


class GalleryLogger:
    """
    Simple logger for gallery generation using Python's logging module.
    Provides convenient methods for common logging patterns with clean output.
    """

    def __init__(self, name: str = "gallery", level: int = logging.INFO,
                 verbose: bool = False, use_colors: bool = True):
        """
        Initialize the gallery logger.

        Args:
            name: Logger name
            level: Logging level (default: INFO)
            verbose: If True, enables DEBUG level logging
            use_colors: If True, enables colored output
        """
        self.logger = logging.getLogger(name)
        self.use_colors = use_colors
        self.current_source = None
        self.current_depth = 0

        # Set level based on verbose flag
        if verbose:
            self.logger.setLevel(logging.DEBUG)
        else:
            self.logger.setLevel(level)

        # Only add handler if logger doesn't have one already
        if not self.logger.handlers:
            handler = logging.StreamHandler(sys.stdout)
            formatter = TreeFormatter(use_colors=use_colors)
            handler.setFormatter(formatter)
            self.logger.addHandler(handler)
            
        # Prevent propagation to avoid duplicate messages
        self.logger.propagate = False

    def _log_with_tree(self, level: int, message: str, indent: int = 0):
        """Log a message with simple indentation"""
        # Store indentation info in a way the formatter can access
        original_makeRecord = self.logger.makeRecord
        
        def makeRecord_with_indent(*args, **kwargs):
            record = original_makeRecord(*args, **kwargs)
            record.indent = indent
            return record
        
        # Temporarily replace makeRecord to add our custom attributes
        self.logger.makeRecord = makeRecord_with_indent
        try:
            self.logger.log(level, message)
        finally:
            # Restore original makeRecord
            self.logger.makeRecord = original_makeRecord

    def start_source(self, source_name: str):
        """Begin processing a new source"""
        self.current_source = source_name
        self.current_depth = 0
        if self.use_colors:
            colored_name = f"{Colors.BOLD}{Colors.MAGENTA}{source_name}{Colors.RESET}"
            self.logger.info(f"\nProcessing: {colored_name}")
        else:
            self.logger.info(f"\nProcessing: {source_name}")

    def info(self, message: str, indent: int = 0):
        """Log an info message"""
        self._log_with_tree(logging.INFO, message, indent)

    def debug(self, message: str, indent: int = 0):
        """Log a debug message"""
        self._log_with_tree(logging.DEBUG, message, indent)

    def warning(self, message: str, indent: int = 0):
        """Log a warning message"""
        self._log_with_tree(logging.WARNING, message, indent)

    def error(self, message: str, indent: int = 0):
        """Log an error message"""
        self._log_with_tree(logging.ERROR, message, indent)

    def found_directory(self, dir_name: str, pdf_count: int, indent: int = 1):
        """Log discovery of a directory with PDFs"""
        if pdf_count > 0:
            self._log_with_tree(
                logging.INFO,
                f"Found {dir_name}/ ({pdf_count} PDFs)",
                indent
            )

    def found_pdf(self, pdf_name: str, indent: int = 2):
        """Log discovery of a PDF file (debug only)"""
        self._log_with_tree(logging.DEBUG, f"Found PDF: {pdf_name}", indent)

    def found_metadata(self, metadata_file: str, field_count: int, indent: int = 1):
        """Log discovery of a metadata file"""
        self._log_with_tree(
            logging.INFO,
            f"Found metadata: {metadata_file} ({field_count} fields)",
            indent
        )

    def converted_pdf(self, pdf_name: str, duration: float = None, indent: int = 2):
        """Log successful PDF conversion"""
        if duration is not None:
            self._log_with_tree(
                logging.INFO,
                f"Converting {pdf_name} ({duration:.2f}s)",
                indent
            )
        else:
            self._log_with_tree(logging.INFO, f"Converting {pdf_name}", indent)

    def skipped_pdf(self, pdf_name: str, reason: str = "up-to-date", indent: int = 2):
        """Log skipped PDF conversion"""
        self._log_with_tree(logging.DEBUG, f"Skipping {pdf_name} ({reason})", indent)

    def generated_html(self, html_path: str, plot_count: int, indent: int = 1):
        """Log HTML page generation"""
        # Extract just the meaningful part of the path
        if '/gallery/' in html_path:
            short_path = html_path.split('/gallery/')[-1]
        else:
            short_path = html_path

        if plot_count > 0:
            self._log_with_tree(
                logging.INFO,
                f"Generated {short_path} ({plot_count} plots)",
                indent
            )
        else:
            self._log_with_tree(
                logging.DEBUG,
                f"Generated {short_path} (index only)",
                indent
            )

    def assets_updated(self):
        """Log assets update"""
        self.logger.info("Assets updated")

    def summary(self, source_count: int):
        """Print a summary"""
        if self.use_colors:
            message = f"{Colors.BOLD}{Colors.GREEN}Completed processing {source_count} sources{Colors.RESET}"
        else:
            message = f"Completed processing {source_count} sources"
        self.logger.info(f"\n{message}")


def create_logger(verbose: bool = False, quiet: bool = False, use_colors: bool = True) -> GalleryLogger:
    """
    Create a configured logger for the gallery application.

    Args:
        verbose: Enable debug-level logging
        quiet: Suppress most output (only errors and warnings)
        use_colors: Enable colored output

    Returns:
        Configured GalleryLogger instance
    """
    if quiet:
        level = logging.WARNING
    elif verbose:
        level = logging.DEBUG
    else:
        level = logging.INFO

    return GalleryLogger(level=level, verbose=verbose, use_colors=use_colors)
