import EventBus from "../../Events/EventBus";
import Events from "../../Events/Events";
import Utils from "../../Utils/Utils";
import ProductCard from "../Products/ProductCard";

class PriceRangeFilter {
    _$container = null;
    _$sliderMin = null;
    _$sliderMax = null;
    _$valueMin = null;
    _$valueMax = null;
    _$track = null;
    _minValue = 0;
    _maxValue = 0;
    _currentMin = 0;
    _currentMax = 0;
    _debouncedTrigger = null;

    init() {
        this._$container = jQuery('.price-range-filter');

        if (!this._$container.length) {
            return;
        }

        this._$sliderMin = this._$container.find('.price-range-slider-min');
        this._$sliderMax = this._$container.find('.price-range-slider-max');
        this._$valueMin = this._$container.find('.price-range-value-min');
        this._$valueMax = this._$container.find('.price-range-value-max');
        this._$track = this._$container.find('.price-range-track-active');

        // Get min/max from data attributes
        this._minValue = parseFloat(this._$container.data('min')) || 0;
        this._maxValue = parseFloat(this._$container.data('max')) || 1000;
        this._currentMin = this._minValue;
        this._currentMax = this._maxValue;

        // Create debounced trigger function (250ms delay)
        this._debouncedTrigger = Utils.debounce(() => {
            this._triggerFilterEvent();
        }, 250);

        this._attachEventHandlers();
        this._listenForURLRestore();
        this._updateTrack();
    }

    _listenForURLRestore() {
        EventBus.getInstance().registerDynamicEvent({
            key: Events.FILTERS_RESTORED_FROM_URL,
            callback: (filters) => this._restoreUIFromFilters(filters)
        });
    }

    _restoreUIFromFilters(filters) {
        if (filters.priceRange) {
            const { min, max } = filters.priceRange;

            if (min !== null && min !== undefined) {
                this._currentMin = parseFloat(min);
                this._$sliderMin.val(this._currentMin);
            }

            if (max !== null && max !== undefined) {
                this._currentMax = parseFloat(max);
                this._$sliderMax.val(this._currentMax);
            }

            this._updateDisplay();
            this._updateTrack();
        }
    }

    _attachEventHandlers() {
        const _this = this;

        // Handle min slider input
        this._$sliderMin.on('input', function() {
            const value = parseFloat(jQuery(this).val());
            _this._currentMin = value;

            // Prevent min from exceeding max
            if (_this._currentMin > _this._currentMax) {
                _this._currentMin = _this._currentMax;
                jQuery(this).val(_this._currentMin);
            }

            _this._updateDisplay();
            _this._updateTrack();
            _this._debouncedTrigger();
        });

        // Handle max slider input
        this._$sliderMax.on('input', function() {
            const value = parseFloat(jQuery(this).val());
            _this._currentMax = value;

            // Prevent max from going below min
            if (_this._currentMax < _this._currentMin) {
                _this._currentMax = _this._currentMin;
                jQuery(this).val(_this._currentMax);
            }

            _this._updateDisplay();
            _this._updateTrack();
            _this._debouncedTrigger();
        });

        // Listen for filters cleared
        EventBus.getInstance().registerDynamicEvent({
            key: Events.FILTERS_CLEARED,
            callback: () => this._resetPriceRange()
        });
    }

    _updateDisplay() {
        this._$valueMin.html(ProductCard.formatPrice(this._currentMin));
        this._$valueMax.html(ProductCard.formatPrice(this._currentMax));
    }

    _updateTrack() {
        const range = this._maxValue - this._minValue;
        const percentMin = ((this._currentMin - this._minValue) / range) * 100;
        const percentMax = ((this._currentMax - this._minValue) / range) * 100;

        this._$track.css({
            'left': percentMin + '%',
            'width': (percentMax - percentMin) + '%'
        });
    }

    _triggerFilterEvent() {
        // Only trigger if values have changed from the original min/max
        const hasChanged = this._currentMin !== this._minValue || this._currentMax !== this._maxValue;

        if (hasChanged) {
            EventBus.getInstance().triggerEvent(Events.PRICE_RANGE_CHANGED, {
                min: this._currentMin,
                max: this._currentMax
            });
        }
    }

    _resetPriceRange() {
        this._currentMin = this._minValue;
        this._currentMax = this._maxValue;

        this._$sliderMin.val(this._minValue);
        this._$sliderMax.val(this._maxValue);

        this._updateDisplay();
        this._updateTrack();
    }
}

export default PriceRangeFilter;
