from .colors import ConsoleColors


class GradientFormatter:
    def __init__(self, start_rgb=(189, 147, 249), end_rgb=(139, 233, 253)):
        self.start_rgb = start_rgb
        self.end_rgb = end_rgb
    
    def format_text(self, text):
        return self._gradient_fmt(text, self.start_rgb, self.end_rgb)
    
    def format_background(self, text, bold=False):
        return self._gradient_bg_fmt(text, self.start_rgb, self.end_rgb, bold)
    
    def _gradient_fmt(self, text, start_rgb, end_rgb):
        r1, g1, b1 = start_rgb
        r2, g2, b2 = end_rgb
        length = len(text)
        if length == 0:
            return ""
        result = ""
        for i, char in enumerate(text):
            if length > 1:
                r = int(r1 + (r2 - r1) * i / (length - 1))
                g = int(g1 + (g2 - g1) * i / (length - 1))
                b = int(b1 + (b2 - b1) * i / (length - 1))
            else:
                r, g, b = r1, g1, b1
            result += f"\033[38;2;{r};{g};{b}m{char}"
        return result + ConsoleColors.RESET
    
    def _gradient_bg_fmt(self, text, start_rgb, end_rgb, bold=False):
        r1, g1, b1 = start_rgb
        r2, g2, b2 = end_rgb
        length = len(text)
        if length == 0:
            return ""
        result = ""
        fg_style = "\033[38;2;0;0;0m"
        if bold:
            fg_style += ConsoleColors.BOLD
        for i, char in enumerate(text):
            if length > 1:
                r = int(r1 + (r2 - r1) * i / (length - 1))
                g = int(g1 + (g2 - g1) * i / (length - 1))
                b = int(b1 + (b2 - b1) * i / (length - 1))
            else:
                r, g, b = r1, g1, b1
            result += f"\033[48;2;{r};{g};{b}m{fg_style}{char}"
        return result + ConsoleColors.RESET


class MultiStopGradient:
    def __init__(self, *colors):
        self.colors = colors if colors else [(255, 255, 255)]
    
    def format_text(self, text):
        if len(self.colors) < 2:
            r, g, b = self.colors[0]
            return f"\033[38;2;{r};{g};{b}m{text}{ConsoleColors.RESET}"
        
        length = len(text)
        if length == 0:
            return ""
        
        segments = len(self.colors) - 1
        chars_per_segment = length / segments
        
        result = ""
        for i, char in enumerate(text):
            segment = min(int(i / chars_per_segment), segments - 1)
            pos_in_segment = (i - segment * chars_per_segment) / chars_per_segment
            
            r1, g1, b1 = self.colors[segment]
            r2, g2, b2 = self.colors[segment + 1]
            
            r = int(r1 + (r2 - r1) * pos_in_segment)
            g = int(g1 + (g2 - g1) * pos_in_segment)
            b = int(b1 + (b2 - b1) * pos_in_segment)
            
            result += f"\033[38;2;{r};{g};{b}m{char}"
        
        return result + ConsoleColors.RESET


class TimestampFormatter:
    def __init__(self, fmt="%H:%M:%S", color=None):
        self.fmt = fmt
        self.color = color or ConsoleColors.GRAY
    
    def format(self, dt=None):
        import datetime
        if dt is None:
            dt = datetime.datetime.now()
        timestamp = dt.strftime(self.fmt)
        return f"{self.color}[-({timestamp})-]{ConsoleColors.RESET}"


class LevelFormatter:
    DEFAULT_FORMATS = {
        "DEBUG": (ConsoleColors.GRAY, "DEBUG", "●"),
        "INFO": (ConsoleColors.CYAN, "INFO", "●"),
        "SUCCESS": (ConsoleColors.GREEN, "SUCCESS", "●"),
        "WARNING": (ConsoleColors.YELLOW, "WARNING", "●"),
        "ERROR": (ConsoleColors.RED, "ERROR", "●"),
        "CRITICAL": (ConsoleColors.PURPLE, "CRITICAL", "●"),
    }
    
    def __init__(self, custom_formats=None):
        self.formats = {**self.DEFAULT_FORMATS}
        if custom_formats:
            self.formats.update(custom_formats)
    
    def format(self, level):
        if level.upper() in self.formats:
            color, name, symbol = self.formats[level.upper()]
            return f"{color}[ {symbol} ] {ConsoleColors.BOLD}{name} {ConsoleColors.RESET}"
        return f"[ ? ] {level} "
    
    def set_format(self, level, color, name=None, symbol="●"):
        self.formats[level.upper()] = (color, name or level, symbol)
