import cssVars from 'css-vars-ponyfill';
import * as enquire from 'enquire.js';
import { ReplaySubject } from 'rxjs';

class Theme {
    constructor(theme) {
        this.id = theme.id;
        this.name = theme.name;
        this.cnName = theme.cnName || this.name;
        this.data = theme.data;
        this.extends = theme.extends || null;
        this.isDark = theme.isDark || undefined;
        this.isPreview = theme.isPreview || false;
        this.isExtendable = theme.isExtendable || true;
    }
}

const THEME_KEY = {
    userLastPreferTheme: 'user-custom-theme',
    userLastPreferThemeData: 'user-custom-theme-data',
    currentTheme: 'devuiCurrentTheme',
    themeCollection: 'devuiThemes',
    styleElementId: 'devuiThemeVariables',
    transitionStyleElementId: 'devuiThemeColorTransition',
    uiThemeAttributeName: 'ui-theme',
    themeService: 'devuiThemeService' // 全局window下的theme service实例
};

const devuiLightTheme = new Theme({
    id: 'devui-light-theme',
    name: 'Light Mode',
    cnName: '浅色主题',
    data: {
        'devui-global-bg': '#f3f6f8',
        'devui-global-bg-normal': '#ffffff',
        'devui-base-bg': '#ffffff',
        'devui-base-bg-dark': '#333854',
        'devui-brand': '#5e7ce0',
        'devui-brand-foil': '#859bff',
        'devui-brand-hover': '#7693f5',
        'devui-brand-active': '#526ecc',
        'devui-brand-active-focus': '#344899',
        'devui-contrast': '#c7000b',
        'devui-text': '#252b3a',
        'devui-text-weak': '#575d6c',
        'devui-aide-text': '#8a8e99',
        'devui-aide-text-hover': '#252b3a',
        'devui-aide-text-stress': '#575d6c',
        'devui-placeholder': '#8a8e99',
        'devui-light-text': '#ffffff',
        'devui-dark-text': '#252b3a',
        'devui-link': '#526ecc',
        'devui-link-active': '#344899',
        'devui-link-light': '#96adfa',
        'devui-link-light-active': '#beccfa',
        'devui-line': '#adb0b8',
        'devui-dividing-line': '#dfe1e6',
        'devui-block': '#ffffff',
        'devui-area': '#f8f8f8',
        'devui-danger': '#f66f6a',
        'devui-warning': '#fac20a',
        'devui-waiting': '#9faad7',
        'devui-success': '#50d4ab',
        'devui-info': '#5e7ce0',
        'devui-initial': '#e9edfa',
        'devui-unavailable': '#f5f5f6',
        'devui-shadow': 'rgba(37, 43, 58, 0.2)',
        'devui-light-shadow': 'rgba(37, 43, 58, 0.1)',
        'devui-connected-overlay-shadow': 'rgba(37, 43, 58, 0.12)',
        'devui-feedback-overlay-shadow': 'rgba(37, 43, 58, 0.16)',
        'devui-icon-text': '#252b3a',
        'devui-icon-bg': '#ffffff',
        'devui-icon-fill': '#252b3a',
        'devui-icon-fill-weak': '#babbc0',
        'devui-icon-fill-hover': '#5e7ce0',
        'devui-icon-fill-active': '#5e7ce0',
        'devui-icon-fill-active-hover': '#526ecc',
        'devui-shape-icon-fill': '#d7d8da',
        'devui-shape-icon-fill-active': '#babbc0',
        'devui-shape-icon-fill-hover': '#babbc0',
        'devui-shape-icon-fill-disabled': '#f5f5f5',
        'devui-form-control-line': '#adb0b8',
        'devui-form-control-bg': '#ffffff',
        'devui-form-control-line-hover': '#575d6c',
        'devui-form-control-line-active': '#5e7ce0',
        'devui-form-control-line-active-hover': '#344899',
        'devui-list-item-active-bg': '#5e7ce0',
        'devui-list-item-active-text': '#ffffff',
        'devui-list-item-active-hover-bg': '#526ecc',
        'devui-list-item-hover-bg': '#f2f5fc',
        'devui-list-item-hover-text': '#526ecc',
        'devui-list-item-selected-bg': '#e9edfa',
        'devui-list-item-strip-bg': '#f2f5fc',
        'devui-disabled-bg': '#f5f5f6',
        'devui-disabled-line': '#dfe1e6',
        'devui-disabled-text': '#adb0b8',
        'devui-primary-disabled': '#beccfa',
        'devui-icon-fill-active-disabled': '#beccfa',
        'devui-label-bg': '#eef0f5',
        'devui-connected-overlay-bg': '#ffffff',
        'devui-connected-overlay-line': '#526ecc',
        'devui-fullscreen-overlay-bg': '#ffffff',
        'devui-feedback-overlay-bg': '#464d6e',
        'devui-feedback-overlay-text': '#dfe1e6',
        'devui-embed-search-bg': '#f2f5fc',
        'devui-embed-search-bg-hover': '#eef0f5',
        'devui-float-block-shadow': 'rgba(94, 124, 224, 0.3)',
        'devui-highlight-overlay': 'rgba(255, 255, 255, 0.8)',
        'devui-range-item-hover-bg': '#e9edfa',
        'devui-primary': '#5e7ce0',
        'devui-primary-hover': '#7693f5',
        'devui-primary-active': '#344899',
        'devui-contrast-hover': '#d64a52',
        'devui-contrast-active': '#b12220',
        'devui-danger-line': '#f66f6a',
        'devui-danger-bg': '#ffeeed',
        'devui-warning-line': '#fa9841',
        'devui-warning-bg': '#fff3e8',
        'devui-info-line': '#5e7ce0',
        'devui-info-bg': '#f2f5fc',
        'devui-success-line': '#50d4ab',
        'devui-success-bg': '#edfff9',
        'devui-primary-line': '#5e7ce0',
        'devui-primary-bg': '#f2f5fc',
        'devui-default-line': '#5e7ce0',
        'devui-default-bg': '#f3f6f8',
        'devui-shadow-length-base': '0 1px 4px 0',
        'devui-shadow-length-slide-left': '-2px 0 8px 0',
        'devui-shadow-length-slide-right': '2px 0 8px 0',
        'devui-shadow-length-connected-overlay': '0 4px 8px 0',
        'devui-shadow-length-hover': '0 8px 16px 0',
        'devui-shadow-length-feedback-overlay': '0 8px 16px 0',
        'devui-shadow-length-fullscreen-overlay': '0 12px 24px 0',
        'devui-border-radius': '2px',
        'devui-border-radius-feedback': '4px',
        'devui-border-radius-card': '6px',
        'devui-border-radius-full': '100px',
        'devui-font-size': '12px',
        'devui-font-size-card-title': '14px',
        'devui-font-size-page-title': '16px',
        'devui-font-size-modal-title': '18px',
        'devui-font-size-price': '20px',
        'devui-font-size-data-overview': '24px',
        'devui-font-size-icon': '16px',
        'devui-font-size-sm': '12px',
        'devui-font-size-md': '12px',
        'devui-font-size-lg': '14px',
        'devui-font-title-weight': 'bold',
        'devui-font-content-weight': 'normal',
        'devui-line-height-base': '1.5',
        'devui-animation-ease-in-smooth': 'cubic-bezier(0.645, 0.045, 0.355, 1)',
        'devui-animation-duration-slow': '300ms',
        'devui-animation-duration-base': '200ms',
        'devui-animation-duration-fast': '100ms',
        'devui-animation-ease-in': 'cubic-bezier(0.5, 0, 0.84, 0.25)',
        'devui-animation-ease-out': 'cubic-bezier(0.16, 0.75, 0.5, 1)',
        'devui-animation-ease-in-out': 'cubic-bezier(0.5, 0.05, 0.5, 0.95)',
        'devui-animation-ease-in-out-smooth': 'cubic-bezier(0.645, 0.045, 0.355, 1)',
        'devui-animation-linear': 'cubic-bezier(0, 0, 1, 1)',
        'devui-z-index-full-page-overlay': '1080',
        'devui-z-index-pop-up': '1060',
        'devui-z-index-dropdown': '1052',
        'devui-z-index-modal': '1050',
        'devui-z-index-drawer': '1040',
        'devui-z-index-framework': '1000',
        'devui-icon-active-color': '#ffffff'
    },
    isDark: false,
});
const devuiGreenTheme = new Theme({
    id: 'avenueui-green-theme',
    name: 'Green - Light Mode',
    cnName: '绿色主题',
    data: Object.assign(Object.assign({}, devuiLightTheme.data), { 'devui-global-bg': '#f3f8f7', 'devui-brand': '#3DCCA6', 'devui-brand-foil': '#7fdac1', 'devui-brand-hover': '#6DDEBB', 'devui-brand-active': '#07c693', 'devui-brand-active-focus': '#369676', 'devui-link': '#07c693', 'devui-link-active': '#07c693', 'devui-link-light': '#96fac8', 'devui-link-light-active': '#befade', 'devui-info': '#079CCD', 'devui-initial': '#CCCCCC', 'devui-icon-fill-active': '#3DCCA6', 'devui-icon-fill-active-hover': '#07c693', 'devui-form-control-line-active': '#3DCCA6', 'devui-form-control-line-active-hover': '#2EB28A', 'devui-list-item-active-bg': '#3DCCA6', 'devui-list-item-active-hover-bg': '#07c693', 'devui-list-item-hover-bg': '#f3fef9', 'devui-list-item-hover-text': '#07c693', 'devui-list-item-selected-bg': '#f3fef9', 'devui-list-item-strip-bg': '#f3fef9', 'devui-connected-overlay-line': '#07c693', 'devui-embed-search-bg': '#f3fef9', 'devui-float-block-shadow': 'rgba(94, 224, 181, 0.3)', 'devui-primary': '#3DCCA6', 'devui-primary-hover': '#6DDEBB', 'devui-primary-active': '#369676', 'devui-info-line': '#0486b1', 'devui-info-bg': '#e3f0f5', 'devui-success-line': '#50d492', 'devui-success-bg': '#edfff9', 'devui-primary-line': '#3DCCA6', 'devui-primary-bg': '#f3fef9', 'devui-default-line': '#3DCCA6', 'devui-default-bg': '#f3f8f7', 'devui-primary-disabled': '#c5f0e5', 'devui-icon-fill-active-disabled': '#c5f0e5', 'devui-range-item-hover-bg': '#d8f9ea' }),
    extends: 'devui-light-theme',
    isDark: false,
});
const devuiDarkTheme = new Theme({
    id: 'devui-dark-theme',
    name: 'Dark Mode',
    cnName: '深色主题',
    data: {
        'devui-global-bg': '#202124',
        'devui-global-bg-normal': '#202124',
        'devui-base-bg': '#2E2F31',
        'devui-base-bg-dark': '#2e2f31',
        'devui-brand': '#5e7ce0',
        'devui-brand-foil': '#313a61',
        'devui-brand-hover': '#425288',
        'devui-brand-active': '#526ecc',
        'devui-brand-active-focus': '#344899',
        'devui-contrast': '#C7000B',
        'devui-text': '#E8E8E8',
        'devui-text-weak': '#A0A0A0',
        'devui-aide-text': '#909090',
        'devui-aide-text-hover': '#73788a',
        'devui-aide-text-stress': '#A0A0A0',
        'devui-placeholder': '#8A8A8A',
        'devui-light-text': '#ffffff',
        'devui-dark-text': '#252b3a',
        'devui-link': '#526ECC',
        'devui-link-active': '#344899',
        'devui-link-light': '#96adfa',
        'devui-link-light-active': '#beccfa',
        'devui-line': '#505153',
        'devui-dividing-line': '#3D3E40',
        'devui-block': '#606061',
        'devui-area': '#34363A',
        'devui-danger': '#f66f6a',
        'devui-warning': '#fac20a',
        'devui-waiting': '#5e6580',
        'devui-success': '#50d4ab',
        'devui-info': '#5e7ce0',
        'devui-initial': '#64676e',
        'devui-unavailable': '#5b5b5c',
        'devui-shadow': 'rgba(0, 0, 0, 0.72)',
        'devui-light-shadow': 'rgba(0, 0, 0, 0.3)',
        'devui-connected-overlay-shadow': 'rgba(0, 0, 0, 0.42)',
        'devui-feedback-overlay-shadow': 'rgba(0, 0, 0, 0.54)',
        // 图标
        'devui-icon-text': '#E8E8E8',
        'devui-icon-bg': '#2E2F31',
        'devui-icon-fill': '#909090',
        'devui-icon-fill-hover': '#5e7ce0',
        'devui-icon-fill-active': '#5e7ce0',
        'devui-icon-fill-active-hover': '#526ecc',
        'devui-shape-icon-fill': '#5b5d66',
        'devui-shape-icon-fill-active': '#868a99',
        // 表单
        'devui-form-control-line': '#505153',
        'devui-form-control-bg': '#2E2F31',
        'devui-form-control-line-hover': '#909090',
        'devui-form-control-line-active': '#5e7ce0',
        'devui-form-control-line-active-hover': '#344899',
        'devui-list-item-active-bg': '#5e7ce0',
        'devui-list-item-active-text': '#ffffff',
        'devui-list-item-active-hover-bg': '#526ecc',
        'devui-list-item-hover-bg': '#383838',
        'devui-list-item-hover-text': '#526ecc',
        'devui-list-item-selected-bg': '#454545',
        'devui-list-item-strip-bg': '#383838',
        'devui-table-expand-area-bg': '#393a3e',
        // 禁用
        'devui-disabled-bg': '#3D3E44',
        'devui-disabled-line': '#505153',
        'devui-disabled-text': '#7D7D7D',
        'devui-primary-disabled': '#2B3458',
        'devui-icon-fill-active-disabled': '#2B3458',
        // 特殊背景色
        'devui-label-bg': '#46443F',
        'devui-connected-overlay-bg': '#2F2F2F',
        'devui-connected-overlay-line': '#526ecc',
        'devui-fullscreen-overlay-bg': '#2E2F31',
        'devui-feedback-overlay-bg': '#4C4C4C',
        'devui-feedback-overlay-text': '#DFE1E6',
        'devui-embed-search-bg': '#383838',
        'devui-embed-search-bg-hover': '#3D3E40',
        'devui-float-block-shadow': 'rgba(94, 124, 224, 0.3)',
        'devui-highlight-overlay': 'rgba(255, 255, 255, 0.1)',
        'devui-range-item-hover-bg': '#454545',
        // 按钮
        'devui-primary': '#5e7ce0',
        'devui-primary-hover': '#425288',
        'devui-primary-active': '#344899',
        'devui-contrast-hover': '#D64A52',
        'devui-contrast-active': '#B12220',
        // 状态
        'devui-danger-line': '#985C5A',
        'devui-danger-bg': '#4B3A39',
        'devui-warning-line': '#8D6138',
        'devui-warning-bg': '#554434',
        'devui-info-line': '#546BB7',
        'devui-info-bg': '#383D4F',
        'devui-success-line': '#5D887D',
        'devui-success-bg': '#304642',
        'devui-primary-line': '#546BB7',
        'devui-primary-bg': '#383D4F',
        'devui-default-line': '#5e7ce0',
        'devui-default-bg': '#383838',
        'devui-icon-active-color': '#ffffff'
    },
    extends: 'devui-light-theme',
    isDark: true,
});
const avenueuiGreenDarkTheme = new Theme({
    id: 'avenueui-green-dark-theme',
    name: 'Green - Dark Mode',
    cnName: '绿色深色主题',
    data: Object.assign(Object.assign({}, devuiDarkTheme.data), { 'devui-brand': '#3DCCA6', 'devui-brand-foil': '#395e54', 'devui-brand-hover': '#4c9780', 'devui-brand-active': '#07c693', 'devui-brand-active-focus': '#297058', 'devui-link': '#07c693', 'devui-link-active': '#08a57b', 'devui-info': '#046788', 'devui-initial': '#64676e', 'devui-icon-fill-active': '#3DCCA6', 'devui-icon-fill-active-hover': '#07c693', 'devui-form-control-line-active': '#3DCCA6', 'devui-form-control-line-active-hover': '#297058', 'devui-list-item-active-bg': '#3DCCA6', 'devui-list-item-active-hover-bg': '#07c693', 'devui-list-item-hover-text': '#07c693', 'devui-connected-overlay-line': '#07c693', 'devui-embed-search-bg': '#3f4241', 'devui-float-block-shadow': 'rgba(94, 224, 181, 0.3)', 'devui-primary': '#3DCCA6', 'devui-primary-hover': '#6DDEBB', 'devui-primary-active': '#369676', 'devui-info-line': '#035e7c', 'devui-info-bg': '#383c3d', 'devui-primary-line': '#3DCCA6', 'devui-primary-bg': '#3f4241', 'devui-default-line': '#3DCCA6', 'devui-default-bg': '#383838', 'devui-primary-disabled': '#28544B', 'devui-icon-fill-active-disabled': '#28544B' }),
    extends: 'devui-dark-theme',
    isDark: true,
});

