const styleMap: Map<string, string> = new Map();
let sheet: CSSStyleSheet | null = null;

function getSheet(): CSSStyleSheet {
    if (!sheet) {
        sheet = new CSSStyleSheet();
        document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
    }
    return sheet;
}

function sanitizeForClassName(value: string): string {
    return value.replace(/[^a-zA-Z0-9]/g, '');
}

export function dynamicBg(color: string): string {
    const key: string = `bg-${color}`;
    if (styleMap.has(key)) return styleMap.get(key)!;
    
    const className: string = `dyn-bg-${sanitizeForClassName(color)}`;
    getSheet().insertRule(`.${className} { background-color: ${color}; }`, getSheet().cssRules.length);
    styleMap.set(key, className);
    return className;
}

export function dynamicText(color: string): string {
    const key: string = `text-${color}`;
    if (styleMap.has(key)) return styleMap.get(key)!;
    
    const className: string = `dyn-text-${sanitizeForClassName(color)}`;
    getSheet().insertRule(`.${className} { color: ${color}; }`, getSheet().cssRules.length);
    styleMap.set(key, className);
    return className;
}

export function dynamicBorder(color: string, side: string = ''): string {
    const prop: string = side ? `border-${side}-color` : 'border-color';
    const key: string = `border-${side}-${color}`;
    if (styleMap.has(key)) return styleMap.get(key)!;
    
    const className: string = `dyn-border-${side ? side + '-' : ''}${sanitizeForClassName(color)}`;
    getSheet().insertRule(`.${className} { ${prop}: ${color}; }`, getSheet().cssRules.length);
    styleMap.set(key, className);
    return className;
}

export function dynamicBgWithOpacity(hexColor: string, opacityHex: string): string {
    const key: string = `bg-${hexColor}-${opacityHex}`;
    if (styleMap.has(key)) return styleMap.get(key)!;
    
    const className: string = `dyn-bg-${sanitizeForClassName(hexColor)}-${opacityHex}`;
    getSheet().insertRule(`.${className} { background-color: ${hexColor}${opacityHex}; }`, getSheet().cssRules.length);
    styleMap.set(key, className);
    return className;
}

export function dynamicBorderWithOpacity(hexColor: string, opacityHex: string): string {
    const key: string = `border-${hexColor}-${opacityHex}`;
    if (styleMap.has(key)) return styleMap.get(key)!;
    
    const className: string = `dyn-border-${sanitizeForClassName(hexColor)}-${opacityHex}`;
    getSheet().insertRule(`.${className} { border-color: ${hexColor}${opacityHex}; }`, getSheet().cssRules.length);
    styleMap.set(key, className);
    return className;
}

export function dynamicBorderLeft(color: string, width: string = '3px'): string {
    const key: string = `bl-${width}-${color}`;
    if (styleMap.has(key)) return styleMap.get(key)!;
    
    const className: string = `dyn-bl-${sanitizeForClassName(color)}`;
    getSheet().insertRule(`.${className} { border-left: ${width} solid ${color}; }`, getSheet().cssRules.length);
    styleMap.set(key, className);
    return className;
}
