import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { UiMessageBlock } from './ui-message-block';
import { NotificationMessageData } from '../../types';
import { Component } from '@angular/core';
import { LinkifyPipe } from '../../pipes/linkify';
import { TranslateModuleStubFactory } from '../../../../tests/stub/translate-module.stub';

const ngContentTestText = 'Some test text';
const testSpanClass = 'test-span';

@Component({
    template: `<ui-message-block>
        <span class="${testSpanClass}" >${ngContentTestText}</span>
    </ui-message-block>`
})
class UiMessageBlockHostComponent {}

describe('UiMessageBlock', () => {
    let component: UiMessageBlock;
    let fixture: ComponentFixture<UiMessageBlock>;
    let data: Array<NotificationMessageData>;
    const defaultTitle = 'Please note';
    let element: HTMLElement;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [
                UiMessageBlock,
                UiMessageBlockHostComponent,
                LinkifyPipe
            ],
            imports: [ TranslateModuleStubFactory({}) ]
        }).compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(UiMessageBlock);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it('One message without description', () => {
        let title = 'SimpleTitle';
        data = [ { title } ];
        component.stringData = data;
        fixture.detectChanges();

        element = document.querySelector('.ui-message-header');
        expect(element.textContent.trim()).toEqual(title);
    });

    it('One message with description', () => {
        let title = 'SimpleTitle';
        let description = 'TestDescription';
        data = [ { title, description } ];
        component.stringData = data;
        fixture.detectChanges();

        element = document.querySelector('.ui-message-header');
        expect(element.textContent.trim()).toEqual(title);

        element = document.querySelector('.ui-message-single-description');
        expect(element.textContent.trim()).toEqual(description);
    });

    it('One message with link', () => {
        let title = 'SimpleTitle';
        let description = 'Some https://docs.cloudlinux.com link';
        data = [ { title, description } ];
        component.stringData = data;
        fixture.detectChanges();

        let anchors: NodeListOf<HTMLElement> =  document.querySelectorAll('a');
        expect(anchors.length).toBe(1);
    });

    it('Ng-content html', () => {
        const hostFixture: ComponentFixture<UiMessageBlockHostComponent> =
            TestBed.createComponent(UiMessageBlockHostComponent);
        hostFixture.detectChanges();

        element = document.querySelector('.ui-message-header');
        expect(element.textContent.trim()).toEqual(defaultTitle);

        element = document.querySelector(`.${testSpanClass}`);
        expect(element.textContent.trim()).toEqual(ngContentTestText);
    });

    describe('Two or more messages', () => {
        const title1 = 'Title', title2 = 'ActuallyUniqueTitle';
        const descr1 = 'Do not use es5', descr2 = 'Not empty string';
        let header: HTMLElement;

        beforeEach(() => {
            data = [
                { title: title1 },
                { title: title2 }
            ];
            component.stringData = data;
            fixture.detectChanges();
            header = document.querySelector('.ui-message-header');
            element = document.querySelector('.ui-message-ordered-list');
        });

        it('Should display default title', () => {
            expect(header.textContent.trim()).toEqual(defaultTitle);
        });

        it('Should display correct number of list element', () => {
            expect(element.children.length).toBe(2);
        });

        it('Should display correct number of inner spans with titles only', () => {
            expect(element.children[0].children.length).toBe(1);
            expect(element.children[1].children.length).toBe(1);
        });

        it('Should display correct titles', () => {
            expect(element.children[0].children[0].textContent.trim()).toEqual(title1);
            expect(element.children[1].children[0].textContent.trim()).toEqual(title2);
        });

        it('Should show correct descriptions', () => {
            component.stringData = [
                { title: title1, description: descr1 },
                { title: title2, description: descr2 }
            ];
            fixture.detectChanges();
            element = document.querySelector('.ui-message-ordered-list');
            expect(element.children[0].children[1].textContent.trim()).toEqual(descr1);
            expect(element.children[1].children[1].textContent.trim()).toEqual(descr2);
        });
    });

    describe('Multiple messages containing links', () => {
        it('Should linkify only one message', () => {
            component.stringData = [
                {title: 'Title1', description: 'Some https://docs.cloudlinux.com link'},
                {title: 'Title2'}
            ];
            fixture.detectChanges();
            let anchors: NodeListOf<HTMLElement> =  document.querySelectorAll('a');
            expect(anchors.length).toBe(1);
        });

        it('Should linkify two messages', () => {
            component.stringData = [
                {title: 'Title1', description: 'Some https://docs.cloudlinux.com link'},
                {title: 'Title2', description: 'Some other https://cloudlinux.com link'}
            ];
            fixture.detectChanges();
            expect(document.querySelectorAll('a').length).toBe(2);
        });
    });
});