class PrefersColorSchemeMediaQuery {
    constructor() {
        this.prefersColorSchemeSubject = new ReplaySubject(1);
        this.prefersColorSchemeChange = this.prefersColorSchemeSubject.asObservable();
        this.handleColorSchemeChange = (value) => {
            this.prefersColorSchemeSubject.next(value);
        };
    }
    register() {
        PrefersColorSchemeMediaQuery.enquire
            .register.bind(enquire)(PrefersColorSchemeMediaQuery.Query.light, {
            match: () => {
                this.handleColorSchemeChange('light');
            }
        })
            .register(PrefersColorSchemeMediaQuery.Query.dark, {
            match: () => {
                this.handleColorSchemeChange('dark');
            }
        });
        this.prefersColorSchemeSubject.next(this.getInitValue());
    }
    unregister() {
        PrefersColorSchemeMediaQuery.enquire
            .unregister(PrefersColorSchemeMediaQuery.Query.light)
            .unregister(PrefersColorSchemeMediaQuery.Query.dark);
        this.prefersColorSchemeSubject.complete();
    }
    getInitValue() {
        return window.matchMedia(PrefersColorSchemeMediaQuery.Query.light).matches && 'light'
            || window.matchMedia(PrefersColorSchemeMediaQuery.Query.dark).matches && 'dark'
            || 'no-preference';
    }
}
PrefersColorSchemeMediaQuery.enquire = enquire; // prevent code optimization excluding enquire out
/* eslint-disable-next-line @typescript-eslint/no-namespace */
(function (PrefersColorSchemeMediaQuery) {
    let Query;
    (function (Query) {
        Query["light"] = "screen and (prefers-color-scheme: light)";
        Query["dark"] = "screen and (prefers-color-scheme: dark)";
        Query["noPreferences"] = "screen and (prefers-color-scheme: light)";
    })(Query = PrefersColorSchemeMediaQuery.Query || (PrefersColorSchemeMediaQuery.Query = {}));
})(PrefersColorSchemeMediaQuery || (PrefersColorSchemeMediaQuery = {}));

