import PubBase from './PubBase';
import PubListen from './PubListen';
import PubUpdate from './PubUpdate';
import PubCommon from './PubCommon';
import pipe from '../utils/pipe';
import ax from '../ax';
import classes from '../utils/classes';
import optAlert from '../options/optAlert';
import prefix from '../global/prefix';
class Alert extends pipe(PubListen, PubUpdate, PubCommon)(PubBase) {
    constructor(elem, options, inital = ax.config.inital) {
        super();
        this.options = {};
        this.ready({
            options,
            maps: optAlert,
            host: elem,
            component: true,
        });
        /**
        * @name Alert.targetEl
        * @description Target element.
        * @type getEl
        */
        /**
        * @name Alert.rawOpts
        * @description Raw Parameters of the instance from map.
        * @type object
        */
        /**
         * @name Alert.dftOpts
         * @description Default Parameters of the instance from merging.The reset method requires this variable.
         * @type object
         */
        /**
         * @name Alert.options
         * @description Parameters of the instance.
         * @type object
         */
        /**
         * @name Alert.destroyed
         * @description Destruction state.
         * @type boolean
         */
        /**
        * @name Alert.plans
        * @description Plans for listening.
        * @type object
        */
        /**
        * @name Alert.storKeys
        * @description The set of parameter fields to save.
        * @type array
        */
        /**
         * @name Alert.storTmp
         * @description Cache object.The "updateCache" method will update the variable.
         * @type object
         */
        /**
        * @name Alert.storObs
        * @description Cache listener(proxy) that listens for "storTmp" changes and automatically updates the local storage.
        * @type any
        */
        /**
        * @name Alert.timestamp
        * @description Instance creation time.
        * @type number
        */
        /**
        * @function Alert.save
        * @description Storing settings locally.
        * @param {fn_cb_options} [cb] - Callback execution after saving local storage.
        * @returns {any} Return the instance itself
        */
        /**
        * @function Alert.reset
        * @description Re-initialization of old parameters.
        * @param {fn_cb_none} [cb] - Call back after reset settings.
        * @returns {*} Return the instance itself
        */
        /**
        * @name Alert.contEl
        * @description The node that holds the content of the alert.
        * @type HTMLElement
        */
        this.contEl = null;
        /**
        * @name Alert.content
        * @description Textual content of the alert, possibly HTML.
        * @type string
        */
        this.content = '';
        /**
        * @name Alert.closeEl
        * @description Close the button node of the alert.
        * @type HTMLElement
        */
        this.closeEl = null;
        /**
        * @name Alert.iconEl
        * @description The indicator icon node for alert.
        * @type HTMLElement
        */
        this.iconEl = null;
        /**
        * @name Alert.bodyEl
        * @description The body node for alert.
        * @type HTMLElement
        */
        this.bodyEl = null;
        /**
        * @name Alert.captionEl
        * @description The title node for alert.
        * @type HTMLElement
        */
        this.captionEl = null;
        super.listen({ name: 'ready' });
        inital ? this.init() : null;
    }
    /**
    * @description Initialization instance.
    * @param {fn_cb_none} [cb] - Callback execution after initialization.
    * @returns {*} Return the instance itself.
    */
    init(cb) {
        super.listen({ name: 'start' });
        this.setEmpty();
        /**
        * @name Alert.shown
        * @description Display state of alert.
        * @type boolean
        */
        this.shown = this.options.asleep ? false : true;
        this.getContent();
        this.render();
        this.setAttrs();
        if (this.closeEl) {
            this.closeEl.onclick = async () => {
                this.options.b4Hide && await this.options.b4Hide.call(this);
                this.hide();
            };
        }
        super.listen({ name: 'init', cb });
        return this;
    }
    getContent() {
        if (this.options.content && typeof this.options.content === 'string') {
            this.content = super.getStrFromContent(this.options.content);
        }
        else {
            this.content = this.rawHtml ? this.rawHtml : this.targetEl.innerHTML;
        }
    }
    render() {
        if (this.content.includes('role="body"') && this.content.includes('role="content"')) {
            this.targetEl.innerHTML = this.content;
        }
        else {
            this.targetEl.innerHTML = `
            ${this.options.icon ? '<i class="' + this.options.icon + '" role="icon"></i>' : ''}
                        <div role="body">
                            ${this.options.caption ? '<div role="caption">' + this.options.caption + '</div>' : ''}
                            <div role="content">${this.content}</div>
                        </div>
                        ${this.options.closable ? '<i role="close" class="' + ax.pfx + 'icon-close"></i>' : ''}
            `;
        }
        this.closeEl = this.targetEl.querySelector('[role="close"]');
        this.iconEl = this.targetEl.querySelector('[role="icon"]');
        this.bodyEl = this.targetEl.querySelector('[role="body"]');
        this.captionEl = this.targetEl.querySelector('[role="caption"]');
        this.contEl = this.targetEl.querySelector('[role="content"]');
    }
    setAttrs() {
        this.targetEl.classList.add(`${prefix}alert`);
        classes.add(this.targetEl, this.options.classes);
        this.options.asleep ? (this.targetEl.style.display = 'none') : null;
        this.options.theme ? this.targetEl.setAttribute('theme', this.options.theme) : null;
        this.options.borderless ? this.targetEl.setAttribute('borderless', '') : null;
        this.options.notable ? this.targetEl.setAttribute('notable', '') : null;
        this.options.square ? this.targetEl.setAttribute('square', '') : null;
        this.options.plain ? this.targetEl.setAttribute('plain', '') : null;
    }
    setEmpty() {
        this.removeAttrs();
        this.targetEl.innerHTML = '';
    }
    removeAttrs() {
        this.targetEl.classList.remove(`${prefix}alert`);
        classes.remove(this.targetEl, this.options.classes);
        this.targetEl.removeAttribute('theme');
        this.targetEl.removeAttribute('borderless');
        this.targetEl.removeAttribute('square');
        this.targetEl.removeAttribute('plain');
        this.targetEl.removeAttribute('notable');
        this.targetEl.style = this.targetEl.style.cssText.replace('display: none;', '');
        this.options.display ? this.targetEl.style = this.targetEl.style.cssText.replace(`display: ${this.options.display};`, '') : null;
    }
    /**
    * @description Update content.
    * @param {string} html - The content to be updated.Can be filled with any text string, including html.
    * @param {fn_cb_html} [cb] - Call back after update content.
    * @returns {*} Return the instance itself
    */
    updateCont(html, cb) {
        if (this.destroyed) {
            return this;
        }
        this.contEl.innerHTML = html;
        super.updateCache({ content: html });
        super.listen({ name: 'updateCont', cb, params: [html] });
        return this;
    }
    /**
    * @description Show alert.
    * @param {fn_cb_none} [cb] - Call back after displaying the alert.
    * @returns {*} Return the instance itself
    */
    show(cb) {
        if (this.destroyed || this.shown || this.options.asleep) {
            return this;
        }
        if (this.options.display) {
            this.targetEl.style.display = this.options.display;
        }
        else {
            this.targetEl.style.cssText = this.targetEl.style.cssText.replace('display: none;', '');
        }
        this.shown = true;
        super.listen({ name: 'show', cb });
        return this;
    }
    /**
    * @description Hide alert.
    * @param {fn_cb_none} [cb] - Call back after hiding the alert.
    * @returns {*} Return the instance itself
    */
    hide(cb) {
        if (this.destroyed || !this.shown) {
            return this;
        }
        this.targetEl.style.display = 'none';
        this.shown = false;
        super.listen({ name: 'hide', cb });
        return this;
    }
    /**
    * @description Clear the contents of the alert.
    * @param {fn_cb_none} [cb] - Call back after clearing the contents of the alert.
    * @returns {*} Return the instance itself
    */
    clear(cb) {
        if (this.destroyed) {
            return this;
        }
        this.setEmpty();
        super.listen({ name: 'clear', cb });
        return this;
    }
    /**
     * @description Destroy instance and prohibit use.
     * @param {fn_cb_none} [cb] - Callback execution after destruction.
     * @returns {any} - Return the instance itself.
     */
    destroy(cb) {
        this.closeEl ? this.closeEl.onclick = null : null;
        this.destroyed = true;
        super.listen({ name: 'destroy', cb });
        return this;
    }
}
Alert.hostType = 'el';
export default Alert;
