import {
    type RecursiveRecord
} from "../../types";

const mergeCurrent = (defaultJSON: RecursiveRecord, projectJSON: RecursiveRecord) => {
    const projectKeys: Array<keyof typeof projectJSON> = Object.keys(projectJSON);

    const newJSON = JSON.parse(JSON.stringify(defaultJSON));

    projectKeys.forEach((pKey) => {
        if(typeof projectJSON[pKey] === "string") {
            newJSON[pKey] = projectJSON[pKey];
        } else {
            if(typeof defaultJSON[pKey] !== "string") {
                if(defaultJSON[pKey]) {
                    newJSON[pKey] = mergeCurrent(defaultJSON[pKey], projectJSON[pKey]!);
                } else {
                    newJSON[pKey] = projectJSON[pKey];
                }
            } else {
                throw new Error("The project theme scheme is not valid.");
            }
        }
    });

    return newJSON;
};

export const mergeTheme = (
    defaultTheme: NCoreUIKit.ThemeTokens,
    projectTheme: NCoreUIKit.ThemeTokens
): NCoreUIKit.ThemeTokens => {
    return {
        content: mergeCurrent(defaultTheme.content as unknown as RecursiveRecord, projectTheme.content as unknown as RecursiveRecord),
        system: mergeCurrent(defaultTheme.system as unknown as RecursiveRecord, projectTheme.system as unknown as RecursiveRecord)
    };
};

export const mergePalettes = (
    defaultPalettes: NCoreUIKit.ThemePalettes,
    projectPalettes: NCoreUIKit.ThemePalettes,
    activePalette: NCoreUIKit.PaletteKey,
    activeTheme: NCoreUIKit.ThemeKey
): NCoreUIKit.ThemeTokens => {
    const defaultPalette = defaultPalettes.find(p => p.name === activePalette);

    if(!defaultPalette) {
        throw new Error("Palette not found!.");
    }

    const projectPalette = projectPalettes.find(p => p.name === activePalette);

    if(projectPalette) {
        const defaultThemeKey = Object.keys(defaultPalette.themes).find(t => t === activeTheme) as keyof typeof defaultPalette.themes;

        if(!defaultThemeKey) {
            throw new Error("Theme not found!.");
        }

        const defaultTheme = defaultPalette.themes[defaultThemeKey as keyof typeof defaultPalette.themes] as unknown as NCoreUIKit.ThemeTokens;

        const projectThemeKey = Object.keys(projectPalette.themes).find(t => t === activeTheme) as keyof typeof projectPalette.themes;

        if(projectThemeKey) {
            const projectTheme = projectPalette.themes[projectThemeKey] as unknown as NCoreUIKit.ThemeTokens;

            return mergeTheme(defaultTheme, projectTheme);
        }

        return defaultTheme;
    }

    const activeT = defaultPalette.themes[activeTheme as keyof typeof defaultPalette.themes] as unknown as NCoreUIKit.ThemeTokens;

    return activeT;
};
