import PubBase from './PubBase';
import PubListen from './PubListen';
import PubUpdate from './PubUpdate';
import PubCommon from './PubCommon';
import pipe from '../utils/pipe';
import optLazy from '../options/optLazy';
import icons from '../utils/icons';
import Spy from './Spy';
import getContent from '../utils/getContent';
import setContent from '../utils/setContent';
import extend from '../utils/extend';
class Lazy extends pipe(PubListen, PubUpdate, PubCommon)(PubBase) {
    constructor(elem, options, initial = true) {
        super();
        this.options = {};
        this.ready({
            options,
            maps: optLazy,
            host: elem,
        });
        this.nodeName = this.targetEl.nodeName;
        this.removeAttrFn = () => {
            this.targetEl.removeAttribute('lazy-src');
            super.listen({ name: 'shown', params: [this.targetEl] });
        };
        super.listen({ name: 'ready' });
        initial && this.init();
    }
    /**
     * @description Initialization instance.No parameters.
     * @param {fn_cb_init} [cb] - Call back after initialization.
     * @returns {*} Return the instance itself.
     */
    async init(cb) {
        super.listen({ name: 'launch' });
        this.options.b4Init && await this.options.b4Init.call(this);
        this.resType = this.options.type || (this.targetEl.hasAttribute('src') ? 'src' : 'async');
        if (this.resType === 'src') {
            this.targetEl.src = icons.image.blank;
            !this.targetEl.hasAttribute('lazy-src') && this.targetEl.setAttribute('lazy-src', '');
        }
        this.spyIns = new Spy(this.targetEl, extend({
            target: {
                root: this.options.root,
                repeat: false,
                onShown: async () => {
                    super.listen({ name: 'showing', params: [this.targetEl] });
                    if (this.resType === 'src') {
                        this.targetEl.src = this.options.content;
                        if (['VIDEO', 'AUDIO'].includes(this.nodeName)) {
                            this.targetEl.onloadeddata = this.removeAttrFn;
                        }
                        else if (['IMG', 'IFRAME'].includes(this.nodeName)) {
                            this.targetEl.onload = this.removeAttrFn;
                        }
                        else {
                            this.this.removeAttrFn();
                        }
                    }
                    else if (this.resType === 'async') {
                        await getContent.call(this, {
                            content: this.options.content,
                            contType: this.options.contType || 'async',
                            contData: this.options.contData,
                            ajax: Object.assign({ target: this.targetEl }, this.options.ajax),
                            hyphen: this.options.hyphen,
                            cb: (data) => {
                                setContent({
                                    target: this.targetEl,
                                    content: data,
                                    template: this.options.tplStr,
                                    engine: this.options.tplEng,
                                });
                                this.targetEl.removeAttribute('lazy-async');
                                this.targetEl.removeAttribute('lazy-type');
                                this.targetEl.removeAttribute('lazy-data');
                                this.targetEl.removeAttribute('lazy-tpl');
                                super.listen({ name: 'shown', params: [this.targetEl] });
                            }
                        });
                    }
                },
            },
            source: this.options.spy
        }));
        super.listen({ name: 'init', cb });
        return this;
    }
    destroy(cb) {
        if (this.destroyed)
            return this;
        this.spyIns.destroy();
        super.listen({ name: 'destroy', cb });
        return this;
    }
}
Lazy.hostType = 'node';
export default Lazy;