class EventBus {
    constructor() {
        this.eventBusCore = [];
    }
    areFuncEqual(a, b) {
        return a.toString() === b.toString();
    }
    isKeyValueObjInArr(arr, key, val) {
        const filteredArr = arr.filter(entry => {
            return entry[key] === val;
        });
        return filteredArr.length > 0;
    }
    removeFuncInFuncArr(arr, fn) {
        for (let z = 0; z < arr.length; z++) {
            if (this.areFuncEqual(arr[z], fn)) {
                arr.splice(z, 1);
            }
        }
        return arr;
    }
    getKeyValueObjInArr(arr, key, val) {
        const filteredArr = arr.filter(entry => {
            return entry[key] === val;
        });
        return filteredArr[0];
    }
    addEvent(eventName, eventFunc) {
        if (!this.isKeyValueObjInArr(this.eventBusCore, 'eventName', eventName)) {
            this.eventBusCore.push({ eventName: eventName, eventFuncArr: [eventFunc] });
        }
        else {
            this.eventBusCore = this.eventBusCore.map(event => {
                if (event['eventName'] === eventName) {
                    event.eventFuncArr.push(eventFunc);
                }
                return event;
            });
        }
    }
    add(eventName, callbacks) {
        if (!eventName) {
            return;
        }
        if (typeof callbacks === 'function') {
            for (let i = 1; i < arguments.length; i++) {
                this.addEvent(eventName, arguments[i]);
            }
        }
        if (typeof callbacks === 'object' && callbacks.forEach) {
            callbacks.forEach(fn => {
                this.addEvent(eventName, fn);
            });
        }
    }
    remove(eventName, callbacks) {
        if (!eventName) {
            return;
        }
        for (let i = 0; i < this.eventBusCore.length; i++) {
            if (this.eventBusCore[i].eventName === eventName) {
                if (arguments.length === 1) {
                    return this.eventBusCore.splice(i, 1);
                }
                const removedEvent = this.eventBusCore.splice(i, 1)[0];
                if (typeof callbacks === 'function') {
                    for (let k = 1; k < arguments.length; k++) {
                        removedEvent.eventFuncArr = this.removeFuncInFuncArr(removedEvent.eventFuncArr, arguments[k]);
                    }
                }
                if (typeof callbacks === 'object' && callbacks.length) {
                    for (let x = 0; x < callbacks.length; x++) {
                        removedEvent.eventFuncArr = this.removeFuncInFuncArr(removedEvent.eventFuncArr, callbacks[x]);
                    }
                }
                this.eventBusCore.push(removedEvent);
            }
        }
    }
    trigger(eventName, data) {
        const event = this.getKeyValueObjInArr(this.eventBusCore, 'eventName', eventName);
        if (event) {
            (event.eventFuncArr || []).forEach(fn => {
                fn.apply(this, data);
            });
        }
    }
}

