/**
 * @since Last modified: 2024-07-01 16:26:19
 * @class PlainElem
 * @description The father of all plain elements.
 * @example
 * class xxxElement extends PlainElem;
 */
import Observe from '../modules/Observe';
import deepClone from '../utils/deepClone';
import getAttrBool from '../utils/getAttrBool';
import isNull from '../utils/isNull';
import plan from '../utils/plan';
import setAttr from '../utils/setAttr';
import storage from '../utils/storage';
class PlainElem extends HTMLElement {
    constructor() {
        super();
        this.propsRaw = {};
        this.properties = {};
        this.isCmpt = true;
        this.plans = {};
        this.timestamp = new Date().getTime();
        this.reset = () => {
            this.innerHTML = '';
            this.fillWrap(this.propsRaw);
            this.restoreAttrs();
            this.render(this.propsRaw);
        };
        this.clear = () => {
            this.removeAttribute('value');
        };
        this.set = (key, val) => {
            setAttr(this, key, val);
            this.listen({ name: 'set', params: [key, this.getAttribute(key)] });
        };
        this.on('init', () => {
            this.setAttribute('customized', '');
            this.setCache();
        });
        this.on('reset', () => {
            this.clearCache();
        });
    }
    disconnectedCallback() {
    }
    adoptedCallback() {
    }
    restoreAttrs() {
        for (let k in this.propsProxy) {
            let valProxy = this.propsProxy[k], valRaw = this.propsRaw[k];
            if (valProxy !== valRaw) {
                if (isNull(valRaw)) {
                    this.removeAttribute(k);
                }
                else if (valRaw === true) {
                    this.setAttribute(k, '');
                }
                else if (valRaw === false) {
                    this.removeAttribute(k);
                }
                else {
                    this.setAttribute(k, valRaw);
                }
            }
        }
    }
    createObs() {
        this.observer = new Observe(this.properties);
        this.propsProxy = this.observer.proxy;
    }
    getPropVal(cmpt, name, val) {
        return cmpt.boolAttrs.includes(name) ? getAttrBool(val) : val;
    }
    getHtmlVal(name = 'label', unformatted = true) {
        let val = unformatted ? this.textContent?.trim() : this.innerHTML;
        return val || this.getAttribute(name);
    }
    getInitPropsRaw(cmpt) {
        [...cmpt.custAttrs, ...cmpt.lazyAttrs].forEach((k) => {
            this.propsRaw[k] = this.getAttribute(k);
        });
        cmpt.boolAttrs.forEach((k) => {
            this.propsRaw[k] = getAttrBool(this.getAttribute(k));
        });
    }
    getInitPropsProxy() {
        for (let k in this.propsRaw) {
            this.propsProxy[k] = this.propsRaw[k];
        }
    }
    connectedRender(data) {
        this.render(data);
        this.initialized = true;
        this.listen({ name: 'init' });
    }
    listen({ name, params = [], cb } = {}) {
        name && this.plans.hasOwnProperty(name) ? this.emit(name, ...params) : null;
        if (name && this.propsProxy[`on-${name.toLowerCase()}`]) {
            let fn = new Function('return' + this.propsProxy[`on-${name.toLowerCase()}`])();
            fn && fn.call(this, ...params);
        }
        cb && cb.call(this, ...params);
    }
    on(type, handler) {
        plan.add(type, this, handler);
        return this;
    }
    emit(type, ...params) {
        plan.do(type, this, ...params);
        return this;
    }
    off(type, handler) {
        plan.remove(type, this, handler);
        return this;
    }
    setCache() {
        let storName = this.propsProxy['stor-name'], cache = storage.get(storName);
        if (!storName || !cache) {
            return this;
        }
        let copyCache = deepClone(cache), dataCache = copyCache['data'], hasData = copyCache.hasOwnProperty('data');
        if (hasData) {
            dataCache ? setAttr(this, 'data', dataCache) : this.removeAttribute('data');
            Reflect.deleteProperty(copyCache, 'data');
        }
        for (let k in copyCache) {
            setAttr(this, k, copyCache[k]);
        }
    }
    updateCache(data) {
        let storName = this.propsProxy['stor-name'];
        if (!storName) {
            return this;
        }
        let cache = storage.get(storName) || {};
        Object.assign(cache, data);
        storage.set(storName, cache);
        console.log(this.properties['stor-name'], storage.get(storName));
    }
    clearCache() {
        let storName = this.propsProxy['stor-name'];
        if (!storName) {
            return this;
        }
        storage.clear(storName);
    }
    render(data) {
    }
    fillWrap(data) {
    }
}
window.customElements.define("ax-plain", PlainElem);
export default PlainElem;
