import logging
import logging.handlers
import traceback
import os
import inspect
from pathlib import Path
from datetime import datetime
from typing import Optional, Any
from analogai.foundation.common.logging.ignored_modules import IGNORED_MODULES
from analogai.foundation.settings import config

def _get_module_name_from_path(pathname: str) -> str:
    if not pathname:
        return 'unknown'
    try:
        path_parts = Path(pathname).parts
        if 'src' in path_parts:
            src_index = path_parts.index('src')
            module_parts = list(path_parts[src_index + 1:])
            if module_parts:
                module_parts[-1] = module_parts[-1].replace('.py', '')
                return '.'.join(module_parts)
        else:
            return Path(pathname).stem
    except Exception:
        pass
    return Path(pathname).stem if pathname else 'unknown'

class ColorFormatter(logging.Formatter):
    COLORS = {
        'green': '\033[92m',
        'red': '\033[91m',
        'blue': '\033[94m',
        'yellow': '\033[93m',
        'reset': '\033[0m'
    }
    
    def __init__(self, datefmt: str = '%Y-%m-%d %H:%M:%S'):
        super().__init__(fmt='%(message)s', datefmt=datefmt)
    
    def format(self, record: logging.LogRecord) -> str:
        timestamp = self.formatTime(record, self.datefmt)
        message = str(record.getMessage())
        module_name = _get_module_name_from_path(record.pathname)
        level_prefix = f"[{record.levelname}] " if record.levelno == logging.DEBUG else ""
        color = getattr(record, 'color', None)
        if color in self.COLORS:
            if ':' in message:
                parts = message.split(':', 1)
                return f"{timestamp} | {level_prefix}[{module_name}] {self.COLORS[color]}{parts[0]}{self.COLORS['reset']}:{parts[1]}"
            return f"{timestamp} | {level_prefix}[{module_name}] {self.COLORS[color]}{message}{self.COLORS['reset']}"
        return f"{timestamp} | {level_prefix}[{module_name}] {message}"

class FileFormatter(logging.Formatter):
    def __init__(self, datefmt: str = '%Y-%m-%d %H:%M:%S'):
        super().__init__(fmt='%(message)s', datefmt=datefmt)
    
    def format(self, record: logging.LogRecord) -> str:
        timestamp = self.formatTime(record, self.datefmt)
        message = record.getMessage()
        module_name = _get_module_name_from_path(record.pathname)
        level_prefix = f"[{record.levelname}] " if record.levelno == logging.DEBUG else ""
        return f"{timestamp} | {level_prefix}[{module_name}] {message}"

class FlexibleColorLogger(logging.Logger):
    def __init__(self, name: str, level: int = logging.NOTSET):
        super().__init__(name, level)
        stream_handler = logging.StreamHandler()
        stream_handler.setFormatter(ColorFormatter())
        self.handlers = [stream_handler]
        self.propagate = False

    def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False, stacklevel=1, **kwargs):
        if extra is None:
            extra = {}
        super()._log(level, msg, args, exc_info=exc_info, extra=extra, stack_info=stack_info, stacklevel=stacklevel + 2, **kwargs)

    def info(self, msg: Any, *args, **kwargs) -> None:
        if self.isEnabledFor(logging.INFO):
            self._log(logging.INFO, msg, args, **kwargs)

    def colored_info(self, msg: Any, color: Optional[str] = None) -> None:
        if self.isEnabledFor(logging.INFO):
            if isinstance(msg, (list, tuple, dict)):
                msg = str(msg)
            self._log(logging.INFO, msg, (), extra={'color': color})

    def success(self, msg: Any) -> None:
        if self.isEnabledFor(logging.INFO):
            if isinstance(msg, (list, tuple, dict)):
                msg = str(msg)
            self._log(logging.INFO, msg, (), extra={'color': 'green'})

    def important(self, msg: Any) -> None:
        if self.isEnabledFor(logging.INFO):
            if isinstance(msg, (list, tuple, dict)):
                msg = str(msg)
            self._log(logging.INFO, msg, (), extra={'color': 'blue'})

    def error(self, msg: Any, exc: Optional[Exception] = None, *args, **kwargs) -> None:
        if self.isEnabledFor(logging.ERROR):
            effective_exc = exc if exc is not None else (args[0] if args and isinstance(args[0], Exception) else None)
            if effective_exc:
                tb_str = traceback.format_exc() if traceback.extract_stack() else "No traceback available"
                msg = f"{msg}: {str(effective_exc)}\n{tb_str}"
            elif args:
                msg = msg % args if '%s' in msg else f"{msg} (args: {args})"
            self._log(logging.ERROR, msg, (), extra={'color': 'red'}, **kwargs)

    def warning(self, msg: Any, *args, **kwargs) -> None:
        if self.isEnabledFor(logging.WARNING):
            self._log(logging.WARNING, msg, args, extra={'color': 'yellow'}, **kwargs)

    def debug(self, msg: Any, *args, **kwargs) -> None:
        if self.isEnabledFor(logging.DEBUG):
            self._log(logging.DEBUG, msg, args, **kwargs)


class SafeRotatingFileHandler(logging.handlers.RotatingFileHandler):
    def doRollover(self) -> None:
        try:
            super().doRollover()
        except PermissionError:
            return

def setup_logger(name: str = 'app_logger', level: int = logging.DEBUG) -> 'FlexibleColorLogger':
    logging.setLoggerClass(FlexibleColorLogger)
    logger = logging.getLogger(name)
    logger.setLevel(level)
    logger.propagate = False
    
    stream_handler = logging.StreamHandler()
    stream_handler.setLevel(level)
    stream_handler.setFormatter(ColorFormatter())
    
    handlers = [stream_handler]
    
    logs_to_files = os.getenv('LOGS_TO_FILES', 'false').lower() == 'true'
    if logs_to_files:
        try:
            logs_dir = Path('logs')
            logs_dir.mkdir(exist_ok=True)
            
            date_str = datetime.now().strftime('%Y-%m-%d')
            log_file = logs_dir / f"{date_str}.log"
            
            file_handler = SafeRotatingFileHandler(
                filename=str(log_file),
                maxBytes=10 * 1024 * 1024,
                backupCount=10,
                encoding='utf-8'
            )
            file_handler.setLevel(level)
            file_handler.setFormatter(FileFormatter())
            handlers.append(file_handler)
        except Exception:
            pass
    
    logger.handlers = handlers
    
    for logger_name, log_level in IGNORED_MODULES.items():
        logging.getLogger(logger_name).setLevel(getattr(logging, log_level))
    
    return logger

if config.get("debug", True):
    level = logging.DEBUG
else:
    level = logging.INFO

app_logger = setup_logger(name='central_logger', level=level)


if __name__ == "__main__":
    app_logger.info("This is an info message")
    app_logger.success("socrates is 'human' and he is mortal")
    app_logger.warning("This is a warning message")
    app_logger.error("This is an error message")
    app_logger.success("This is a success message")
    app_logger.important("This is an important message")
    app_logger.colored_info("This is a colored info message", color="green")
    app_logger.colored_info("This is a colored info message", color="red")
    app_logger.colored_info("This is a colored info message", color="blue")
    app_logger.colored_info("This is a colored info message", color="yellow")