class ContextService {
    getDataFromNameSpace(nameSpace) {
        return window[nameSpace];
    }
    setDataFromNameSpace(nameSpace, value) {
        window[nameSpace] = value;
    }
}

class StorageService {
    tryGetLocalStorage(key) {
        return window.localStorage.getItem(key);
    }
    trySetLocalStorage(key, value) {
        window.localStorage.setItem(key, value);
    }
}

/**
 * 负责CSS变量主题的装卸，主题元数据转换成主题数据
 */
class ThemeService {
    constructor(eventBus, storage, context) {
        this.eventBus = eventBus === undefined ? new EventBus() : eventBus;
        this.storage = storage === undefined ? new StorageService() : storage;
        this.context = context === undefined ? new ContextService() : context;
    }
    set appendClasses(classes) {
        if (this._appendedClasses) {
            this.removeAppendedClass(this._appendedClasses);
        }
        if (classes) {
            this.addAppendClass(classes);
        }
        this._appendedClasses = classes;
    }
    get appendClasses() {
        return this._appendedClasses;
    }
    initializeTheme(specificThemeId, allowDynamicTheme) {
        const themeId = specificThemeId
            || this.storage.tryGetLocalStorage(THEME_KEY.userLastPreferTheme)
            || this.context.getDataFromNameSpace(THEME_KEY.currentTheme);
        let theme;
        if (themeId) {
            const themes = this.context.getDataFromNameSpace(THEME_KEY.themeCollection);
            if (themes && Object.keys(themes).length > 0) {
                theme = themes[themeId];
            }
        }
        this.currentTheme = theme || {
            id: 'empty-theme',
            name: '',
            data: {}
        };
        this.createColorTransition();
        if (!theme && allowDynamicTheme) {
            return;
        }
        this.applyTheme(this.currentTheme);
    }
    formatCSSVariables(themeData) {
        return Object.keys(themeData).map(cssVar => ('--' + cssVar + ':' + themeData[cssVar])).join(';');
    }
    applyTheme(theme) {
        this.addColorTransition();
        this.currentTheme = theme;
        if (!this.contentElement) {
            const styleElement = document.getElementById(THEME_KEY.styleElementId);
            if (styleElement) {
                this.contentElement = styleElement;
            }
            else {
                this.contentElement = document.createElement('style');
                this.contentElement.id = THEME_KEY.styleElementId;
                document.head.appendChild(this.contentElement);
            }
        }
        this.contentElement.innerText = ':root { ' + this.formatCSSVariables(theme.data) + ' }';
        this.contentElement.setAttribute(THEME_KEY.uiThemeAttributeName, this.currentTheme.id);
        document.body.setAttribute(THEME_KEY.uiThemeAttributeName, this.currentTheme.id);
        // 用于挂载额外变量和类名
        this.applyExtraData();
        this.saveCustomTheme(this.currentTheme);
        // 通知外部主题变更
        this.notify(theme, 'themeChanged');
        setTimeout(() => { this.removeColorTransition(); }, 500);
    }
    saveCustomTheme(customTheme) {
        this.storage.trySetLocalStorage(THEME_KEY.userLastPreferTheme, customTheme.id);
        this.storage.trySetLocalStorage(THEME_KEY.userLastPreferThemeData, JSON.stringify(customTheme.data));
        this.context.setDataFromNameSpace(THEME_KEY.currentTheme, customTheme.id);
    }
    notify(theme, eventType) {
        if (!this.eventBus) {
            return;
        }
        this.eventBus.trigger(eventType, theme);
    }
    setEventBus(eb) {
        this.eventBus = eb;
    }
    addAppendClass(classNames) {
        document.body.classList.add(...classNames);
    }
    removeAppendedClass(classNames) {
        document.body.classList.remove(...classNames);
    }
    setExtraData(data, apply = false) {
        this.extraData = data;
        if (apply) {
            this.applyExtraData();
        }
    }
    applyExtraData() {
        const theme = this.currentTheme;
        if (this.extraData && this.extraData[theme.id] && this.extraData[theme.id].cssVariables) {
            this.contentElement.innerText
                = ':root { ' + this.formatCSSVariables(theme.data) + ' }'
                    + ':root { ' + this.formatCSSVariables(this.extraData[theme.id].cssVariables) + ' }';
        }
        if (this.extraData && this.extraData[theme.id] && this.extraData[theme.id].appendClasses) {
            this.appendClasses = this.extraData[theme.id].appendClasses;
        }
        else {
            this.appendClasses = undefined;
        }
    }
    unloadTheme() {
        if (this.contentElement && document.contains(this.contentElement)) {
            this.contentElement.parentElement.removeChild(this.contentElement);
        }
        if (this.appendClasses) {
            this.appendClasses = undefined;
        }
    }
    registerMediaQuery() {
        if (!this.mediaQuery) {
            this.mediaQuery = new PrefersColorSchemeMediaQuery();
        }
        this.mediaQuery.register();
    }
    unregisterMediaQuery() {
        if (!this.mediaQuery) {
            return;
        }
        this.mediaQuery.unregister();
        this.mediaQuery = undefined;
    }
    createColorTransition() {
        this.colorTransitionElement = document.createElement('style');
        this.colorTransitionElement.id = THEME_KEY.transitionStyleElementId;
        this.colorTransitionElement.innerText = `
      * { transition: background .3s ease-out, background-color .3s ease-out,
                    border .3s ease-out, border-color .3s ease-out,
                    box-shadow .3s ease-out, box-shadow-color .3s ease-out}
    `;
    }
    addColorTransition() {
        document.head.appendChild(this.colorTransitionElement);
    }
    removeColorTransition() {
        if (!this.colorTransitionElement.parentElement) {
            return;
        }
        this.colorTransitionElement.parentElement.removeChild(this.colorTransitionElement);
    }
}

