import { themesType, themeType, UIThemeConfig } from './theme.types' // Must be relative as doing publish
import __themes from './themes.json' // Must be relative as doing publish

const _default = __themes.redGreen as themeType

const themes: themesType = __themes

const globalVariables = {
    'input-font-size': '0.875rem',
    'input-font-weight': '500',
    'select-option-height': '2rem',
    'base-border-radius': '0.25rem'
}

export function overrideElementTheme (theme: {[key: string]: string}) {
    return {
        ...theme,
        'el-color-primary': theme['el-color-primary'] ?? theme.primary,
        'el-color-success': theme['el-color-success'] ?? theme.success,
        'el-color-warning': theme['el-color-warning'] ?? theme.warning,
        'el-color-danger': theme['el-color-danger'] ?? theme.error,
        'el-color-error': theme['el-color-error'] ?? theme.error,
        'el-color-info': theme['el-color-info'] ?? theme['secondary'],
        'el-fill-color': theme['el-fill-color'] ?? theme['field-bg'],
        'el-text-color-primary': theme['el-text-color-primary'] ?? theme['default-text'],
        'el-text-color-regular': theme['el-text-color-regular'] ?? theme['default-text'],
        'el-text-color-placeholder': theme['el-text-color-placeholder'] ?? theme.placeholders,
        'el-disabled-text-color': theme['el-disabled-text-color'] ?? theme['inactive-text'],
        'el-text-color-disabled': theme['el-text-color-disabled'] ?? theme['inactive-text'],
        transparent: 'transparent',
        white: '#FFFFFF',
        black: '#000000',
        current: 'currentColor'
    }
}

export function appendGlobalCssVariables (cssData: { [key: string]: string }, appendTo: HTMLElement) {
    Object.entries(cssData).forEach(([ variableName, variableValue ]) => {
        appendTo.style.setProperty(`--${variableName}`, variableValue)
    })
}

export async function getThemeConfigData (themeConfig?: UIThemeConfig) {
    let currentTheme = _default

    if (themeConfig) {

        if (themeConfig.type === 'local') {
            if (themes[themeConfig.themeName]) {
                currentTheme = themes[themeConfig.themeName]
            } else {
                console.warn(`[VoicenterUI-plus] No such theme: ${themeConfig.themeName}`)
            }
        }

        if (themeConfig.type === 'remote') {
            let body = JSON.stringify(
                {
                    SectionList: [
                        themeConfig.brandingSectionName
                    ],
                    Domain: window.location.hostname
                }
            )

            if (themeConfig.payloadData) {
                body = JSON.stringify(themeConfig.payloadData)
            }

            const apiStyling = await fetch(themeConfig.apiUrl, {
                method: 'POST',
                cache: 'no-cache',
                headers: {
                    'Content-Type': 'application/json'
                },
                referrerPolicy: 'no-referrer',
                body
            })
                .then(res => res.json())
                .then(res => res.Data)
                .then(res => {
                    return Object.fromEntries(Object.entries(res).map(([ key, value ]) => {
                        return [
                            key.replace(`${themeConfig.brandingSectionName}.`, ''),
                            String(value)
                        ]
                    }))
                })
                .catch(e => console.error(e))

            if (apiStyling) {
                currentTheme = apiStyling
            }
        }

        if (themeConfig.type === 'customJson') {
            currentTheme = themeConfig.config ?? {}
        }
    }

    return currentTheme
}

export default async function (themeConfig?: UIThemeConfig, appendTo: HTMLElement = document.documentElement) {

    if (themeConfig?.type === 'none') {
        return themeConfig?.onSetupCallback ? themeConfig?.onSetupCallback({}) : {}
    }

    const currentTheme = await getThemeConfigData(themeConfig)

    appendGlobalCssVariables(
        {
            ...overrideElementTheme(currentTheme),
            ...globalVariables
        },
        appendTo
    )

    if (themeConfig?.onSetupCallback) {
        themeConfig.onSetupCallback(currentTheme)
    }
}
