/**
******************************************************************************
* Copyright © 2017-2018 PTA GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* 
*     http://www.eclipse.org/legal/epl-v10.html
* 
******************************************************************************
*/
/* 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-Post/Plan', () => {

  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;
    fixture.detectChanges();
    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;
    fixture.detectChanges();
    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(15);
    });
  }));

  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(true);
    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();

  }));

});

describe('ShiftChangeComponent-Fetch', () => {

  class MockDialogRef extends AbstractMockObservableService {
    close() { }
  }

  class MockUserService extends AbstractMockObservableService {
    getUsers() {
      return this;
    };
  }  
  
  class MockResponsibilityService extends AbstractMockObservableService {
    public fetchCalled = false;
    getAllResponsibilities() {
      return this;
    };
    fetchResponsibilities(newResponsibility: TerritoryResponsibility[]) {
      this.fetchCalled = true;
      return this;
    };
  }
  let mockService: MockResponsibilityService;
  let sessionContext: SessionContext;
  let messageService: MessageService;
  let mockUserService: MockUserService;

  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;
    component.isFetchingResp = true;
  }));
  it('should init for fetch correctly', async(() => {
    sessionContext.setAllUsers(USERS);
    sessionContext.setCurrUser(USERS[1]);

    mockService.content = RESPONSIBILITIES;
    mockService.fetchCalled = false;
    fixture.detectChanges();
    page = new Page();
    page.addPageElements();
    mockService.subscribe(null, null, () => {
      mockService.content = [];
      fixture.detectChanges();
      fixture.whenStable().then(() => {
        fixture.detectChanges();
        expect(mockService.fetchCalled).toBeTruthy();
      });
    });
    click(page.confirmBtn);
  }));
});



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];

  }
}