/* tslint:disable:no-unused-variable */
import { FormsModule } from '@angular/forms';
import { async, fakeAsync, ComponentFixture, TestBed, tick, inject } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Injectable, DebugElement, EventEmitter } from '@angular/core';
import { newEvent, click } from '../../testing';
import { MdDialogModule, MaterialModule, MdDialog, MdDialogConfig, Overlay, OverlayContainer, OVERLAY_PROVIDERS } from '@angular/material';
import { AbstractMockObservableService } from '../../common/abstract-mock-observable.service';
import { ShiftChangeProtocolComponent } from '../shift-change-protocol/shift-change-protocol.component';
import { FutureNotificationsComponent } from '../../lists/future-notifications/future-notifications.component';
import { FinishedNotificationsComponent } from '../../lists/finished-notifications/finished-notifications.component';
import { OpenNotificationsComponent } from '../../lists/open-notifications/open-notifications.component';
import { ResponsibilityComponent } from './responsibility.component';
import { RESPONSIBILITIES } from '../../test-data/responsibilities';
import { USERS } from '../../test-data/users';
import { Responsibility } from '../../model/responsibility';
import { ResponsibilityService } from '../../services/responsibility.service';
import { MdDialogRef } from '@angular/material';
import { MockComponent } from '../../testing/mock.component';
import { StringToDatePipe } from '../../common-components/pipes/string-to-date.pipe';
import { FormattedDatePipe } from '../../common-components/pipes/formatted-date.pipe';
import { NotificationService } from '../../services/notification.service';
import { DaterangepickerConfig } from 'ng2-daterangepicker';
import { FilterComponent } from '../../filter/filter.component';
import { OverviewComponent } from '../../pages/overview/overview.component';
import { MessageService } from '../../services/message.service';
import { Router } from '@angular/router';
import { SessionContext } from '../../common/session-context';
let component: ResponsibilityComponent;
let responsibilityFixture: ComponentFixture<ResponsibilityComponent>;
let respPage: ResponsilityPage;

function testCheckboxRow(des: DebugElement[], targetVal: boolean): void {
  for (const de of des) {
    const hie: HTMLInputElement = de.nativeElement;
    expect(hie.checked).toBe(targetVal);
  }
}

