/* tslint:disable:no-unused-variable */
import { FormsModule } from '@angular/forms';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { AbstractMockObservableService } from '../../common/abstract-mock-observable.service';
import { click } from '../../testing';
import { MockComponent } from '../../testing/mock.component';
import { MdDialogRef } from '@angular/material';
import { ShiftChangeComponent } from './shift-change.component';
import { TerritoryResponsibility } from '../../model/territory-responsibility';
import { UserService } from '../../services/user.service';
import { ResponsibilityService } from '../../services/responsibility.service';
import { SessionContext } from '../../common/session-context';
import { RESPONSIBILITIES } from '../../test-data/responsibilities';
import { RESPONSIBILITIES_SHIFT_CHANGE } from '../../test-data/responsibilities';
import { USERS } from '../../test-data/users';
import { AngularMultiSelectComponent } from '../../common-components/multiselect-dropdown/multiselect.component';
import { MessageService } from '../../services/message.service';

let component: ShiftChangeComponent;
let fixture: ComponentFixture<ShiftChangeComponent>;
let page: Page;

describe('ShiftChangeComponent', () => {

  class MockDialogRef extends AbstractMockObservableService {
    close() { }
  }

  class MockUserService extends AbstractMockObservableService {
    getUsers() {
      return this;
    };
  }
  let mockUserService: MockUserService;

  class MockResponsibilityService extends AbstractMockObservableService {
    getResponsibilities() {
      return this;
    };
    planResponsibilities(newResponsibility: TerritoryResponsibility[]) {
      return this;
    };
  }
  let mockService: MockResponsibilityService;
  let sessionContext: SessionContext;
  let messageService: MessageService;

  beforeEach(async(() => {
    mockUserService = new MockUserService();
    mockService = new MockResponsibilityService();
    sessionContext = new SessionContext();
    messageService = new MessageService();

    TestBed.configureTestingModule({
      imports: [FormsModule],
      declarations: [ShiftChangeComponent,
        MockComponent({ selector: 'multiselect', inputs: ['data', 'settings'] })
      ],
      providers: [
      { provide: MdDialogRef, useClass: MockDialogRef },
      { provide: UserService, useValue: mockUserService },
      { provide: ResponsibilityService, useValue: mockService },
      { provide: MessageService, useValue: messageService },      
      { provide: SessionContext, useValue: sessionContext }],
    }).compileComponents();


    fixture = TestBed.createComponent(ShiftChangeComponent);
    component = fixture.componentInstance;
  }));
  it('should show banner info when confirmResponsibilities clicked but responsibilities changed meanwhile from other user', async(() => {
    let hasBeenCalled = false;
    messageService.errorOccured$.subscribe( msg => hasBeenCalled = true);
    fixture.componentInstance.responsibilityContainers = RESPONSIBILITIES;
    page = new Page();
    page.addPageElements();
    mockService.subscribe(null, null, () => {
      mockService.content = [];
      fixture.detectChanges();
      fixture.whenStable().then(() => {
        fixture.detectChanges();
        expect(hasBeenCalled).toBeTruthy();
      });
    });
    click(page.confirmBtn);

  }));


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

      fixture.componentInstance.responsibilityContainers = RESPONSIBILITIES;
      page = new Page();
      page.addPageElements();

      mockService.subscribe(null, null, () => {
        fixture.detectChanges();
        fixture.whenStable().then(() => {
          fixture.detectChanges();
          let des: DebugElement[];
          des = fixture.debugElement.queryAll(By.css('.alert-info'));

          expect(des.length).toBe(0);
        });
      });
      click(page.confirmBtn);
    }));

  it('selectboxes should be preselected', async(() => {
    const resp = RESPONSIBILITIES;
    const testUser = USERS[0];
    resp.forEach(responsibilityContainer => {
      responsibilityContainer.responsibilityList.forEach(responsibility => {
        responsibility.newResponsibleUser = testUser.username;
      });
    });

    fixture.componentInstance.preSelectedUsers = USERS;
    fixture.componentInstance.responsibilityContainers = resp;
    page = new Page();
    page.addPageElements();

    let elLocal: HTMLSelectElement;
    fixture.detectChanges();
    fixture.whenStable().then(() => {

      let des: DebugElement[];
      des = fixture.debugElement.queryAll(By.css('.shc-table-select'));

      des.forEach(de => {
        elLocal = de.nativeElement;

        const option = elLocal.options[elLocal.options.selectedIndex];
        expect(option.textContent).toBe(testUser.name);
      });
    });
  }));

  it('selectboxes should be set to empty option after cancle click', async(() => {
    const resp = RESPONSIBILITIES;
    const testUser = USERS[0];
    resp.forEach(responsibilityContainer => {
      responsibilityContainer.responsibilityList.forEach(responsibility => {
        responsibility.newResponsibleUser = testUser.username;
      });
    });

    fixture.componentInstance.preSelectedUsers = USERS;
    fixture.componentInstance.responsibilityContainers = resp;
    page = new Page();
    page.addPageElements();

    let elLocal: HTMLSelectElement;

    click(page.stornoBtn);
    fixture.detectChanges();
    fixture.whenStable().then(() => {

      let des: DebugElement[];
      des = fixture.debugElement.queryAll(By.css('.shc-table-select'));

      des.forEach(de => {
        elLocal = de.nativeElement;

        const option = elLocal.options[elLocal.options.selectedIndex];
        expect(elLocal.options.selectedIndex).toBe(0);
      });
    });
  }));

  it('should show Responsibilities as selectBox in Table after getResponsibilities', async(() => {
    const resps = RESPONSIBILITIES;
    mockService.content = resps;
    
    component.afterUsersLoaded();

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

      let des: DebugElement[];
      des = fixture.debugElement.queryAll(By.css('.shc-table-select'));
      expect(des.length).toBe(12);
    });
  }));

  it('should call service on "getUsers" and work correctly in this multitest', async(() => {
    const serviceUsers = USERS;
    mockUserService.content = serviceUsers;
    const serviceResp = RESPONSIBILITIES;
    mockService.content = serviceResp;
    sessionContext.setCurrUser(USERS[1]); // admin is logged in

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

      // let des: DebugElement[];
      // des = fixture.debugElement.queryAll( By.css('.user-cb-test'));
      // expect( des.length ).toBe(2); // 2 checkboxes
      // expect( component.noUserSelected ).toBe( true );

      // click(des[1].nativeElement
      // expect( component.noUserSelected ).toBe( false );


    });
  }));

  it('should call getResponsibilities service method and return an error', async(() => {
    mockService.error = 'GETRESPONSIBILITIES_ERROR';
    fixture.detectChanges();
    mockService.getResponsibilities().subscribe((resp) => {
      fixture.whenStable().then(() => {
        fixture.detectChanges();
        expect(component.bannerMessage.text).toEqual('Schichtübergabe getResponsibilities');       
      });
    });

    component.getResponsibilities();
    fixture.detectChanges();

  }));

  it('should call planResponsibilities service method and return an error', async(() => {
    spyOn(component.dialogRef, 'close').and.callThrough();
    mockService.error = 'PLANRESPONSIBILITIES_ERROR';
    const responsibilityContainers = RESPONSIBILITIES_SHIFT_CHANGE;
    const serviceUsers = USERS;
    mockUserService.content = serviceUsers;
    const serviceResp = RESPONSIBILITIES;
    mockService.content = serviceResp;
    sessionContext.setCurrUser(USERS[1]);

    fixture.detectChanges();
    mockService.planResponsibilities(responsibilityContainers).subscribe((resp) => {
      fixture.whenStable().then(() => {
        fixture.detectChanges();
        expect(component.bannerMessage.text).toEqual('Schichtübergabe');
        expect(component.dialogRef.close).toHaveBeenCalled();
      });
    });

    component.shiftChange();
    fixture.detectChanges();

  }));
    
  it('should call getUsers service method and return an error', async(() => {
    mockUserService.error = 'GETUSERS_ERROR';
    fixture.detectChanges();
    mockUserService.getUsers().subscribe((resp) => {
      fixture.whenStable().then(() => {
        fixture.detectChanges();
        expect(component.bannerMessage.text).toEqual('Schichtübergabe getUsers');
      });
    });

    component.getUsers();
    fixture.detectChanges();

  }));
});
class Page {
  //  gotoSpy:      jasmine.Spy;
  //  navSpy:       jasmine.Spy;

  cancelBtn: DebugElement;
  stornoBtn: 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 = fixture.debugElement.queryAll(By.css('button'));

    this.cancelBtn = buttons[2];
    this.stornoBtn = buttons[1];
    this.confirmBtn = buttons[0];

  }
}