import type { BrandingFontOption } from '@/types/branding';

const PREVIEW_FONTS_LINK_ID = 'branding-font-preview';
const INK = '#11224B';

/**
 * Loads every curated font at weight 400 (available for all of them) so the
 * font picker and live preview can show unsaved choices.
 */
export function loadPreviewFonts(fonts: BrandingFontOption[]): void {
    const families = fonts
        .map((font) => `family=${font.family.replaceAll(' ', '+')}:wght@400`)
        .join('&');

    let link = document.getElementById(
        PREVIEW_FONTS_LINK_ID,
    ) as HTMLLinkElement | null;

    if (!link) {
        link = document.createElement('link');
        link.id = PREVIEW_FONTS_LINK_ID;
        link.rel = 'stylesheet';
        document.head.appendChild(link);
    }

    link.href = `https://fonts.googleapis.com/css2?${families}&display=swap`;
}

/**
 * Picks white or the dark ink color, whichever reads better on the given background.
 * Mirrors BrandPalette::readableForeground on the server.
 */
export function readableForeground(hex: string): string {
    return contrastRatio(hex, '#FFFFFF') >= contrastRatio(hex, INK)
        ? '#FFFFFF'
        : INK;
}

function contrastRatio(first: string, second: string): number {
    const [lighter, darker] = [
        relativeLuminance(first),
        relativeLuminance(second),
    ].sort((a, b) => b - a);

    return (lighter + 0.05) / (darker + 0.05);
}

function relativeLuminance(hex: string): number {
    const [red, green, blue] = [1, 3, 5].map((offset) => {
        const value = parseInt(hex.slice(offset, offset + 2), 16) / 255;

        return value <= 0.03928
            ? value / 12.92
            : ((value + 0.055) / 1.055) ** 2.4;
    });

    return 0.2126 * red + 0.7152 * green + 0.0722 * blue;
}
