/**
 * Utilitários para manipulação de cores e garantia de acessibilidade
 */

/**
 * Converte hex para RGB
 */
export function hexToRgb(hex: string): { r: number; g: number; b: number } | null {
    const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result
        ? {
            r: parseInt(result[1], 16),
            g: parseInt(result[2], 16),
            b: parseInt(result[3], 16),
        }
        : null;
}

/**
 * Converte RGB para hex
 */
export function rgbToHex(r: number, g: number, b: number): string {
    return '#' + [r, g, b].map((x) => {
        const hex = Math.round(x).toString(16);
        return hex.length === 1 ? '0' + hex : hex;
    }).join('');
}

/**
 * Calcula luminosidade relativa (0-1) - WCAG 2.0
 */
export function getLuminance(hex: string): number {
    const rgb = hexToRgb(hex);
    if (!rgb) return 0;

    const [r, g, b] = [rgb.r, rgb.g, rgb.b].map((val) => {
        const v = val / 255;
        return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
    });

    return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}

/**
 * Calcula contraste entre duas cores (1-21) - WCAG 2.0
 */
export function getContrast(color1: string, color2: string): number {
    const lum1 = getLuminance(color1);
    const lum2 = getLuminance(color2);
    const lighter = Math.max(lum1, lum2);
    const darker = Math.min(lum1, lum2);
    return (lighter + 0.05) / (darker + 0.05);
}

/**
 * Verifica se a cor é clara (luminosidade > 0.5)
 */
export function isLight(hex: string): boolean {
    return getLuminance(hex) > 0.5;
}

/**
 * Escurece uma cor em uma porcentagem
 */
export function darken(hex: string, amount: number): string {
    const rgb = hexToRgb(hex);
    if (!rgb) return hex;

    const factor = 1 - amount;
    return rgbToHex(
        rgb.r * factor,
        rgb.g * factor,
        rgb.b * factor
    );
}

/**
 * Clareia uma cor em uma porcentagem
 */
export function lighten(hex: string, amount: number): string {
    const rgb = hexToRgb(hex);
    if (!rgb) return hex;

    const factor = amount;
    return rgbToHex(
        rgb.r + (255 - rgb.r) * factor,
        rgb.g + (255 - rgb.g) * factor,
        rgb.b + (255 - rgb.b) * factor
    );
}

/**
 * Gera cor de hover automática baseada na luminosidade
 * Se a cor for clara, escurece 15%
 * Se a cor for escura, clareia 15%
 */
export function generateHoverColor(hex: string): string {
    return isLight(hex) ? darken(hex, 0.15) : lighten(hex, 0.15);
}

/**
 * Determina se deve usar texto branco ou preto sobre uma cor de fundo
 * Prioriza branco para cores vibrantes/saturadas
 */
export function getTextColor(backgroundColor: string): string {
    const contrastWithWhite = getContrast(backgroundColor, '#FFFFFF');
    const contrastWithBlack = getContrast(backgroundColor, '#000000');

    // Se o contraste com branco for >= 3.5, prefere branco (mais comum em UIs modernas)
    // WCAG AA requer 4.5:1, mas 3:1 para textos grandes
    if (contrastWithWhite >= 3.5) {
        return '#FFFFFF';
    }

    // Se não, usa a cor com melhor contraste
    return contrastWithWhite > contrastWithBlack ? '#FFFFFF' : '#000000';
}

/**
 * Gera paleta completa de cores com hover e variações
 */
export function generateColorPalette(primaryHex: string, secondaryHex: string) {
    const primaryRgb = hexToRgb(primaryHex);
    const secondaryRgb = hexToRgb(secondaryHex);

    if (!primaryRgb || !secondaryRgb) {
        throw new Error('Cores inválidas');
    }

    const primaryHover = generateHoverColor(primaryHex);
    const secondaryHover = generateHoverColor(secondaryHex);

    const primaryRgbString = `${primaryRgb.r} ${primaryRgb.g} ${primaryRgb.b}`;
    const secondaryRgbString = `${secondaryRgb.r} ${secondaryRgb.g} ${secondaryRgb.b}`;
    const hoverRgb = hexToRgb(primaryHover);
    const hoverRgbString = hoverRgb ? `${hoverRgb.r} ${hoverRgb.g} ${hoverRgb.b}` : secondaryRgbString;

    return {
        primary: primaryHex,
        secondary: secondaryHex,
        primaryHover,
        secondaryHover,
        primaryRgb: primaryRgbString,
        secondaryRgb: secondaryRgbString,
        hoverRgb: hoverRgbString,
        gradient: `linear-gradient(135deg, ${primaryHex}, ${secondaryHex})`,
        textOnPrimary: getTextColor(primaryHex),
        textOnSecondary: getTextColor(secondaryHex),
        isLightPrimary: isLight(primaryHex),
        isLightSecondary: isLight(secondaryHex),
        contrast: getContrast(primaryHex, secondaryHex),
    };
}

/**
 * Valida se as cores têm contraste suficiente
 */
export function validateColorContrast(primary: string, secondary: string): {
    valid: boolean;
    warnings: string[];
} {
    const warnings: string[] = [];
    const contrast = getContrast(primary, secondary);

    if (contrast < 3) {
        warnings.push('As cores são muito similares e podem causar problemas de legibilidade');
    }

    const primaryContrast = getContrast(primary, '#FFFFFF');
    if (primaryContrast < 4.5 && !isLight(primary)) {
        warnings.push('A cor primária pode ter baixo contraste com texto branco');
    }

    const secondaryContrast = getContrast(secondary, '#FFFFFF');
    if (secondaryContrast < 4.5 && !isLight(secondary)) {
        warnings.push('A cor secundária pode ter baixo contraste com texto branco');
    }

    return {
        valid: warnings.length === 0,
        warnings,
    };
}
