/**  
 * @since Last modified: 2024-09-17 00:30:53
 * @class FileElem
 * @description The custom element : ax-file .
 * @see {@link https://codepen.io/axui/pen/YzMVvWP|demo @ codepen}
 * @example
 * <ax-file name="demo" value="book" placeholder="Reading"></ax-file>;
 */
import { T_el, T_obj } from '../../../types/ax';
import ax from '../ax';
import config from '../global/config';
import prefix from '../global/prefix';
import alias from '../global/alias';
import createEl from '../utils/createEl';
import createTools from '../utils/createTools';
import getAttrArr from '../utils/getAttrArr';
import getAttrBool from '../utils/getAttrBool';
import isEmpty from '../utils/isEmpty';
import renderTpl from '../utils/renderTpl';
import PlainElem from './PlainElem';
class FileElem extends PlainElem {
    holderEl: any;
    inputEl: any;
    meanEl: any;
    propsRaw: any;
    clickEvent: any;
    changeEvent: any;
    toolsEl: any;
    labelEl: any;
    constructor() {
        super();
        super.createObs();
        this.getRawData();
        this.fillWrap(this.propsProxy);
        this.clickEvent = () => {
            this.inputEl.click();
        }
        this.observer.ins.on('set', (data: T_obj) => {
            /* if (data.key === 'value') {
                let len = this.propsProxy.value.split(',').length;
                if (len === 0) {
                    this.classList.remove(`${prefix}filled`);
                    this.labelEl.innerHTML = config.lang.form.fileLabel;
                } else {
                    this.classList.add(`${prefix}filled`);
                    this.labelEl.innerHTML = (len === 1) ? this.propsProxy.value : renderTpl(config.lang.form.fileMulti, { data: len }) + this.propsProxy.value;
                }
            } */
            this.initialized && this.updateCache({ [data.key]: data.value });
        });
        this.changeEvent = new Event('change');
        this.reset = () => {
            for (let k in this.propsRaw) {
                (this.propsRaw[k] !== null && this.propsRaw[k] !== false) ? this.setAttribute(k, this.propsRaw[k]) : this.removeAttribute(k);
            }
            this.inputEl.value = '';
            this.inputEl.dispatchEvent(this.changeEvent);
            this.listen({ name: 'reset' });
        }
        this.clear = () => {
            this.inputEl.value = '';
            this.inputEl.dispatchEvent(this.changeEvent);
            this.listen({ name: 'clear' });
        }
    }
    static lazyAttrs = ['stor-name'];
    static custAttrs = [
        'class',
        'name', 'accept', 'size', 'tools',
        'on-init', 'on-reset', 'on-clear', 'on-change', 'on-set'
    ];
    static boolAttrs = ['disabled', 'readonly', 'multiple'];
    static get observedAttributes() {
        return ['placeholder', ...this.custAttrs, ...this.boolAttrs];
    }
    attributeChangedCallback(name: string, oldVal: string, newVal: string) {
        this.propsProxy[name] = FileElem.boolAttrs.includes(name) ? getAttrBool(newVal) : name === 'tools' ? getAttrArr(newVal, 'close') : newVal;
        if (FileElem.boolAttrs.includes(name)) {
            this.inputEl[name === 'readonly' ? 'readOnly' : name] = this.propsProxy[name];
        } else if (name === 'tools') {
            this.toolsEl && this.toolsEl.remove();
            if (this.propsProxy.tools.length > 0) {
                this.getToolsEl(this.propsProxy.tools);
                this.propsProxy.tools.forEach((k: any) => {
                    if (k.name === 'close') {
                        k.wrapEl.onclick = () => {
                            this.clear();
                        }
                    } else {
                        k.action && k.action.bind(this);
                    }
                });
            }
        } else if (name === 'placeholder') {
            this.holderEl.innerHTML = newVal;
        } else if (['name', 'accept'].includes(name)) {
            this.inputEl.setAttribute(name, newVal);
        }
        if (oldVal !== newVal) {
            this.listen({ name: 'change', params: [{ name, oldVal, newVal }] });
        }
    }
    connectedCallback() {
        this.render();
        this.initialized = true;
        this.listen({ name: 'init' });
    }
    disconnectedCallback() {
    }
    adoptedCallback() {
    }
    getRawData() {
        [...FileElem.custAttrs, ...FileElem.lazyAttrs].forEach((k: string) => {
            this.propsRaw[k] = this.getAttribute(k);
        });
        FileElem.boolAttrs.forEach((k: string) => {
            this.propsRaw[k] = getAttrBool(this.getAttribute(k));
        });
        this.propsRaw.placeholder = this.getAttribute('placeholder') || this.innerHTML || config.lang.form.fileLabel;
        for (let k in this.propsRaw) {
            this.propsProxy[k] = this.propsRaw[k]
        }
        this.propsProxy['tools'] = getAttrArr(this.getAttribute('tools'), 'close');
        this.propsProxy.value = '';
        this.innerHTML = '';
    }
    getToolsEl(data: any) {
        if (!isEmpty(data)) {
            this.toolsEl = createTools(data);
            this.toolsEl.setAttribute(alias, 'tools');
            this.holderEl.insertAdjacentElement('afterEnd', this.toolsEl);
        }
    }
    fillWrap(data: T_obj) {
        this.wrapEl = createEl('div', { [alias]: 'wrap' });
        this.inputEl = createEl('input', { type: 'file', name: data.name })
        this.inputEl.multiple = data.multiple;
        this.holderEl = createEl('i', { [alias]: 'placeholder' }, data.placeholder);
        this.labelEl = createEl('i', { [alias]: 'label' });
        this.meanEl = createEl('i', { [alias]: 'mean' }, 'file');
        this.wrapEl.append(this.inputEl, this.labelEl, this.holderEl, this.meanEl);
    }
    render() {
        this.appendChild(this.wrapEl);
        this.inputEl.addEventListener('change', (e: any) => {
            let files = [...this.inputEl.files],
                names = files.map((k: any) => k.name);
            files.length > 0 && (this.propsProxy.value = names.join(','));
            this.labelEl.innerHTML = (files.length === 0) ? '' : (files.length === 1) ? this.inputEl.value : renderTpl(config.lang.form.fileMulti, { data: files.length }) + this.propsProxy.value;
        }, false);
        this.labelEl.addEventListener('click', this.clickEvent);
        this.holderEl.addEventListener('click', this.clickEvent);
        this.meanEl.addEventListener('click', this.clickEvent);
    }
}
window.customElements.define("ax-file", FileElem);
export default FileElem;
