import ToubizRangeSlider from './index';
import { fireEvent } from '@nimius/event-utility';
import { expect } from 'chai';

describe('ToubizRangeSlider', () => {
    let dom;
    let slider;

    const type = (element, string) => {
        element.value = string;
        fireEvent(element, 'input');
        fireEvent(element, 'change');
    };

    beforeEach(() => {
        dom = document.createElement('div');
        dom.innerHTML = `
            <div>
                <div data-toubiz-range-slider
                     data-toubiz-range-slider-user-field.min="#target-user-min__1, #target-user-min__2"
                     data-toubiz-range-slider-user-field.max="#target-user-max__1"
                     data-toubiz-range-slider-data-field.min="#target-data-min"
                     data-toubiz-range-slider-data-field.max="#target-data-max"
                     data-toubiz-range-slider-factor="0.1"
                     data-toubiz-range-slider-step="0.1"
                >
        
                </div>
            </div>
        
            <div>
                <input 
                    type="number" 
                    min="0" 
                    max="100" 
                    id="target-data-min" 
                    style="display: none" 
                />
                <input 
                    type="number" 
                    min="0" 
                    max="100" 
                    id="target-data-max" 
                    value="95"
                    style="display: none" 
                />
                <input type="number" id="target-user-min__1" />
                <input type="number" id="target-user-min__2" />
                <input type="number" id="target-user-max__1" />
            </div>
        `;

        document.body.appendChild(dom);

        slider = new ToubizRangeSlider(
            dom.querySelector('[data-toubiz-range-slider]')
        );
    });

    afterEach(() => {
        slider = null;
        document.body.removeChild(dom);
    });

    it('should set bound elements', () => {
        expect(dom.querySelector('#target-data-min').value).to.equal('0');
        expect(dom.querySelector('#target-data-max').value).to.equal('95');
        expect(dom.querySelector('#target-user-min__1').value).to.equal('');
        expect(dom.querySelector('#target-user-min__2').value).to.equal('');
        expect(dom.querySelector('#target-user-max__1').value).to.equal('9.5');
    });

    it('should update values if handles change', () => {
        slider.slider.set([ 20, 40 ]);

        expect(dom.querySelector('#target-data-min').value).to.equal('20');
        expect(dom.querySelector('#target-data-max').value).to.equal('40');
        expect(dom.querySelector('#target-user-min__1').value).to.equal('2.0');
        expect(dom.querySelector('#target-user-min__2').value).to.equal('2.0');
        expect(dom.querySelector('#target-user-max__1').value).to.equal('4.0');
    });

    it('should round according to step', () => {
        slider.slider.set([ 31.41, 62.89 ]);
        expect(dom.querySelector('#target-data-min').value).to.equal('31.4');
        expect(dom.querySelector('#target-data-max').value).to.equal('62.9');
        expect(dom.querySelector('#target-user-min__1').value).to.equal('3.1');
        expect(dom.querySelector('#target-user-min__2').value).to.equal('3.1');
        expect(dom.querySelector('#target-user-max__1').value).to.equal('6.3');
    });

    it('should update handles if input changes', () => {
        // data fields change
        type(dom.querySelector('#target-data-min'), 10);
        type(dom.querySelector('#target-data-max'), 90);

        const [ min, max ] = slider.slider.get();
        expect(parseInt(min, 10), 'slider min').to.equal(10);
        expect(parseInt(max, 10), 'slider max').to.equal(90);

        expect(dom.querySelector('#target-data-min').value, 'data min').to.equal('10');
        expect(dom.querySelector('#target-data-max').value, 'data max').to.equal('90');

        expect(dom.querySelector('#target-user-min__1').value, 'user min 1').to.equal('1.0');
        expect(dom.querySelector('#target-user-min__2').value, 'user min 2').to.equal('1.0');
        expect(dom.querySelector('#target-user-max__1').value, 'user max').to.equal('9.0');
    });

    it('should stay in boundaries when slider changes', () => {
        slider.slider.set([ -999, 999 ]);
        expect(dom.querySelector('#target-data-min').value).to.equal('');
        expect(dom.querySelector('#target-data-max').value).to.equal('');
        expect(dom.querySelector('#target-user-min__1').value).to.equal('');
        expect(dom.querySelector('#target-user-min__2').value).to.equal('');
        expect(dom.querySelector('#target-user-max__1').value).to.equal('');

        const [ min, max ] = slider.slider.get();
        expect(parseInt(min, 10), 'slider min').to.equal(0);
        expect(parseInt(max, 10), 'slider max').to.equal(100);
    });

    it ('should set both data fields if one value is defined', () => {
        const dataMin = dom.querySelector('#target-data-min');
        const dataMax = dom.querySelector('#target-data-max');

        // Slider is at bounds: data fields should be empty
        slider.slider.set([ 0, 100 ]);
        expect(dataMin.value).to.equal('');
        expect(dataMax.value).to.equal('');

        // User changes one slider: both data fields should be filled
        slider.slider.set([ 0, 90 ]);
        expect(parseInt(dataMin.value, 10)).to.equal(0);
        expect(parseInt(dataMax.value, 10)).to.equal(90);
    });

    it ('should only update corresponding user field if one value is defined', () => {
        const userMin = dom.querySelector('#target-user-min__1');
        const userMax = dom.querySelector('#target-user-max__1');

        // Slider is at bounds: user fields should be empty
        slider.slider.set([ 0, 100 ]);
        expect(userMin.value).to.equal('');
        expect(userMax.value).to.equal('');

        // User changes one slider: only corresponding slider should change
        slider.slider.set([ 0, 90 ]);
        expect(userMin.value).to.equal('');
        expect(parseInt(userMax.value, 10)).to.equal(9);
    });

    it ('should update slider state if user enters data manually', () => {
        // User manually changes the inputs
        type(dom.querySelector('#target-user-min__1'), 1);
        type(dom.querySelector('#target-user-max__1'), 9);

        // Slider state should reflect that
        const [ min, max ] = slider.slider.get();
        expect(parseInt(min, 10)).to.equal(10);
        expect(parseInt(max, 10)).to.equal(90);
    });

    it ('should update data fields if user enters data manually', () => {
        // User manually changes the inputs
        type(dom.querySelector('#target-user-min__1'), 1);
        type(dom.querySelector('#target-user-max__1'), 9);

        // Data fields should reflect that
        expect(parseInt(dom.querySelector('#target-data-min').value, 10)).to.equal(10);
        expect(parseInt(dom.querySelector('#target-data-max').value, 10)).to.equal(90);
    });

    it('should stay in boundaries when user updates', () => {
        // User manually changes the inputs
        type(dom.querySelector('#target-user-min__1'), -999);
        type(dom.querySelector('#target-user-max__1'), 999);

        expect(dom.querySelector('#target-data-min').value, 'data min').to.equal('');
        expect(dom.querySelector('#target-data-max').value, 'data max').to.equal('');
        expect(dom.querySelector('#target-user-min__1').value, 'user min 1').to.equal('');
        expect(dom.querySelector('#target-user-min__2').value, 'user min 2').to.equal('');
        expect(dom.querySelector('#target-user-max__1').value, 'user max 1').to.equal('');

        const [ min, max ] = slider.slider.get();
        expect(parseInt(min, 10), 'slider min').to.equal(0);
        expect(parseInt(max, 10), 'slider max').to.equal(100);
    });
});
