
$(() => {
    const INPUT_CONTAINER_CLASSES = "col-12 col-xl-3 col-md-4 col-sm-6";

    function makeDoubleSlider(minValue, maxValue, actualMin, actualMax, serialize) {
        if (!serialize)
            serialize = i => i;
        let resultContainer = document.createElement("div");
        resultContainer.className = `slider-container ${INPUT_CONTAINER_CLASSES}`;
        let sliderDiv = document.createElement("div");
        sliderDiv.className = "container";
        resultContainer.appendChild(sliderDiv);
        let labelRow = document.createElement("div");
        labelRow.className = "container justify-content-between";
        let minValueLabel = document.createElement("input");
        minValueLabel.className = "slider-value slider-min-value form-control";
        minValueLabel.type = "text";
        minValueLabel.value = serialize(actualMin);
        labelRow.appendChild(minValueLabel);
        let maxValueLabel = document.createElement("input");
        maxValueLabel.className = "slider-value slider-max-value form-control";
        maxValueLabel.type = "text";
        maxValueLabel.value = serialize(actualMax);
        labelRow.appendChild(maxValueLabel);
        sliderDiv.appendChild(labelRow);
        let inputContainer = document.createElement("div");
        inputContainer.className = "container";
        sliderDiv.appendChild(inputContainer);
        let sliderCol = document.createElement("div");
        sliderCol.className = "col slider-col";
        inputContainer.appendChild(sliderCol);
        let input = document.createElement("input");
        input.type = "text";
        input.className = "col";
        input.dataset.sliderMin = minValue ?? 0;
        input.dataset.sliderMax = maxValue ?? 100;
        input.dataset.sliderValue = `[${actualMin},${actualMax}]`;
        input.dataset.sliderTooltip = "hide";
        sliderCol.appendChild(input);
        let jQueryInput = $(input);
        jQueryInput.slider();
        let onChange = () => {};
        jQueryInput.on('slideStop', evt => onChange({ min: evt.value[0], max: evt.value[1] }));
        jQueryInput.on('slide', evt => {
            minValueLabel.value = serialize(evt.value[0]);
            maxValueLabel.value = serialize(evt.value[1]);
        });
        $(minValueLabel).datepicker({
            format: "dd/mm/yyyy",
            todayBtn: "linked",
            autoclose: true,
            startDate: serialize(minValue),
            endDate: serialize(maxValue)
        }).on('changeDate', e => {
            let maxDate = jQueryInput.slider('getValue')[1];
            jQueryInput.slider("setValue", [ e.date.getTime(), maxDate ]);
            onChange({ min: e.date.getTime(), max: maxDate });
        });
        $(maxValueLabel).datepicker({
            format: "dd/mm/yyyy",
            todayBtn: "linked",
            autoclose: true,
            startDate: serialize(minValue),
            endDate: serialize(maxValue)
        }).on('changeDate', e => {
            let min = jQueryInput.slider('getValue')[0];
            jQueryInput.slider("setValue", [ min, e.date.getTime() ]);
            onChange({ min: min, max: e.date.getTime() });
        });
        return {
            container: resultContainer,
            minValueLabel: minValueLabel,
            maxValueLabel: maxValueLabel,
            input: jQueryInput,
            getInputValue: () => { const val = jQueryInput.slider('getValue'); return { min: val[0], max: val[1] }; },
            onChange: (fnc) => { onChange = fnc; }
        };
    }

    const EMPTY_STRING = "(Empty)";

    window.ReloadFilters = function(mediaManager, onNewData) {
        let buildFilterBar = (labelText, canBeEmpty, possibleValues) => {
            let result = document.createElement("div");
            result.className = INPUT_CONTAINER_CLASSES;
            let label = document.createElement('label');
            result.appendChild(label);
            label.textContent = labelText;
            label.className = "container";
            let select = document.createElement('select');
            select.multiple = 'multiple';
            label.appendChild(select);
            let allPossibleValues = [].concat(canBeEmpty ? [undefined] : [], possibleValues);
            let currentSelection = window.FilterManager.getFilterValues(labelText);
            let existingValue = currentSelection.include.filter(x => allPossibleValues.indexOf(x) >= 0);
            if (existingValue.length != currentSelection.include.length)
                window.FilterManager.setFilterValue(labelText, existingValue);
            existingValue = currentSelection.exclude.filter(x => allPossibleValues.indexOf(x) >= 0);
            if (existingValue.length != currentSelection.exclude.length)
                window.FilterManager.setExclusionFilter(labelText, existingValue);
            for (let i of allPossibleValues) {
                let opt = document.createElement("option");
                opt.textContent = i ? i : EMPTY_STRING;
                opt.value = i ?? "";
                if (currentSelection.include.indexOf(opt.value) >= 0)
                    opt.selected = true;
                else if (currentSelection.exclude.indexOf(opt.value) >= 0)
                    opt.selected = opt.indeterminate = true;
                select.appendChild(opt);
            }
            let multiselect = makeMultiselect(select);
            multiselect.addEventListener(e => {
                let val = e.filter(i => i.checked && !i.indeterminate).map(i => i.value === EMPTY_STRING ? "" : i.value);
                window.FilterManager.setFilterValue(labelText, val);
                val = e.filter(i => i.checked && i.indeterminate).map(i => i.value === EMPTY_STRING ? "" : i.value);
                window.FilterManager.setExclusionFilter(labelText, val);
                window.FilterManager.updateFilter();
            });
            return {
                content: result
            };
        };

        let container = document.getElementById('pch-filterbar');
        if (container.children.length && !onNewData)
            return;
        container.textContent = '';
        if (MediaStorage.Instance.isLoading())
            return;
        for (let i of Object.keys(mediaManager.allMetaTypes).filter(i => mediaManager.allMetaTypes[i].type === 'string' ||
                [].indexOf(i) >= 0)) {
            let filterUi = buildFilterBar(i, mediaManager.allMetaTypes[i].canBeEmpty, Array.from(mediaManager.allMeta[i]).sort());
            container.appendChild(filterUi.content);
        }

        let filterUi = buildFilterBar("Tags", true, Array.from(mediaManager.allTags).sort());
        container.appendChild(filterUi.content);

        if (window.chronology.isInitialized()) {
            let range = window.chronology.getRange();
            let filteredChronology = window.FilterManager.getChronologyRange();
            let minChronology = Math.max(filteredChronology.min, range.min.getTime());
            let maxChronology = Math.min(filteredChronology.max, range.max.getTime());
            let timeSlider = makeDoubleSlider(range.min.getTime(), range.max.getTime(), minChronology, maxChronology, i => (new Date(i)).toLocaleDateString());
            timeSlider.onChange(val => window.FilterManager.setChronologyRange(val.min, val.max));
            container.appendChild(timeSlider.container);
        }
    }

    document.getElementById('pch-navbar-filterToggle').addEventListener('click', e => {
        e.preventDefault();
        let filterBarDom = document.getElementById('pch-filterbarContainer');
        if (filterBarDom.style.display)
            filterBarDom.style.display = "";
        else
            filterBarDom.style.display = "flex"
    });

    document.onClosePopinRequested(() => {
        document.getElementById('pch-filterbarContainer').style.display = "";
    });
});

