// jshint esversion: 6
'use strict';

import React from 'react';
import {Wizard} from './Wizard';
import {mount} from '../../build/enzyme';

class MyWizardStep extends React.Component {
    render() {
        return <div />;
    }
}

const WIZARD_STEPS = [
    <MyWizardStep key={0} id={0} />,
    <MyWizardStep key={1} id={1} disabled />,
    <MyWizardStep key={2} id={2} />,
    <MyWizardStep key={3} id={3} validation={() => Promise.reject(new Error('Step Failure'))} />,
    <MyWizardStep key={4} id={4} />,
    <MyWizardStep key={5} id={5} disabled />
];

class MyWizard extends Wizard {
    getSnapshotKey() {
        return this.props.snapshotKey;
    }
    getSnapshotValue() {
        return this.props.data;
    }
    getSteps() {
        return WIZARD_STEPS;
    }
}

describe('Wizard', () => {
    const snapshotKey = () => 'snapshotKey' + Math.random();
    const instance = wrapper => (wrapper ? wrapper.instance() : mount(<MyWizard />).instance());

    it.skip('saves snapshot', () => {
        const data = {someKey: 'someData'};
        const ls = window.localStorage;
        const setItemMock = jest.fn((...args) => ls.setItem(...args));

        window.localStorage = {
            setItem: setItemMock
        };

        const key = snapshotKey();
        const wrapper = mount(<MyWizard snapshotKey={key} />);

        wrapper.setProps({data});

        expect(setItemMock.mock.calls.length).toBe(1);
        expect(setItemMock.mock.calls[0]).toEqual([key, JSON.stringify(data)]);

        window.localStorage = ls;
    });

    it('enables snapshot recording by default', () => {
        const inst = instance();
        expect(inst.snapshotRecording).toBe(true);
    });

    it('thows RangeError if index out of bounds', () => {
        const inst = instance();
        expect(function() {
            inst.setCurrentStepIndex(WIZARD_STEPS.length);
        }).toThrow(RangeError, /out of ranges/);
    });

    it('sibling step index in forward direction', () => {
        const inst = instance();
        const direction = 1;
        inst.goToStep(0);
        inst.goNext(direction);
        expect(inst.getCurrentStepIndex()).toBe(2);
    });

    it('back navigation', () => {
        const inst = instance();
        inst.goToStep(2);
        inst.goBack();
        expect(inst.getCurrentStepIndex()).toBe(0);
    });

    // XXX: inconsistency return - null (see getStepIndexById -1)
    it('sibling step index - null', () => {
        const inst = instance();
        const direction = 1;
        inst.goToStep(4);
        expect(inst.getEnabledSiblingStepIndex(direction)).toBe(null);
    });

    it('keeps getMaxVisitedStepIndex', () => {
        const inst = instance();
        inst.goToStep(2);
        inst.goToStep(0);
        expect(inst.getMaxVisitedStepIndex()).toBe(2);
    });

    it('step validation', () => {
        const inst = instance();
        inst.goToStep(3); // step with hardcoded validation (failure)
        inst.goNext();
        expect(inst.getCurrentStepIndex()).toBe(3);
    });
});
