import React from 'react';
import ReactDOM from 'react-dom';
import { mount } from 'enzyme';
import { CreditCard } from 'web-foundation';
import { strPad } from 'web-foundation/etc/format';
import FieldKit from 'field-kit/dist/field-kit';
const CardFormatter = FieldKit.AdaptiveCardFormatter;

describe('CreditCard', function() {
    const visa = {
        number: '4485185693146008',
        month: 6,
        year: 2060,
        zip: '94107'
    };

    it('should fill properly', function() {
        const model = new CreditCard.Model(visa);

        expect(model.number).to.equal(visa.number);
        expect(model.month).to.equal(visa.month);
        expect(model.year).to.equal(visa.year);
        expect(model.zip).to.equal(visa.zip);

        // these should be autopopulated on fill
        expect(model.type).to.equal('visa');
        expect(model.lastFour).to.equal(visa.number.slice(-4));
    });

    it('should fill individual properties correctly', function() {
        const model = new CreditCard.Model(visa),
            changes = {
                month: 11,
                year: 2018
            };

        expect(model.month).to.equal(visa.month);
        expect(model.year).to.equal(visa.year);

        model.fill(changes);

        expect(model.month).to.equal(changes.month);
        expect(model.year).to.equal(changes.year);
    });

    it('should auto detect card type', function() {
        const model = new CreditCard.Model(),
            types = {
                'american-express': '344759392605453',
                'discover': '6011214946385276',
                'jcb': '3595094654223120',
                'diners-club': '36519120418998',
                'maestro': '5018404512301667',
                'mastercard': '5573731008602761'
            };

        for (const type in types) {
            model.fill({ number: types[type] });
            expect(model.type).to.equal(type);
        }
    });
});

describe('<CreditCard />', function() {
    const card = {
        number: '4532576331258176',
        cvv: '777',
        month: 7,
        year: 2027,
        zip: '94107'
    };

    it('should initialize all nice like', function() {
        const wrapper = mount(<CreditCard.View />);

        expect(wrapper.children().find('.row')).to.have.length(2);
        expect(wrapper.find('.row.t100').find('input')).to.have.length(1);
        expect(wrapper.find('.row.t30-30-30').find('input')).to.have.length(3);
    });

    it('should have nickname field if passes as prop', function() {
        const wrapper = mount(<CreditCard.View nickname />);

        expect(wrapper.children().find('.row')).to.have.length(3);
        expect(wrapper.find('.row.t100')).to.have.length(2);
        expect(wrapper.find('.row.t100').find('input')).to.have.length(2);
        expect(wrapper.find('.row.t30-30-30').find('input')).to.have.length(3);
    });

    it('should fill with stuff', function() {
        const model = new CreditCard.Model(),
            wrapper = mount(<CreditCard.View model={ model } />),
            node = ReactDOM.findDOMNode(wrapper.instance());

        model.fill(card);
        wrapper.update();

        expect(node.getElementsByTagName('input')[0].value)
            .to.equal(new CardFormatter().format(card.number));
        expect(node.getElementsByTagName('input')[1].value)
            .to.equal(`${strPad(card.month, 2, 1)}/${card.year % 100}`);
        expect(node.getElementsByTagName('input')[2].value).to.equal(card.cvv);
        expect(node.getElementsByTagName('input')[3].value).to.equal(card.zip);
    });

    it('updateExpirationDate() should update the model properly', function() {
        const model = new CreditCard.Model(),
            wrapper = mount(<CreditCard.View model={ model } />),
            date = { month: 2, year: 2020 };

        wrapper.instance().updateExpirationDate(date);

        expect(model.month).to.equal(2);
        expect(model.year).to.equal(2020);

        wrapper.instance().updateExpirationDate(null);

        expect(model.month).to.equal(null);
        expect(model.year).to.equal(null);
    });

    it('should allow setting custom error messages', function(done) {
        const model = new CreditCard.Model(),
            wrapper = mount(
                <CreditCard.View model={ model }
                    inlineErrors />),
            msg = 'KI2ctzpN7r';

        wrapper.instance().setErrorMessages({ number: msg });
        wrapper.instance().formValidate(() => {
            expect(wrapper.find('.text-input')
                .find('.error-tooltip').first().text()).to.equal(msg);
            done();
        });
    });

    it('should know what is valid', function(done) {
        const model = new CreditCard.Model(card),
            wrapper = mount(<CreditCard.View model={ model } />);

        wrapper.instance().formValidate(() => {
            const errors = wrapper.instance().model.errors;

            expect(Object.keys(errors).every((key) => !errors[key]));
            done();
        });
    });
});
