/**  
 * @since Last modified: 2024-09-09 22:37:22
 * @class Lazy
 * @description Folding too long text and omittind.
 * @param {*} elem - target element
 * @param {Object} [options] - Parameters 
 * @see {@link https://codepen.io/axui/pen/ZEwvpNL|demo @ codepen}
 * @example
 * ax.Lazy('#id');
 */
import getEl from '../utils/getEl';
import isEmpty from '../utils/isEmpty';
import instance from '../utils/instance';
import breakpoints from '../utils/breakpoints';
import createEl from '../utils/createEl';
import deepClone from '../utils/deepClone';
import purifyHtml from '../utils/purifyHtml';
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 { T_lazy } from '../../../types/lazy';
import { T_fn, T_obj } from '../../../types/ax';
import optLazy from '../options/optLazy';
import elProps from '../utils/elProps';
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) {
    targetEl: any;
    options: T_lazy = {};
    destroyed: any;
    plans: any;
    storKeys: any;
    storObs: any;
    storTmp: any;
    rawOpts: any;
    static hostType = 'node';
    constructor(elem: any, options?: T_lazy, initial: boolean = true) {
        super();
        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?: any): Promise<any> {
        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: any) => {
                                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?: any): any {
        if (this.destroyed) return this;
        this.spyIns.destroy();
        super.listen({ name: 'destroy', cb });
        return this;
    }
}
export default Lazy;
