import importlib.metadata
import logging
import os.path
from enum import Enum, auto
from sys import stdout

from strenum import StrEnum


## Constants
class Constants:
    MELEE_DATE_FORMAT = "%m/%d/%Y"
    MTGO_DATE_FORMAT = "%B %d, %Y"
    VERSION = importlib.metadata.version("scraptrawler")
    USER_AGENT = f"scraptrawler {VERSION}"
    UUID_PATTERN = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"


def get_logger(
    filename: str,
    logger_name: str,
    file_logging_level: int = logging.DEBUG,
    console_logging_level: int = logging.WARNING,
    formatter: logging.Formatter = logging.Formatter("%(asctime)s - %(name)s:%(levelname)s - %(message)s"),
):
    """
    Helper function to get a new logger.

    Parameters:
        filename (str): Filename of the log file.
        logger_name (str): The logger's name.
        file_logging_level (int): Logging level for the log file.
        console_logging_level (int): Logging level for stdout.
        formatter (logging.Formatter): The Formatter to be used in messages generated by this logger.

    Returns:
        logger (logging.Logger): A new logger.
    """

    # Create directory if not exists
    filepath = os.path.join("logs", filename)
    os.makedirs(os.path.dirname(filepath), exist_ok=True)

    # Handlers
    fh = logging.FileHandler(filepath, mode="a", encoding="UTF-8", delay=False)
    fh.setLevel(file_logging_level)
    ch = logging.StreamHandler(stdout)
    ch.setLevel(console_logging_level)

    # Formatting
    fh.setFormatter(formatter)
    ch.setFormatter(formatter)

    # Create the logger
    logger = logging.getLogger(logger_name)
    logger.setLevel(logging.DEBUG)
    logger.addHandler(fh)
    logger.addHandler(ch)

    return logger


class ExtendedEnum(Enum):
    """
    An extension of the classic Python Enum to support additional behaviors.

    Methods
    -------
    list():
        Returns a list of the attributes of this Enum.
    get(key):
        Returns the value if it has a matching key. Otherwise, None.
    """

    @classmethod
    def list(cls):
        return list(map(lambda c: c.value, cls))

    @classmethod
    def get(cls, key):
        key = str(key).strip().lower()
        for v in cls.list():
            if key == str(v).lower():
                return cls(v)


class DecklistFormatter(ExtendedEnum, StrEnum):
    """
    A method of formatting a decklist for external systems.

    Attributes
    ----------
    ARENA: Magic: the Gathering Arena
    MTGO: Magic: the Gathering Online
    """

    ARENA = auto()
    MTGO = auto()