/**
 * usage
 * main.ts
 ```ts
 import { ThemeServiceInit } from 'ng-devui/theme';
 ThemeServiceInit();
 ```
 *
*/
function ThemeServiceInit(themes, defaultThemeName, extraData, ieSupport = false, // TODO：css-var-ponyflll 仍有一些问题待定位
allowDynamicTheme = false) {
    if (typeof window === 'undefined' || typeof document === 'undefined') {
        return null;
    }
    window[THEME_KEY.themeCollection] = themes || {
        'devui-light-theme': devuiLightTheme,
        'devui-dark-theme': devuiDarkTheme,
    };
    window[THEME_KEY.currentTheme] = defaultThemeName || 'devui-light-theme';
    const eventBus = window['globalEventBus'] || new EventBus(); // window.globalEventBus 为 框架的事件总线
    const themeService = new ThemeService(eventBus);
    window[THEME_KEY.themeService] = themeService;
    themeService.setExtraData(extraData || {
        'devui-dark-theme': {
            appendClasses: ['dark-mode']
        }
    });
    const currentTheme = (window === null || window === void 0 ? void 0 : window.localStorage.getItem(THEME_KEY.userLastPreferTheme)) || defaultThemeName;
    themeService.initializeTheme(currentTheme, allowDynamicTheme);
    if (ieSupport) {
        ieSupportCssVar();
    }
    return themeService;
}
function ThemeServiceFollowSystemOn(themeConfig) {
    if (typeof window === 'undefined' || typeof document === 'undefined') {
        return null;
    }
    const themeService = window[THEME_KEY.themeService];
    themeService.registerMediaQuery();
    return themeService.mediaQuery.prefersColorSchemeChange.subscribe(value => {
        if (value === 'dark') {
            themeService.applyTheme(window[THEME_KEY.themeCollection][themeConfig && themeConfig.darkThemeName || 'devui-dark-theme']);
        }
        else {
            themeService.applyTheme(window[THEME_KEY.themeCollection][themeConfig && themeConfig.lightThemeName || 'devui-light-theme']);
        }
    });
}
function ThemeServiceFollowSystemOff(sub) {
    if (typeof window === 'undefined' || typeof document === 'undefined') {
        return;
    }
    if (sub) {
        sub.unsubscribe();
    }
    const themeService = window[THEME_KEY.themeService];
    themeService.unregisterMediaQuery();
}
function ieSupportCssVar() {
    if (typeof window === 'undefined' || typeof document === 'undefined') {
        return;
    }
    const isNativeSupport = window['CSS'] && CSS.supports && CSS.supports('(--a: 0)') || false;
    if (isNativeSupport) {
        return;
    }
    cssVars({ watch: true, silent: true });
    const observer = new MutationObserver(function (mutations) {
        mutations.forEach(function (mutation) {
            cssVars({ watch: false, silent: true });
            cssVars({ watch: true, silent: true });
        });
    });
    const config = { attributes: true, attributeFilter: [THEME_KEY.uiThemeAttributeName] };
    observer.observe(document.querySelector(`#${THEME_KEY.styleElementId}`), config);
}
// TODO: management should handle add / remove theme from theme collection.
// TODO: move global variables（window.xxxx） to single namespace

/**
 * Generated bundle index. Do not edit.
 */

export { ContextService, EventBus, StorageService, Theme, ThemeService, ThemeServiceFollowSystemOff, ThemeServiceFollowSystemOn, ThemeServiceInit, avenueuiGreenDarkTheme, devuiDarkTheme, devuiGreenTheme, devuiLightTheme, ieSupportCssVar };
//# sourceMappingURL=ng-devui-theme.mjs.map
