import sys
from time import sleep
from rich import print as rp
from rich.prompt import Confirm
from rich.markup import escape
from datetime import datetime

class Log:
    """
    Class printing message on terminal
    """

    log_file = "log.glpwnme"
    quiet = False
    debug = False

    @classmethod
    def log(cls, m, save=False, **kwargs):
        """
        Log a message on the console

        :param m: The message to log
        :type m: str

        :param save: Whether or not to save the message in the log
        :type save: bool
        """
        if cls.quiet:
            return
        if save:
            cls.write(m)
        escaped = escape("[!]")
        rp(f"[bright_yellow]{escaped}[/bright_yellow] {m}", **kwargs)

    @classmethod
    def msg(cls, m, save=False, **kwargs):
        """
        Print a successfull message on the console

        :param m: The message to log
        :type m: str

        :param save: Whether or not to save the message in the log
        :type save: bool
        """
        if cls.quiet:
            return
        if save:
            cls.write(m)
        escaped = escape("[+]")
        rp(f"[green]{escaped}[/green] {m}", **kwargs)

    @classmethod
    def err(cls, m, save=False, **kwargs):
        """
        Print an error message on the console

        :param m: The message to log
        :type m: Union[str, Exception]

        :param save: Whether or not to save the message in the log
        :type save: bool
        """
        if cls.quiet:
            return
        if save:
            cls.write(m)

        escaped = escape("[-]")
        if isinstance(m, Exception):
            rp(f"[red]{escaped}[/red] {m.__class__.__name__}: {m}", **kwargs)
        else:
            rp(f"[red]{escaped}[/red] {m}", **kwargs)

    @classmethod
    def print(cls, m, **kwargs):
        """
        Just print a message with rich
        this avoid importing rich and Log
        """
        if cls.quiet:
            return
        rp(m, **kwargs)

    @classmethod
    def debug(cls, m, **kwargs):
        """
        Just print a message with rich
        this avoid importing rich and Log
        """
        if not cls.debug:
            return
        escaped = escape("[DEBUG]")
        rp(f"[gold3]{escaped}[/gold3] {m}", **kwargs)

    @staticmethod
    def ask(msg, **kwargs):
        """
        Wrapper for Confirm.ask method from rich
        """
        escaped = escape("[?]")
        return Confirm.ask(f"[blue]{escaped}[/blue] {msg}", **kwargs)

    @classmethod
    def pad(cls, n=2):
        """
        Add padding to print
        """
        if cls.quiet:
            return
        print(" " * n, end="")
        return cls

    @classmethod
    def write(cls, msg):
        """
        Write a msg in the log file to not lose some important
        log
        """
        now = datetime.now()
        log_date = now.strftime("[%Y-%m-%d %H:%M:%S] ").encode()
        if isinstance(msg, str):
            msg = msg.encode()

        with open(cls.log_file, "ab") as log:
            log.write(log_date + msg)
            log.write(b"\n")

class KiddieLogger:
    """
    Just a logger that display text with a fixed interval
    """
    interval = 0.05

    @classmethod
    def display(cls, text, color=None, end="\n"):
        """
        Display the text

        :param text: The text do display on screen
        :type text: str

        :param color: The color to use (ANSI code)
        :type color: optional(str)

        :param newline: End char
        :type newline: str (default: "\n")
        """
        if color:
            sys.stdout.write(f"{color}")

        for letter in text:
            sys.stdout.write(letter)
            sys.stdout.flush()
            sleep(cls.interval)

        if color:
            sys.stdout.write(f"\x1b[0m")

        if end:
            sys.stdout.write(end)
