"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const utils_1 = require("../../utils");
const react_1 = tslib_1.__importDefault(require("react"));
const __1 = require("..");
const deepmerge_1 = tslib_1.__importDefault(require("deepmerge"));
const lodash_isnil_1 = tslib_1.__importDefault(require("lodash.isnil"));
/**
 * Merges component styles from different sources and passes on the the component as 'styles' prop.
 *
 * Following sources are considered as style sources. (In order of least important first):
 *
 * 1. defaultStyles: A component may provide default styles as a "defaultStyles" static
 * property of component. This is similar to defaultProps in react.
 * 2. stylesParam: 3rd property of this function. Note: Component Registry passes 'styles' prop from it's registry item.
 * 3. Themes: From theme.components[componentName] property of current theme.
 * 4. styles prop: The styles prop passed on to the component during usage.
 *
 * FIXME: Fix return typing of this function
 *
 * @param name
 * @param Component
 * @param stylesParam
 */
exports.applyStyles = (name, Component, stylesParam) => {
    return class ThemedComponent extends react_1.default.PureComponent {
        render() {
            const _a = this.props, { styles: stylesProp } = _a, rest = tslib_1.__rest(_a, ["styles"]);
            return (react_1.default.createElement(__1.ThemeContext.Consumer, { children: (args) => {
                    if (!args) {
                        // We return null here because the component may depend on the styles prop,
                        // and may crash without it.
                        return null;
                    }
                    const { theme } = args;
                    const defaultStyles = Component.defaultStyles;
                    const themedStyles = theme.components[name];
                    const stylesArr = [
                        defaultStyles,
                        stylesParam,
                        themedStyles,
                        stylesProp,
                    ]
                        .filter(a => !lodash_isnil_1.default(a))
                        .map(a => a && utils_1.resolveThunk(a, theme));
                    const styles = deepmerge_1.default.all(stylesArr);
                    const props = stylesArr.length > 0 ? Object.assign({}, rest, { styles }) : rest;
                    return react_1.default.createElement(Component, props);
                } }));
        }
    };
};