describe('ResponsibilityComponent', () => {
  let mockService;    

  class FakeRouter {
    navigate(commands: any[]) {
      return commands[0];
    }
  }
  
  class MockBtbService extends AbstractMockObservableService {
    getPlanedResponsibilities() {
      return this;
    };
    confirmResponsibilities(resp: Responsibility[]) {
      return this;
    };
  }

  beforeEach(async(() => {

    mockService = new MockBtbService();        

    TestBed.configureTestingModule({
      imports: [FormsModule, MdDialogModule],
      declarations: [

        ResponsibilityComponent,
        MockComponent({ selector: 'input', inputs: ['options'] })
      ],
      providers: [
        { provide: ResponsibilityService, useValue: mockService },
        { provide: MdDialogRef, useValue: MdDialogRef },
        { provide: MessageService, useClass: MessageService },
        { provide: SessionContext, useClass: SessionContext },
        { provide: DaterangepickerConfig, useClass: DaterangepickerConfig }
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    responsibilityFixture = TestBed.createComponent(ResponsibilityComponent);
    component = responsibilityFixture.componentInstance;
    responsibilityFixture.componentInstance.responsiblitySelection = RESPONSIBILITIES;
  });

  it('should show Responsibilities with checkboxes after getResponsibilities', async(() => {

    const resps = RESPONSIBILITIES;
    resps[0].responsibilityList[0].isActive = true; // set a distict field to true
    resps[2].responsibilityList[0].isActive = false; // set another field to false
    mockService.content = resps;


    responsibilityFixture.detectChanges();

    let elLocal: HTMLInputElement;
    responsibilityFixture.whenStable().then(() => { // wait for async getResponsibilities
      responsibilityFixture.detectChanges();        // update view with array

      let des: DebugElement[];
      des = responsibilityFixture.debugElement.queryAll(By.css('.responsibility-checkbox-er'));
      expect(des.length).toBe(3);
      des = responsibilityFixture.debugElement.queryAll(By.css('.responsibility-checkbox-gr'));
      expect(des.length).toBe(3);

      // check first modification
      elLocal = des[0].nativeElement;
      expect(elLocal.checked).toBe(true);
      des = responsibilityFixture.debugElement.queryAll(By.css('.responsibility-checkbox-er'));
      expect(des.length).toBe(3);

      // check second modification
      elLocal = des[2].nativeElement;
      expect(elLocal.checked).toBe(false);

      des = responsibilityFixture.debugElement.queryAll(By.css('.responsibility-checkbox-dhr'));
      expect(des.length).toBe(3);

      des = responsibilityFixture.debugElement.queryAll(By.css('.responsibility-checkbox-wr'));
      expect(des.length).toBe(3);

    });
  }));

  it('should show banner info when confirmResponsibilities clicked but responsibilities changed meanwhile from other user', async(() => {

    mockService.confirmResponsibilities(RESPONSIBILITIES).subscribe(() => {
      mockService.content = []; // manipulate data for response
      responsibilityFixture.detectChanges();
      responsibilityFixture.whenStable().then(() => {
        let des: DebugElement[];
        des = responsibilityFixture.debugElement.queryAll(By.css('.alert-info'));
        expect(des.length).toBe(1);
      });
    });
  }));

  it('should not show banner info when confirmResponsibilities clicked' +
    ' but responsibilities changed meanwhile from other user', async(() => {

      responsibilityFixture.componentInstance.responsiblitySelection = RESPONSIBILITIES;


      mockService.confirmResponsibilities(RESPONSIBILITIES).subscribe(() => {
        responsibilityFixture.detectChanges();
        responsibilityFixture.whenStable().then(() => {
          responsibilityFixture.detectChanges();
          const des = responsibilityFixture.debugElement.queryAll(By.css('.alert-info'));

          expect(des.length).toBe(1);
        });
      });
    }));

  it('should be a modified model after checking the boxes', fakeAsync(() => {

    let elLocal: HTMLInputElement;
    const resps = RESPONSIBILITIES;
    resps[0].responsibilityList[0].isActive = true;
    resps[1].responsibilityList[0].isActive = true;
    resps[2].responsibilityList[2].isActive = true;
    mockService.content = resps;


    responsibilityFixture.detectChanges();
    responsibilityFixture.whenStable().then(() => {// wait for async getResponsibilities
      responsibilityFixture.detectChanges();       // update view with array

      // the 3 Flags from above should be "true" now... See test above
      // We are modifying them on the UI (DebugElement) and control the model thereafter
      let des: DebugElement[];
      des = responsibilityFixture.debugElement.queryAll(By.css('.responsibility-checkbox-wr'));
      elLocal = des[0].nativeElement;
      expect(elLocal.checked).toBe(true);
      elLocal.checked = false;
      elLocal.dispatchEvent(newEvent('change'));
      // should have been modified now
      expect(responsibilityFixture.componentInstance.responsiblitySelection[0].responsibilityList[1].isActive).toBe(false);

      des = responsibilityFixture.debugElement.queryAll(By.css('.responsibility-checkbox-er'));
      elLocal = des[1].nativeElement;
      expect(elLocal.checked).toBe(true);
      elLocal.checked = false;
      elLocal.dispatchEvent(newEvent('change'));
      // should have been modified now 
      expect(responsibilityFixture.componentInstance.responsiblitySelection[1].responsibilityList[0].isActive).toBe(false);

      des = responsibilityFixture.debugElement.queryAll(By.css('.responsibility-checkbox-dhr'));
      elLocal = des[2].nativeElement;
      expect(elLocal.checked).toBe(true);
      elLocal.checked = false;
      elLocal.dispatchEvent(newEvent('change'));
      // should have been modified now
      expect(responsibilityFixture.componentInstance.responsiblitySelection[2].responsibilityList[2].isActive).toBe(false);
    });
  }));

  it('should modify Responsibilities correctly after Btn selectAllResponsibilities', async(() => {

    const resps = RESPONSIBILITIES;
    mockService.content = resps;
    respPage = new ResponsilityPage();


    responsibilityFixture.detectChanges();

    responsibilityFixture.whenStable().then(() => { // wait for async getResponsibilities
      responsibilityFixture.detectChanges();        // update view with array
      respPage.addPageElements();

      click(respPage.selAllBtn);

      for (const respC of component.responsiblitySelection) {
        for (const resp of respC.responsibilityList) {

          expect(resp.isActive).toBe(true);
        }
      }
    });
  }));

  it('should modify Responsibilities correctly after Btn deselectAllResponsibilities', async(() => {

    const resps = RESPONSIBILITIES;
    mockService.content = resps;
    respPage = new ResponsilityPage();


    responsibilityFixture.detectChanges();

    responsibilityFixture.whenStable().then(() => { // wait for async getResponsibilities
      responsibilityFixture.detectChanges();        // update view with array
      respPage.addPageElements();

      click(respPage.deselAllBtn);

      for (const respC of component.responsiblitySelection) {
        for (const resp of respC.responsibilityList) {

          expect(resp.isActive).toBe(false);
        }
      }
    });
  }));

  it('should run correctly in setError ', async(() => {

    mockService.error = 'Connection Error';
    respPage = new ResponsilityPage();

    responsibilityFixture.detectChanges();

    responsibilityFixture.whenStable().then(() => { // wait for async getResponsibilities
      responsibilityFixture.detectChanges();        // update view with array
      respPage.addPageElements();
      // TODO: _fd 2017-05-04: Nothing to expect at the moment... 
      //  Later test, if the error was set correctly ... 
    });
  }));

  it('should map user name correctly', async(inject([SessionContext], (scontext: SessionContext) => {
    const inkognito: any = component;

    scontext.setAllUsers( null );
    expect( function() { inkognito.mapUserName('otto'); } ).toThrowError(EvalError);

    scontext.setAllUsers( USERS );
    expect(inkognito.mapUserName('unk')).toBe( '[unk]');
    expect(inkognito.mapUserName('otto')).toBe( 'Otto Normalverbraucher' );
  })));

});

class ResponsilityPage {
  //  gotoSpy:      jasmine.Spy;
  //  navSpy:       jasmine.Spy;

  selDefaultBtn: DebugElement;
  selAllBtn: DebugElement;
  deselAllBtn: DebugElement;
  confirmBtn: DebugElement;

  constructor() {
    /*    const router = TestBed.get(Router); // get router from root injector
        this.gotoSpy = spyOn(comp, 'gotoList').and.callThrough();
        this.navSpy  = spyOn(router, 'navigate');
        */
  }

  addPageElements() {

    // have a hero so these elements are now in the DOM
    const buttons = responsibilityFixture.debugElement.queryAll(By.css('button'));

    this.selAllBtn = buttons[0];
    this.deselAllBtn = buttons[1];


  }
}

