from __future__ import annotations

import logging
import sys
from pathlib import Path

__all__ = ["logger", "log_to_file", "set_level"]

BLACK = "\033[30m"
ORANGE = "\033[33m"
RED = "\033[31m"
RESET = "\033[0m"


class MultiLineFormatter(logging.Formatter):
    """Detect multi-line logs and adds newlines with colors."""

    # ANSI escape codes for colors
    COLOURS = {
        "DEBUG": BLACK,
        "INFO": BLACK,
        "WARNING": ORANGE,
        "ERROR": RED,
        "CRITICAL": RED,
    }

    def __init__(self):
        super().__init__("[%(name)s %(levelname)s]: %(message)s")

    def format(self, record: logging.LogRecord) -> str:
        record.msg = str(record.msg).strip()
        # add in new lines
        if "\n" in record.msg:
            record.msg = "\n" + record.msg + "\n"
        formatted = super().format(record)

        # add in color
        color = self.COLOURS.get(record.levelname, "")
        formatted = f"{color}{formatted}{RESET}"

        return formatted


# create the graph-pes logger
logger = logging.getLogger(name="graph-pes")

# log to stdout
_handler = logging.StreamHandler(stream=sys.stdout)
_handler.setFormatter(MultiLineFormatter())
logger.addHandler(_handler)

# capture all logs but only show INFO and above in stdout (by default)
logger.setLevel(logging.DEBUG)
_handler.setLevel(logging.INFO)


def log_to_file(file: str | Path):
    """Append logs to a file."""

    file = Path(file)
    file.parent.mkdir(parents=True, exist_ok=True)

    handler = logging.FileHandler(file, mode="a")
    handler.setLevel(logging.DEBUG)
    handler.setFormatter(MultiLineFormatter())

    logger.addHandler(handler)
    logger.info(f"Logging to {file}")


def set_level(level: str | int):
    """Set the logging level."""

    _handler.setLevel(level)
    logger.debug(f"Set logging level to {level}")
