const COLOR_PREFIXES = new Set([
    'bg',
    'text',
    'border',
    'from',
    'via',
    'to',
    'ring',
    'stroke',
    'fill',
    'outline',
    'placeholder',
    'caret',
    'accent',
    'decoration',
    'shadow'
]);
const COLOR_NAMES = new Set([
    'slate',
    'gray',
    'zinc',
    'neutral',
    'stone',
    'red',
    'orange',
    'amber',
    'yellow',
    'lime',
    'green',
    'emerald',
    'teal',
    'cyan',
    'sky',
    'blue',
    'indigo',
    'violet',
    'purple',
    'fuchsia',
    'pink',
    'rose',
    'white',
    'black',
    'transparent'
]);
const isObject = (value) => {
    return typeof value === 'object' && value !== null && !Array.isArray(value);
};
const hasColorName = (segment) => {
    const normalized = segment.replace(/[^a-z-]/g, '');
    return Array.from(COLOR_NAMES).some((name) => normalized.includes(`${name}-`) || normalized.endsWith(`-${name}`) || normalized.includes(`${name}`));
};
const isColorClass = (className) => {
    const segment = className.split(':').pop() ?? className;
    const [prefix, ...restParts] = segment.split('-');
    if (!COLOR_PREFIXES.has(prefix)) {
        return false;
    }
    const rest = restParts.join('-');
    if (!rest) {
        return false;
    }
    return hasColorName(rest);
};
const splitClassList = (value) => {
    const classes = value.split(/\s+/).filter(Boolean);
    const layout = [];
    const colors = [];
    for (const className of classes) {
        if (isColorClass(className)) {
            colors.push(className);
        }
        else {
            layout.push(className);
        }
    }
    return {
        layout: layout.join(' '),
        color: colors.join(' ')
    };
};
const mergeClassLists = (layout, color) => {
    return [layout, color].filter(Boolean).join(' ').trim();
};
const splitThemeInternal = (value) => {
    if (typeof value === 'string') {
        return splitClassList(value);
    }
    if (isObject(value)) {
        const layoutEntries = {};
        const colorEntries = {};
        for (const [key, child] of Object.entries(value)) {
            const { layout, color } = splitThemeInternal(child);
            layoutEntries[key] = layout;
            colorEntries[key] = color;
        }
        return { layout: layoutEntries, color: colorEntries };
    }
    return { layout: value, color: value };
};
const mergeThemeInternal = (layoutValue, colorValue) => {
    if (typeof layoutValue === 'string' && typeof colorValue === 'string') {
        return mergeClassLists(layoutValue, colorValue);
    }
    if (isObject(layoutValue) && isObject(colorValue)) {
        const keys = new Set([...Object.keys(layoutValue), ...Object.keys(colorValue)]);
        const result = {};
        for (const key of keys) {
            const merged = mergeThemeInternal(layoutValue[key], colorValue[key]);
            if (merged !== undefined) {
                result[key] = merged;
            }
        }
        return result;
    }
    if (colorValue !== undefined && colorValue !== null) {
        return colorValue;
    }
    return layoutValue;
};
const diffThemeInternal = (base, override) => {
    if (typeof base === 'string' && typeof override === 'string') {
        const trimmedBase = base.trim();
        const trimmedOverride = override.trim();
        if (trimmedBase === trimmedOverride || trimmedOverride.length === 0) {
            return undefined;
        }
        return trimmedOverride;
    }
    if (isObject(base) && isObject(override)) {
        const result = {};
        for (const key of Object.keys(override)) {
            const diff = diffThemeInternal(base[key], override[key]);
            if (diff !== undefined) {
                result[key] = diff;
            }
        }
        if (Object.keys(result).length === 0) {
            return undefined;
        }
        return result;
    }
    if (override === undefined) {
        return undefined;
    }
    return override;
};
const pruneEmpty = (value) => {
    if (typeof value === 'string') {
        return value;
    }
    if (isObject(value)) {
        const entries = Object.entries(value)
            .map(([key, child]) => [key, pruneEmpty(child)])
            .filter(([, child]) => {
            if (child === undefined) {
                return false;
            }
            if (typeof child === 'string') {
                return child.trim().length > 0;
            }
            if (isObject(child)) {
                return Object.keys(child).length > 0;
            }
            return true;
        });
        return Object.fromEntries(entries);
    }
    return value;
};
const mergeColorInternal = (base, override) => {
    if (override === undefined) {
        return base;
    }
    if (typeof override === 'string') {
        return override;
    }
    if (isObject(base) && isObject(override)) {
        const keys = new Set([...Object.keys(base), ...Object.keys(override)]);
        const result = {};
        for (const key of keys) {
            result[key] = mergeColorInternal(base[key], override[key]);
        }
        return result;
    }
    if (isObject(override)) {
        const result = {};
        for (const [key, value] of Object.entries(override)) {
            result[key] = mergeColorInternal(undefined, value);
        }
        return result;
    }
    return override ?? base;
};
export const splitThemeTokens = (theme) => {
    const { layout, color } = splitThemeInternal(theme);
    return {
        layoutTokens: layout,
        colorTokens: color
    };
};
export const mergeThemeTokens = (layoutTokens, colorTokens) => {
    return mergeThemeInternal(layoutTokens, colorTokens);
};
export const diffThemeTokens = (base, override) => {
    return pruneEmpty(diffThemeInternal(base, override));
};
export const mergeColorTokens = (baseColorTokens, overrideColorTokens) => {
    return mergeColorInternal(baseColorTokens, overrideColorTokens);
};
