"""
y4seenx - Ultimate Color Utilities
Supports HEX, RGB, HSL, HSV, CMYK and more!
"""
import re
from typing import Tuple, Union
import colorsys


class Color:
    """Ultimate Color class - handles ANY color format"""
    
    def __init__(self, r: int, g: int, b: int):
        """Initialize with RGB values (0-255)"""
        self.r = max(0, min(255, r))
        self.g = max(0, min(255, g))
        self.b = max(0, min(255, b))
    
    @classmethod
    def from_hex(cls, hex_color: str) -> 'Color':
        """Create Color from HEX (#FF5733, FF5733, or 0xFF5733)"""
        hex_color = hex_color.strip().replace('#', '').replace('0x', '').replace('0X', '')
        if len(hex_color) == 3:
            hex_color = ''.join([c*2 for c in hex_color])
        if len(hex_color) != 6:
            raise ValueError(f"Invalid HEX color: {hex_color}")
        r = int(hex_color[0:2], 16)
        g = int(hex_color[2:4], 16)
        b = int(hex_color[4:6], 16)
        return cls(r, g, b)
    
    @classmethod
    def from_rgb(cls, r: int, g: int, b: int) -> 'Color':
        """Create Color from RGB (0-255)"""
        return cls(r, g, b)
    
    @classmethod
    def from_hsl(cls, h: float, s: float, l: float) -> 'Color':
        """Create Color from HSL (h: 0-360, s: 0-100, l: 0-100)"""
        h = h / 360.0
        s = s / 100.0
        l = l / 100.0
        r, g, b = colorsys.hls_to_rgb(h, l, s)
        return cls(int(r * 255), int(g * 255), int(b * 255))
    
    @classmethod
    def from_hsv(cls, h: float, s: float, v: float) -> 'Color':
        """Create Color from HSV (h: 0-360, s: 0-100, v: 0-100)"""
        h = h / 360.0
        s = s / 100.0
        v = v / 100.0
        r, g, b = colorsys.hsv_to_rgb(h, s, v)
        return cls(int(r * 255), int(g * 255), int(b * 255))
    
    @classmethod
    def from_cmyk(cls, c: float, m: float, y: float, k: float) -> 'Color':
        """Create Color from CMYK (0-100 for each)"""
        c, m, y, k = c/100.0, m/100.0, y/100.0, k/100.0
        r = int(255 * (1 - c) * (1 - k))
        g = int(255 * (1 - m) * (1 - k))
        b = int(255 * (1 - y) * (1 - k))
        return cls(r, g, b)
    
    def to_hex(self) -> str:
        """Convert to HEX format"""
        return f"#{self.r:02x}{self.g:02x}{self.b:02x}"
    
    def to_rgb(self) -> Tuple[int, int, int]:
        """Convert to RGB tuple"""
        return (self.r, self.g, self.b)
    
    def to_hsl(self) -> Tuple[float, float, float]:
        """Convert to HSL (h: 0-360, s: 0-100, l: 0-100)"""
        r, g, b = self.r/255.0, self.g/255.0, self.b/255.0
        h, l, s = colorsys.rgb_to_hls(r, g, b)
        return (h * 360, s * 100, l * 100)
    
    def to_hsv(self) -> Tuple[float, float, float]:
        """Convert to HSV (h: 0-360, s: 0-100, v: 0-100)"""
        r, g, b = self.r/255.0, self.g/255.0, self.b/255.0
        h, s, v = colorsys.rgb_to_hsv(r, g, b)
        return (h * 360, s * 100, v * 100)
    
    def to_ansi(self, background: bool = False) -> str:
        """Convert to ANSI escape code for terminal"""
        code = 48 if background else 38
        return f"\033[{code};2;{self.r};{self.g};{self.b}m"
    
    def interpolate(self, other: 'Color', factor: float) -> 'Color':
        """Interpolate between this color and another (factor: 0.0 to 1.0)"""
        r = int(self.r + (other.r - self.r) * factor)
        g = int(self.g + (other.g - self.g) * factor)
        b = int(self.b + (other.b - self.b) * factor)
        return Color(r, g, b)
    
    def lighten(self, amount: float = 0.1) -> 'Color':
        """Lighten color by amount (0.0 to 1.0)"""
        h, s, l = self.to_hsl()
        l = min(100, l + (amount * 100))
        return Color.from_hsl(h, s, l)
    
    def darken(self, amount: float = 0.1) -> 'Color':
        """Darken color by amount (0.0 to 1.0)"""
        h, s, l = self.to_hsl()
        l = max(0, l - (amount * 100))
        return Color.from_hsl(h, s, l)
    
    def __repr__(self):
        return f"Color(r={self.r}, g={self.g}, b={self.b}) {self.to_hex()}"


def parse_color(color: Union[str, Tuple, Color]) -> Color:
    """
    Parse any color format to Color object
    Supports: HEX, RGB tuple, HSL tuple, Color object
    """
    if isinstance(color, Color):
        return color
    
    if isinstance(color, str):
        # HEX format
        if '#' in color or 'x' in color.lower() or re.match(r'^[0-9A-Fa-f]{3,6}$', color.replace('#', '')):
            return Color.from_hex(color)
        
        # Named colors (optional - can be extended)
        named_colors = {
            'red': '#FF0000', 'green': '#00FF00', 'blue': '#0000FF',
            'yellow': '#FFFF00', 'cyan': '#00FFFF', 'magenta': '#FF00FF',
            'white': '#FFFFFF', 'black': '#000000', 'orange': '#FFA500',
            'purple': '#800080', 'pink': '#FFC0CB', 'lime': '#00FF00',
            'navy': '#000080', 'teal': '#008080', 'gold': '#FFD700',
            'silver': '#C0C0C0', 'gray': '#808080', 'maroon': '#800000'
        }
        if color.lower() in named_colors:
            return Color.from_hex(named_colors[color.lower()])
        
        raise ValueError(f"Unknown color format: {color}")
    
    if isinstance(color, (tuple, list)):
        if len(color) == 3:
            return Color.from_rgb(*color)
        else:
            raise ValueError(f"Invalid RGB tuple: {color}")
    
    raise ValueError(f"Cannot parse color: {color}")
