"""
Color Primitives Library

Color manipulation: RGB, HSV, blending, luminance.
"""
import numpy as np
import colorsys


def prim_rgb(r, g, b):
    """Create RGB color as [r, g, b] (0-255)."""
    return [int(max(0, min(255, r))),
            int(max(0, min(255, g))),
            int(max(0, min(255, b)))]


def prim_red(c):
    return c[0]


def prim_green(c):
    return c[1]


def prim_blue(c):
    return c[2]


def prim_luminance(c):
    """Perceived luminance (0-1) using standard weights."""
    return (0.299 * c[0] + 0.587 * c[1] + 0.114 * c[2]) / 255


def prim_rgb_to_hsv(c):
    """Convert RGB [0-255] to HSV [h:0-360, s:0-1, v:0-1]."""
    r, g, b = c[0] / 255, c[1] / 255, c[2] / 255
    h, s, v = colorsys.rgb_to_hsv(r, g, b)
    return [h * 360, s, v]


def prim_hsv_to_rgb(hsv):
    """Convert HSV [h:0-360, s:0-1, v:0-1] to RGB [0-255]."""
    h, s, v = hsv[0] / 360, hsv[1], hsv[2]
    r, g, b = colorsys.hsv_to_rgb(h, s, v)
    return [int(r * 255), int(g * 255), int(b * 255)]


def prim_rgb_to_hsl(c):
    """Convert RGB [0-255] to HSL [h:0-360, s:0-1, l:0-1]."""
    r, g, b = c[0] / 255, c[1] / 255, c[2] / 255
    h, l, s = colorsys.rgb_to_hls(r, g, b)
    return [h * 360, s, l]


def prim_hsl_to_rgb(hsl):
    """Convert HSL [h:0-360, s:0-1, l:0-1] to RGB [0-255]."""
    h, s, l = hsl[0] / 360, hsl[1], hsl[2]
    r, g, b = colorsys.hls_to_rgb(h, l, s)
    return [int(r * 255), int(g * 255), int(b * 255)]


def prim_blend_color(c1, c2, alpha):
    """Blend two colors: c1 * (1-alpha) + c2 * alpha."""
    return [int(c1[i] * (1 - alpha) + c2[i] * alpha) for i in range(3)]


def prim_average_color(img):
    """Get average color of an image."""
    mean = np.mean(img, axis=(0, 1))
    return [int(mean[0]), int(mean[1]), int(mean[2])]


def prim_dominant_color(img, k=1):
    """Get dominant color using k-means (simplified: just average for now)."""
    return prim_average_color(img)


def prim_invert_color(c):
    """Invert a color."""
    return [255 - c[0], 255 - c[1], 255 - c[2]]


def prim_grayscale_color(c):
    """Convert color to grayscale."""
    gray = int(0.299 * c[0] + 0.587 * c[1] + 0.114 * c[2])
    return [gray, gray, gray]


def prim_saturate(c, amount):
    """Adjust saturation of color. amount=0 is grayscale, 1 is unchanged, >1 is more saturated."""
    hsv = prim_rgb_to_hsv(c)
    hsv[1] = max(0, min(1, hsv[1] * amount))
    return prim_hsv_to_rgb(hsv)


def prim_brighten(c, amount):
    """Adjust brightness. amount=0 is black, 1 is unchanged, >1 is brighter."""
    return [int(max(0, min(255, c[i] * amount))) for i in range(3)]


def prim_shift_hue(c, degrees):
    """Shift hue by degrees."""
    hsv = prim_rgb_to_hsv(c)
    hsv[0] = (hsv[0] + degrees) % 360
    return prim_hsv_to_rgb(hsv)


PRIMITIVES = {
    # Construction
    'rgb': prim_rgb,

    # Component access
    'red': prim_red,
    'green': prim_green,
    'blue': prim_blue,
    'luminance': prim_luminance,

    # Color space conversion
    'rgb->hsv': prim_rgb_to_hsv,
    'hsv->rgb': prim_hsv_to_rgb,
    'rgb->hsl': prim_rgb_to_hsl,
    'hsl->rgb': prim_hsl_to_rgb,

    # Blending
    'blend-color': prim_blend_color,

    # Analysis
    'average-color': prim_average_color,
    'dominant-color': prim_dominant_color,

    # Manipulation
    'invert-color': prim_invert_color,
    'grayscale-color': prim_grayscale_color,
    'saturate': prim_saturate,
    'brighten': prim_brighten,
    'shift-hue': prim_shift_hue,
}
