import { fireEvent } from '@nimius/event-utility';
import { attributeSelector } from './selector-utilities';

const ATTRIBUTE = Object.freeze({
    FILTER_FORM: 'data-toubiz-results-list.filter-form',
    TAG: 'data-toubiz-results.filter-tag',
    TAG_FALLBACK: 'data-js-poi-filter-tag',
    RESET_EVENT: 'data-toubiz-results.filter-tag-reset-event',
    RESET_TARGET: 'data-toubiz-results.filter-tag-reset-target',
});

export class RemoveFilters {

    /**
     * @param {HTMLElement} node - node wrapping the results list tagged by `data-toubiz-filter-tags`
     * @param {HTMLFormElement} form
     */
    constructor (node, form) {
        /** @private {HTMLElement} */
        this.node = node;

        /** @private {HTMLFormElement} */
        this.form = form;

        if (this.node && this.form) {
            this.initTags();
        }
    }

    initTags () {
        for (const tag of this.getTags()) {
            tag.addEventListener('click', (e) => {
                e.preventDefault();
                this.removeFilter(tag);
                this.fireAllTagsRemovedEventIfNoTagsLeft();
            });
        }
    }

    /**
     * @param {HTMLElement} tag
     */
    removeFilter (tag) {
        const filterId = tag.getAttribute(ATTRIBUTE.TAG) || tag.dataset.id;
        const resetEvent = tag.getAttribute(ATTRIBUTE.RESET_EVENT);
        const resetTargetSelector = tag.getAttribute(ATTRIBUTE.RESET_TARGET);
        for (const filter of this.getItems(filterId)) {
            const type = filter.getAttribute('type');

            if (type === 'checkbox') {
                filter.checked = false;
            } else if (type === 'number') {
                filter.value = '';
            }

            fireEvent(filter, 'input');
        }

        if (tag.parentNode) {
            tag.parentNode.removeChild(tag);
        }

        if (resetEvent && resetTargetSelector) {
            const resetTarget = document.querySelector(resetTargetSelector);
            if (resetTarget) {
                fireEvent(resetTarget, resetEvent);
            }
        }

        fireEvent(this.node, 'tagRemoved', { filterId });
    }

    fireAllTagsRemovedEventIfNoTagsLeft() {
        if (this.getTags().length === 0) {
            fireEvent(this.node, 'allTagsRemoved');
        }
    }

    /**
     * @private
     * @returns {Element[]}
     */
    getTags() {
        const tags = [ ...document.querySelectorAll(attributeSelector(ATTRIBUTE.TAG)) ];
        const fallback = [ ...document.querySelectorAll(attributeSelector(ATTRIBUTE.TAG_FALLBACK)) ];
        if (fallback.length > 0) {
            console.warn(
                `The ${ATTRIBUTE.TAGS_FALLBACK} attribute is deprecated. Please use the newer ${ATTRIBUTE.TAGS}`
            );
        }
        return [ ...tags, ...fallback ];
    }

    /**
     * @param {string} filterId
     * @returns {HTMLElement[]}
     * @private
     */
    getItems(filterId) {
        const items = [];
        const selectors = [ `#${filterId}`, `[data-id="${filterId}"]` ];

        for (const selector of selectors) {
            try {
                items.push(...this.form.querySelectorAll(selector));
            } catch (e) {
                console.warn(e);
            }
        }

        return items;
    }


}
