/**
 * Color utility functions for ColorPicker component
 * Handles conversion between HEX, RGB, HSL, and HSV color formats
 */
/**
 * Convert HEX color to RGB
 * @param hex - Hex color string (e.g., "#FF5733" or "FF5733")
 * @returns RGB object
 */
const hexToRgb = (hex) => {
    // Remove # if present
    const cleanHex = hex.replace(/^#/, '');
    // Validate hex format
    if (!/^[0-9A-Fa-f]{6}$/.test(cleanHex)) {
        if (process.env.NODE_ENV !== 'production') {
            console.warn('[ColorPicker]: Invalid hex color format:', hex);
        }
        return null;
    }
    const r = parseInt(cleanHex.substring(0, 2), 16);
    const g = parseInt(cleanHex.substring(2, 4), 16);
    const b = parseInt(cleanHex.substring(4, 6), 16);
    return { r, g, b };
};
/**
 * Convert RGB to HEX color
 * @param r - Red (0-255)
 * @param g - Green (0-255)
 * @param b - Blue (0-255)
 * @returns Hex color string with # prefix
 */
const rgbToHex = (r, g, b) => {
    const toHex = (n) => {
        const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16);
        return hex.length === 1 ? '0' + hex : hex;
    };
    return `#${toHex(r)}${toHex(g)}${toHex(b)}`.toUpperCase();
};
/**
 * Convert RGB to HSL
 * @param r - Red (0-255)
 * @param g - Green (0-255)
 * @param b - Blue (0-255)
 * @returns HSL object
 */
const rgbToHsl = (r, g, b) => {
    r /= 255;
    g /= 255;
    b /= 255;
    const max = Math.max(r, g, b);
    const min = Math.min(r, g, b);
    let h = 0;
    let s = 0;
    const l = (max + min) / 2;
    if (max !== min) {
        const d = max - min;
        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
        switch (max) {
            case r:
                h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
                break;
            case g:
                h = ((b - r) / d + 2) / 6;
                break;
            case b:
                h = ((r - g) / d + 4) / 6;
                break;
        }
    }
    return {
        h: Math.round(h * 360),
        s: Math.round(s * 100),
        l: Math.round(l * 100),
    };
};
/**
 * Convert HSL to RGB
 * @param h - Hue (0-360)
 * @param s - Saturation (0-100)
 * @param l - Lightness (0-100)
 * @returns RGB object
 */
const hslToRgb = (h, s, l) => {
    h = ((h % 360) + 360) % 360; // Normalize hue
    s = Math.max(0, Math.min(100, s)) / 100;
    l = Math.max(0, Math.min(100, l)) / 100;
    const c = (1 - Math.abs(2 * l - 1)) * s;
    const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
    const m = l - c / 2;
    let r = 0;
    let g = 0;
    let b = 0;
    if (h >= 0 && h < 60) {
        r = c;
        g = x;
        b = 0;
    }
    else if (h >= 60 && h < 120) {
        r = x;
        g = c;
        b = 0;
    }
    else if (h >= 120 && h < 180) {
        r = 0;
        g = c;
        b = x;
    }
    else if (h >= 180 && h < 240) {
        r = 0;
        g = x;
        b = c;
    }
    else if (h >= 240 && h < 300) {
        r = x;
        g = 0;
        b = c;
    }
    else if (h >= 300 && h < 360) {
        r = c;
        g = 0;
        b = x;
    }
    return {
        r: Math.round((r + m) * 255),
        g: Math.round((g + m) * 255),
        b: Math.round((b + m) * 255),
    };
};
/**
 * Convert RGB to HSV
 * @param r - Red (0-255)
 * @param g - Green (0-255)
 * @param b - Blue (0-255)
 * @returns HSV object
 */
const rgbToHsv = (r, g, b) => {
    r /= 255;
    g /= 255;
    b /= 255;
    const max = Math.max(r, g, b);
    const min = Math.min(r, g, b);
    const d = max - min;
    let h = 0;
    const s = max === 0 ? 0 : d / max;
    const v = max;
    if (max !== min) {
        switch (max) {
            case r:
                h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
                break;
            case g:
                h = ((b - r) / d + 2) / 6;
                break;
            case b:
                h = ((r - g) / d + 4) / 6;
                break;
        }
    }
    return {
        h: Math.round(h * 360),
        s: Math.round(s * 100),
        v: Math.round(v * 100),
    };
};
/**
 * Convert HSV to RGB
 * @param h - Hue (0-360)
 * @param s - Saturation (0-100)
 * @param v - Value (0-100)
 * @returns RGB object
 */
