import { DOM, IBindingContext, createBindingContext, ViewController } from 'mframejs';
import { JSDOM } from 'jsdom';
import { RepeatAttribute } from '../../../src/mframejs/attribute/repeatAttribute';

let tempNode: any;
let repeatAttribute: RepeatAttribute;
let bindingContext: IBindingContext;



describe('repeatAttribute "a of arrayNumber"', () => {


    beforeAll(() => {
        const window = new JSDOM('').window;
        DOM.setConfig(window, window.document);
        tempNode = DOM.document.createElement('div');
        tempNode.setAttribute('repeat.for', 'a of arrayNumber');
        tempNode.innerHTML = '${a}';
        repeatAttribute = new RepeatAttribute();
        bindingContext = createBindingContext({
            arrayNumber: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        });
        repeatAttribute.$bindingContext = bindingContext;
        repeatAttribute.$element = tempNode;
        repeatAttribute.$attribute = tempNode.getAttributeNode('repeat.for');
        repeatAttribute.$controller = ({
            getView() {
                return new ViewController(null, null);
            }
        } as any);

    });



    it('call created', () => {
        expect(repeatAttribute.created()).toBe(undefined);
    });



    it('call attached', () => {
        DOM.document.body.appendChild(tempNode);
        expect(repeatAttribute.attached()).toBe(undefined);
    });



    it('test elements correct rows are created', async () => {
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(10);
    });



    it('test elements content of rows', () => {
        expect(DOM.document.body.children.length).toBe(10);
        expect(DOM.document.body.children[0].innerHTML).toBe('1');
        expect(DOM.document.body.children[1].innerHTML).toBe('2');
        expect(DOM.document.body.children[2].innerHTML).toBe('3');
        expect(DOM.document.body.children[3].innerHTML).toBe('4');
        expect(DOM.document.body.children[4].innerHTML).toBe('5');
        expect(DOM.document.body.children[5].innerHTML).toBe('6');
        expect(DOM.document.body.children[6].innerHTML).toBe('7');
        expect(DOM.document.body.children[7].innerHTML).toBe('8');
        expect(DOM.document.body.children[8].innerHTML).toBe('9');
        expect(DOM.document.body.children[9].innerHTML).toBe('10');

    });



    it('test arrayNumber.reverse()', async () => {
        bindingContext.$context.arrayNumber.reverse();
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(10);
        expect(DOM.document.body.children[0].innerHTML).toBe('10');
        expect(DOM.document.body.children[1].innerHTML).toBe('9');
        expect(DOM.document.body.children[2].innerHTML).toBe('8');
        expect(DOM.document.body.children[3].innerHTML).toBe('7');
        expect(DOM.document.body.children[4].innerHTML).toBe('6');
        expect(DOM.document.body.children[5].innerHTML).toBe('5');
        expect(DOM.document.body.children[6].innerHTML).toBe('4');
        expect(DOM.document.body.children[7].innerHTML).toBe('3');
        expect(DOM.document.body.children[8].innerHTML).toBe('2');
        expect(DOM.document.body.children[9].innerHTML).toBe('1');
    });


    it('test arrayNumber.reverse()', async () => {
        bindingContext.$context.arrayNumber.reverse();
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(10);
        expect(DOM.document.body.children[0].innerHTML).toBe('1');
        expect(DOM.document.body.children[1].innerHTML).toBe('2');
        expect(DOM.document.body.children[2].innerHTML).toBe('3');
        expect(DOM.document.body.children[3].innerHTML).toBe('4');
        expect(DOM.document.body.children[4].innerHTML).toBe('5');
        expect(DOM.document.body.children[5].innerHTML).toBe('6');
        expect(DOM.document.body.children[6].innerHTML).toBe('7');
        expect(DOM.document.body.children[7].innerHTML).toBe('8');
        expect(DOM.document.body.children[8].innerHTML).toBe('9');
        expect(DOM.document.body.children[9].innerHTML).toBe('10');
    });


    it('test arrayNumber.reverse()', async () => {
        bindingContext.$context.arrayNumber.reverse();
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(10);
        expect(DOM.document.body.children[0].innerHTML).toBe('10');
        expect(DOM.document.body.children[1].innerHTML).toBe('9');
        expect(DOM.document.body.children[2].innerHTML).toBe('8');
        expect(DOM.document.body.children[3].innerHTML).toBe('7');
        expect(DOM.document.body.children[4].innerHTML).toBe('6');
        expect(DOM.document.body.children[5].innerHTML).toBe('5');
        expect(DOM.document.body.children[6].innerHTML).toBe('4');
        expect(DOM.document.body.children[7].innerHTML).toBe('3');
        expect(DOM.document.body.children[8].innerHTML).toBe('2');
        expect(DOM.document.body.children[9].innerHTML).toBe('1');
    });


    it('test arrayNumber.sort(fn)', async () => {
        bindingContext.$context.arrayNumber.sort(function (a: number, b: number) {
            return a - b;
        });
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(10);
        expect(DOM.document.body.children[0].innerHTML).toBe('1');
        expect(DOM.document.body.children[1].innerHTML).toBe('2');
        expect(DOM.document.body.children[2].innerHTML).toBe('3');
        expect(DOM.document.body.children[3].innerHTML).toBe('4');
        expect(DOM.document.body.children[4].innerHTML).toBe('5');
        expect(DOM.document.body.children[5].innerHTML).toBe('6');
        expect(DOM.document.body.children[6].innerHTML).toBe('7');
        expect(DOM.document.body.children[7].innerHTML).toBe('8');
        expect(DOM.document.body.children[8].innerHTML).toBe('9');
        expect(DOM.document.body.children[9].innerHTML).toBe('10');
    });


    it('test arrayNumber.push(11)', async () => {
        bindingContext.$context.arrayNumber.push(11);
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(11);
        expect(DOM.document.body.children[10].innerHTML).toBe('11');
    });



    it('test arrayNumber.pop()', async () => {
        bindingContext.$context.arrayNumber.pop();
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(10);
        expect(DOM.document.body.children[10]).toBe(undefined);
        expect(DOM.document.body.children[9].innerHTML).toBe('10');
    });



    it('test replace same size', async () => {
        bindingContext.$context.arrayNumber = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(10);
        expect(DOM.document.body.children[0].innerHTML).toBe('11');
        expect(DOM.document.body.children[1].innerHTML).toBe('12');
        expect(DOM.document.body.children[2].innerHTML).toBe('13');
        expect(DOM.document.body.children[3].innerHTML).toBe('14');
        expect(DOM.document.body.children[4].innerHTML).toBe('15');
        expect(DOM.document.body.children[5].innerHTML).toBe('16');
        expect(DOM.document.body.children[6].innerHTML).toBe('17');
        expect(DOM.document.body.children[7].innerHTML).toBe('18');
        expect(DOM.document.body.children[8].innerHTML).toBe('19');
        expect(DOM.document.body.children[9].innerHTML).toBe('20');
    });


    it('test replace smaller', async () => {
        bindingContext.$context.arrayNumber = [1, 2, 3];
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(3);
        expect(DOM.document.body.children[0].innerHTML).toBe('1');
        expect(DOM.document.body.children[1].innerHTML).toBe('2');
        expect(DOM.document.body.children[2].innerHTML).toBe('3');
    });


    it('test replace bigger', async () => {
        bindingContext.$context.arrayNumber = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(10);
        expect(DOM.document.body.children[0].innerHTML).toBe('11');
        expect(DOM.document.body.children[1].innerHTML).toBe('12');
        expect(DOM.document.body.children[2].innerHTML).toBe('13');
        expect(DOM.document.body.children[3].innerHTML).toBe('14');
        expect(DOM.document.body.children[4].innerHTML).toBe('15');
        expect(DOM.document.body.children[5].innerHTML).toBe('16');
        expect(DOM.document.body.children[6].innerHTML).toBe('17');
        expect(DOM.document.body.children[7].innerHTML).toBe('18');
        expect(DOM.document.body.children[8].innerHTML).toBe('19');
        expect(DOM.document.body.children[9].innerHTML).toBe('20');
    });


    it('test arrayNumber.splice(0, 0, 100)', async () => {
        bindingContext.$context.arrayNumber.splice(0, 0, 100);
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(11);
        expect(DOM.document.body.children[0].innerHTML).toBe('100');
        expect(DOM.document.body.children[1].innerHTML).toBe('11');
        expect(DOM.document.body.children[2].innerHTML).toBe('12');
        expect(DOM.document.body.children[3].innerHTML).toBe('13');
        expect(DOM.document.body.children[4].innerHTML).toBe('14');
        expect(DOM.document.body.children[5].innerHTML).toBe('15');
        expect(DOM.document.body.children[6].innerHTML).toBe('16');
        expect(DOM.document.body.children[7].innerHTML).toBe('17');
        expect(DOM.document.body.children[8].innerHTML).toBe('18');
        expect(DOM.document.body.children[9].innerHTML).toBe('19');
        expect(DOM.document.body.children[10].innerHTML).toBe('20');
    });


    it('test arrayNumber.splice(0, 1)', async () => {
        bindingContext.$context.arrayNumber.splice(0, 1);
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(10);
        expect(DOM.document.body.children[0].innerHTML).toBe('11');
        expect(DOM.document.body.children[1].innerHTML).toBe('12');
        expect(DOM.document.body.children[2].innerHTML).toBe('13');
        expect(DOM.document.body.children[3].innerHTML).toBe('14');
        expect(DOM.document.body.children[4].innerHTML).toBe('15');
        expect(DOM.document.body.children[5].innerHTML).toBe('16');
        expect(DOM.document.body.children[6].innerHTML).toBe('17');
        expect(DOM.document.body.children[7].innerHTML).toBe('18');
        expect(DOM.document.body.children[8].innerHTML).toBe('19');
        expect(DOM.document.body.children[9].innerHTML).toBe('20');
    });


    it('test arrayNumber.shift()', async () => {
        bindingContext.$context.arrayNumber.shift();
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(9);
        expect(DOM.document.body.children[0].innerHTML).toBe('12');
        expect(DOM.document.body.children[1].innerHTML).toBe('13');
        expect(DOM.document.body.children[2].innerHTML).toBe('14');
        expect(DOM.document.body.children[3].innerHTML).toBe('15');
        expect(DOM.document.body.children[4].innerHTML).toBe('16');
        expect(DOM.document.body.children[5].innerHTML).toBe('17');
        expect(DOM.document.body.children[6].innerHTML).toBe('18');
        expect(DOM.document.body.children[7].innerHTML).toBe('19');
        expect(DOM.document.body.children[8].innerHTML).toBe('20');
    });


    it('test arrayNumber.splice(0, 0, 11)', async () => {
        bindingContext.$context.arrayNumber.splice(0, 0, 11);
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(10);
        expect(DOM.document.body.children[0].innerHTML).toBe('11');
        expect(DOM.document.body.children[1].innerHTML).toBe('12');
        expect(DOM.document.body.children[2].innerHTML).toBe('13');
        expect(DOM.document.body.children[3].innerHTML).toBe('14');
        expect(DOM.document.body.children[4].innerHTML).toBe('15');
        expect(DOM.document.body.children[5].innerHTML).toBe('16');
        expect(DOM.document.body.children[6].innerHTML).toBe('17');
        expect(DOM.document.body.children[7].innerHTML).toBe('18');
        expect(DOM.document.body.children[8].innerHTML).toBe('19');
        expect(DOM.document.body.children[9].innerHTML).toBe('20');
    });


    it('test arrayNumber = null', async () => {
        bindingContext.$context.arrayNumber = null;
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(0);
    });


    it('test arrayNumber = [1]', async () => {
        bindingContext.$context.arrayNumber = [1000];
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(1);
        expect(DOM.document.body.children[0].innerHTML).toBe('1000');
    });


    it('test arrayNumber = undefined', async () => {
        bindingContext.$context.arrayNumber = undefined;
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(0);
    });


    it('test arrayNumber = [1]', async () => {
        bindingContext.$context.arrayNumber = [1000];
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(1);
        expect(DOM.document.body.children[0].innerHTML).toBe('1000');
    });


    it('test arrayNumber = 1', async () => {
        bindingContext.$context.arrayNumber = 1;
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(0);
    });



    it('test arrayNumber = [1]', async () => {
        bindingContext.$context.arrayNumber = [1000];
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(1);
        expect(DOM.document.body.children[0].innerHTML).toBe('1000');
    });


    it('test arrayNumber = {}', async () => {
        bindingContext.$context.arrayNumber = {};
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(0);
    });


    it('test arrayNumber = [1]', async () => {
        bindingContext.$context.arrayNumber = [1000];
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(1);
        expect(DOM.document.body.children[0].innerHTML).toBe('1000');
    });

    it('test arrayNumber = "sometext"', async () => {
        bindingContext.$context.arrayNumber = 'sometext';
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(0);
    });


    it('test arrayNumber = [1]', async () => {
        bindingContext.$context.arrayNumber = [1000];
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(1);
        expect(DOM.document.body.children[0].innerHTML).toBe('1000');
    });



    it('detach', async () => {
        repeatAttribute.detached();
    });



    it('check i removed all', async () => {
        await DOM.waitFor(0);
        expect(DOM.document.body.children.length).toBe(0);
    });



});

