
window.FilterManager = (() => {
    class FilterManager {
        #updateFilter() {
            for (let i of MediaStorage.Instance.medias) {
                if (!i.ui)
                    continue;
                if (this.match(i))
                    i.ui.root.classList.remove("filtered");
                else
                    i.ui.root.classList.add("filtered");
            }
            MediaStorage.Instance.onFilterUpdated();

            if (this.isFiltering())
                document.body.classList.add("filter-active");
            else
                document.body.classList.remove("filter-active");
        }

        setFilterValue(key, val) {
            this.#filters[key] = val;
            this.#updateFilter();
        }

        setChronologyRange(min, max) {
            let updated = false;

            if (this.#minDate != min) {
                this.#minDate = min;
                updated = true;
            }
            if (this.#maxDate != max) {
                this.#maxDate = max;
                updated = true;
            }
            updated && this.#updateFilter();
        }

        isFiltering() {
            if (window.chronology.isInitialized()) {
                let chronoRange = window.chronology.getRange();
                if (this.#minDate > chronoRange.min || this.#maxDate < chronoRange.max)
                    return true;
            }
            for (let i in this.#filters) {
                if (this.#filters[i]?.length)
                    return true;
            }
            return false;
        }

        // Returns false if image doesnt match
        #matchTags(mediaTags, tags) {
            for (let i of tags)
                if (mediaTags.find(x => x === i || x.startsWith(`${i}/`)))
                    return true;
            return false;
        }

        match(mediaItem) {
            const dateTime = mediaItem.getDateTs();
            if (dateTime < this.#minDate || dateTime > this.#maxDate)
                return false;
            for (let i in this.#filters) {
                if (!this.#filters[i] || !this.#filters[i].length)
                    continue;
                if (i === "Tags") {
                    const mediaTags = mediaItem.allTags();
                    if (this.#filters[i].indexOf(undefined) !== -1 && !mediaTags.length)
                        continue;
                    if (this.#matchTags(mediaTags, this.#filters[i].filter(i => !!i)))
                        continue;
                    return false;
                }
                if (this.#filters[i].indexOf(""+mediaItem.meta[i]?.value) === -1)
                    return false;
            }
            return true;
        }

        #filters = {};
        #minDate = 0;
        #maxDate = Infinity;
    }

    return new FilterManager();
})();