const hsvToRgb = (h, s, v) => {
    h = ((h % 360) + 360) % 360; // Normalize hue
    s = Math.max(0, Math.min(100, s)) / 100;
    v = Math.max(0, Math.min(100, v)) / 100;
    const c = v * s;
    const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
    const m = v - c;
    let r = 0;
    let g = 0;
    let b = 0;
    if (h >= 0 && h < 60) {
        r = c;
        g = x;
        b = 0;
    }
    else if (h >= 60 && h < 120) {
        r = x;
        g = c;
        b = 0;
    }
    else if (h >= 120 && h < 180) {
        r = 0;
        g = c;
        b = x;
    }
    else if (h >= 180 && h < 240) {
        r = 0;
        g = x;
        b = c;
    }
    else if (h >= 240 && h < 300) {
        r = x;
        g = 0;
        b = c;
    }
    else if (h >= 300 && h < 360) {
        r = c;
        g = 0;
        b = x;
    }
    return {
        r: Math.round((r + m) * 255),
        g: Math.round((g + m) * 255),
        b: Math.round((b + m) * 255),
    };
};
/**
 * Validate hex color format
 * @param hex - Hex color string
 * @returns True if valid hex format
 */
const validateHex = (hex) => {
    const cleanHex = hex.replace(/^#/, '');
    return /^[0-9A-Fa-f]{6}$/.test(cleanHex);
};
/**
 * Validate RGB color values
 * @param r - Red (0-255)
 * @param g - Green (0-255)
 * @param b - Blue (0-255)
 * @returns True if all values are valid
 */
const validateRgb = (r, g, b) => {
    return (Number.isInteger(r) && r >= 0 && r <= 255 &&
        Number.isInteger(g) && g >= 0 && g <= 255 &&
        Number.isInteger(b) && b >= 0 && b <= 255);
};
/**
 * Parse color string to HSLA
 * Supports hex, rgb, rgba, hsl, hsla formats
 * @param value - Color string in various formats
 * @returns HSLA object or null if invalid
 */
const parseColor = (value) => {
    if (!value)
        return null;
    const trimmed = value.trim();
    // Parse HEX format
    if (trimmed.startsWith('#')) {
        const rgb = hexToRgb(trimmed);
        if (!rgb)
            return null;
        const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
        return { ...hsl, a: 1 };
    }
    // Parse RGB/RGBA format
    const rgbMatch = trimmed.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)$/);
    if (rgbMatch) {
        const r = parseInt(rgbMatch[1], 10);
        const g = parseInt(rgbMatch[2], 10);
        const b = parseInt(rgbMatch[3], 10);
        const a = rgbMatch[4] ? parseFloat(rgbMatch[4]) : 1;
        if (!validateRgb(r, g, b))
            return null;
        const hsl = rgbToHsl(r, g, b);
        return { ...hsl, a };
    }
    // Parse HSL/HSLA format
    const hslMatch = trimmed.match(/^hsla?\((\d+),\s*(\d+)%,\s*(\d+)%(?:,\s*([\d.]+))?\)$/);
    if (hslMatch) {
        const h = parseInt(hslMatch[1], 10);
        const s = parseInt(hslMatch[2], 10);
        const l = parseInt(hslMatch[3], 10);
        const a = hslMatch[4] ? parseFloat(hslMatch[4]) : 1;
        return { h, s, l, a };
    }
    if (process.env.NODE_ENV !== 'production') {
        console.warn('[ColorPicker]: Unsupported color format:', value);
    }
    return null;
};
/**
 * Format HSLA to hex string
 * @param h - Hue (0-360)
 * @param s - Saturation (0-100)
 * @param l - Lightness (0-100)
 * @returns Hex color string
 */
const formatHex = (h, s, l) => {
    const rgb = hslToRgb(h, s, l);
    return rgbToHex(rgb.r, rgb.g, rgb.b);
};
/**
 * Format HSLA to RGB string
 * @param h - Hue (0-360)
 * @param s - Saturation (0-100)
 * @param l - Lightness (0-100)
 * @param a - Alpha (0-1)
 * @returns RGB/RGBA string
 */
const formatRgb = (h, s, l, a = 1) => {
    const rgb = hslToRgb(h, s, l);
    if (a < 1) {
        return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${a.toFixed(2)})`;
    }
    return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;
};
/**
 * Format HSLA to HSL string
 * @param h - Hue (0-360)
 * @param s - Saturation (0-100)
 * @param l - Lightness (0-100)
 * @param a - Alpha (0-1)
 * @returns HSL/HSLA string
 */
const formatHsl = (h, s, l, a = 1) => {
    if (a < 1) {
        return `hsla(${Math.round(h)}, ${Math.round(s)}%, ${Math.round(l)}%, ${a.toFixed(2)})`;
    }
    return `hsl(${Math.round(h)}, ${Math.round(s)}%, ${Math.round(l)}%)`;
};

export { formatHex, formatHsl, formatRgb, hexToRgb, hslToRgb, hsvToRgb, parseColor, rgbToHex, rgbToHsl, rgbToHsv, validateHex, validateRgb };
