/* 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 } from '@angular/core';
import { click, newEvent } from '../../testing';
import { DaterangepickerConfig, Daterangepicker } from 'ng2-daterangepicker';
import { AbstractMockObservableService } from '../../common/abstract-mock-observable.service';
import { MockComponent } from '../../testing/mock.component';
import { MdDialogRef } from '@angular/material';
import { EntryComponent } from './entry.component';
import { USERS } from '../../test-data/users';
import { NotificationService } from '../../services/notification.service';
import { StringToDatePipe } from '../../common-components/pipes/string-to-date.pipe';
import { FormattedTimestampPipe } from '../../common-components/pipes/formatted-timestamp.pipe';
import { Globals } from '../../common/globals';
import { SessionContext } from '../../common/session-context';
import { CURRENT_NOTIFICATIONS, FINISHED_NOTIFICATIONS, OPEN_NOTIFICATIONS, NOTIFICATION_VERSIONS } from '../../test-data/notifications';
import { Notification } from '../../model/notification';
import { StatusEn } from '../../common/enums';
import { STATUSES } from '../../test-data/statuses';
import { BRANCHES } from '../../test-data/branches';
import { GRIDTERRITORIES } from '../../test-data/gridterritories';
import { FilterMatrix } from '../../model/controller-model/filter-matrix';
import { FILTER_MATRIX_NONE_SELECTED } from '../../test-data/filter-matrix';
import { FILTER_MATRIX_UNIQUE_BRANCH } from '../../test-data/filter-matrix';
import { FILTER_MATRIX_UNIQUE_GRIDTERRITORY } from '../../test-data/filter-matrix';

import { MessageService } from '../../services/message.service';
describe('EntryComponent', () => {
let component: EntryComponent;
let fixture: ComponentFixture<EntryComponent>;
  let sessionContext: SessionContext;

  class MockDialogRef extends AbstractMockObservableService {
    close() { }
  }

  class MockNotificationService extends AbstractMockObservableService {

    createNotification(newNotification) {
      this.content = newNotification;
      return this;
    };

    updateNotification(updatedNotification) {
      this.content = updatedNotification;
      return this;
    };

    getNotificationVersions(incidentId: number) {
      return this;
    }
  }
  let mockNotificationService;
  let messageService;

  beforeEach(async(() => {
    messageService = new MessageService();
    sessionContext = new SessionContext();
    sessionContext.setBranches(BRANCHES);
    sessionContext.setGridTerritories(GRIDTERRITORIES);
    sessionContext.setfilterMatrix(FILTER_MATRIX_NONE_SELECTED);
    mockNotificationService = new MockNotificationService();

    TestBed.configureTestingModule({
      imports: [FormsModule],
      declarations: [
        EntryComponent,
        StringToDatePipe,
        FormattedTimestampPipe,
        MockComponent({ selector: 'input', inputs: ['options'] }),
        MockComponent({
          selector: 'app-autocomplete',
          inputs: ['responsibilityForwarding'],
          outputs: ['responsibilityForwarding']
        })
      ],
      providers: [
        { provide: MdDialogRef, useClass: MockDialogRef },
        { provide: NotificationService, useValue: mockNotificationService },
        { provide: SessionContext, useClass: SessionContext },
        { provide: MessageService, useValue: messageService },
        DaterangepickerConfig,
        Daterangepicker
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(EntryComponent);
    component = fixture.componentInstance;
    component.user = USERS[1];
    component.sessionContext.setCurrUser(USERS[1]);
    component.sessionContext.setBranches(BRANCHES);
    component.sessionContext.setGridTerritories(GRIDTERRITORIES);
    component.sessionContext.setfilterMatrix(FILTER_MATRIX_NONE_SELECTED);
    component.branches = BRANCHES;
    component.gridTerritories = GRIDTERRITORIES;
  });

  it('should change the Version and set the according notification', async(() => {    
    component.notificationVersions = NOTIFICATION_VERSIONS;
    component.notification = NOTIFICATION_VERSIONS[0];
    component.isReadOnlyDialog = true;
    fixture.detectChanges();

    fixture.whenStable().then(() => {
      fixture.detectChanges();      
      const select = fixture.debugElement.query(By.css('select[name=notificationSelection]'));      
      select.nativeElement.value = '3';      
      select.nativeElement.dispatchEvent(newEvent('change'));
      fixture.detectChanges();

      fixture.whenStable().then(() => {
        fixture.detectChanges();
        expect(component.notification.version).toBe(NOTIFICATION_VERSIONS[2].version);              
      });

    });          
  }));

  it('should call statusChanged on changing the status (inWork)', async(() => {        
    spyOn(component, 'statusChanged').and.callThrough();
    component.sessionContext.setStatuses(STATUSES);
    const currNotification: Notification = NOTIFICATION_VERSIONS[0];    
    component.notification = currNotification;        
    fixture.detectChanges();

    fixture.whenStable().then(() => {
      expect(component.notification.fkRefNotificationStatus).toBe(NOTIFICATION_VERSIONS[0].fkRefNotificationStatus);                    
  
      const select = fixture.debugElement.query(By.css('select[name=statusSelection]'));    
      select.nativeElement.value = StatusEn.inWork;
      select.nativeElement.dispatchEvent(newEvent('change'));
      fixture.detectChanges();

      fixture.whenStable().then(() => {
        expect(component.statusChanged).toHaveBeenCalledWith(StatusEn.inWork.toString(), currNotification);             
      });

    });          
  }));

  it('should call statusChanged on changing the status (done)', async(() => {        
    spyOn(component, 'statusChanged').and.callThrough();
    component.sessionContext.setStatuses(STATUSES);
    const currNotification: Notification = NOTIFICATION_VERSIONS[0];    
    component.notification = currNotification;        
    fixture.detectChanges();

    fixture.whenStable().then(() => {
      expect(component.notification.fkRefNotificationStatus).toBe(NOTIFICATION_VERSIONS[0].fkRefNotificationStatus);                    
  
      const select = fixture.debugElement.query(By.css('select[name=statusSelection]'));    
      select.nativeElement.value = StatusEn.done;
      select.nativeElement.dispatchEvent(newEvent('change'));
      fixture.detectChanges();

      fixture.whenStable().then(() => {
        expect(component.statusChanged).toHaveBeenCalledWith(StatusEn.done.toString(), currNotification);             
      });

    });          
  }));

  it('should call setNotification service methode and return an error', async(() => {
    const currNotification: Notification = OPEN_NOTIFICATIONS[0];
    currNotification.beginDate = '';
    mockNotificationService.error = 'SETNOTIFICATION_ERROR';
    component.isReadOnlyDialog = true;
    fixture.detectChanges();
    mockNotificationService.getNotificationVersions(currNotification.id).subscribe((resp) => {

      fixture.whenStable().then(() => {
        fixture.detectChanges();
        expect(component.notification.id).toBe(currNotification.id);
        expect(component.notificationVersions.length).toBe(OPEN_NOTIFICATIONS.length);
        expect(component.sessionContext.bannerMessage.text).toEqual('Fehler beim Lesen der Versionen von der Datenbank.');
      });
    });

    component.setNotification(currNotification);
    fixture.detectChanges();

  }));

  it('should call setNotification service methode and set right notificationVersions', async(() => {
    const currNotification: Notification = OPEN_NOTIFICATIONS[0];
    mockNotificationService.content = OPEN_NOTIFICATIONS;
    component.isReadOnlyDialog = true;
    fixture.detectChanges();
    mockNotificationService.getNotificationVersions(currNotification.id).subscribe((resp) => {

      fixture.whenStable().then(() => {
        fixture.detectChanges();
        expect(component.notification.id).toBe(currNotification.id);
        expect(component.notificationVersions.length).toBe(OPEN_NOTIFICATIONS.length);
      });
    });

    component.setNotification(currNotification);
    fixture.detectChanges();

  }));

  it('should call getNotificationVersions service methode and set current user as create user', async(() => {
    const currNotification = FINISHED_NOTIFICATIONS[0];
    currNotification.createUser = '';
    mockNotificationService.content = FINISHED_NOTIFICATIONS;
    component.isReadOnlyDialog = true;

    mockNotificationService.getNotificationVersions(currNotification.id).subscribe((resp) => {
      component.notificationVersions = resp;
      fixture.whenStable().then(() => {

        fixture.detectChanges();
        const des = fixture.debugElement.queryAll(By.css('.nvo'));
        expect(des.length).toBe(FINISHED_NOTIFICATIONS.length);
      });
    });
  }));

  it('InstructionDialog: only statusSelection should be reuqired on instructionDialog', async(() => {
    component.isInstructionDialog = true;
    fixture.detectChanges();

    let de = fixture.debugElement.query(By.css('.form-control[name=statusSelection]'));
    expect(de.nativeElement.required).toBe(true);

    de = fixture.debugElement.query(By.css('.form-control[name=gridTerritorySelection]'));
    expect(de.nativeElement.required).toBe(false);

    de = fixture.debugElement.query(By.css('.form-control[name=branchSelection]'));
    expect(de.nativeElement.required).toBe(false);

  }));

  it('InstructionDialog: should call add on click button "Hinzufügen"', async(() => {
    spyOn(component, 'add').and.callThrough();
    component.isInstructionDialog = true;
    fixture.detectChanges();

    component.notification.notificationText = 'TestContent';
    component.notification.fkRefNotificationStatus = 1;
    fixture.detectChanges();

    const de = fixture.debugElement.query(By.css('.btn-success'));
    click(de);

    fixture.whenStable().then(() => {
      expect(component.notification.responsibilityControlPoint).toBe(USERS[1].name);
      expect(component.notification.adminFlag).toBe(true);
    });
  }));

  it('should call add on click button "Hinzufügen" and return an error', async(() => {
    let hasBeenCalled = false;
    spyOn(component, 'add').and.callThrough();
    component.isInstructionDialog = true;
    mockNotificationService.error = 'ADD_CLICK_ERROR';

    component.notification.notificationText = 'TestContentChanged';
    component.notification.fkRefNotificationStatus = 1;

    messageService.errorOccured$.subscribe( msg => hasBeenCalled = true);
    fixture.detectChanges();

    const de = fixture.debugElement.query(By.css('.btn-success'));
    click(de);

    fixture.whenStable().then(() => {
      expect(component.add).toHaveBeenCalled();
      expect(hasBeenCalled).toBeTruthy();
    });
  }));

  it('should call edit on click button "Ändern"', async(() => {
    spyOn(component, 'edit').and.callThrough();
    component.isInstructionDialog = true;
    component.isEditDialog = true;
    component.notification = OPEN_NOTIFICATIONS[0];
    fixture.detectChanges();

    component.notification.notificationText = 'TestContentChanged';
    component.notification.fkRefNotificationStatus = 1;
    fixture.detectChanges();

    const de = fixture.debugElement.query(By.css('.btn-success'));
    click(de);

    fixture.whenStable().then(() => {
      expect(component.edit).toHaveBeenCalled();
    });
  }));

  it('should call edit on click button "Ändern" and return an error', async(() => {
    let hasBeenCalled = false;
    spyOn(component, 'edit').and.callThrough();
    component.isInstructionDialog = true;
    component.isEditDialog = true;
    mockNotificationService.error = 'EDIT_CLICK_ERROR';

    component.notification.notificationText = 'TestContentChanged';
    component.notification.fkRefNotificationStatus = 1;
    messageService.errorOccured$.subscribe( msg => hasBeenCalled = true);    
    fixture.detectChanges();

    const de = fixture.debugElement.query(By.css('.btn-success'));
    click(de);

    fixture.whenStable().then(() => {
      expect(component.edit).toHaveBeenCalled();
      expect(hasBeenCalled).toBeTruthy();
    });
  }));

  it('close dialog on cancel', async(() => {
    spyOn(component, 'cancel').and.callThrough();
    component.isInstructionDialog = true;
    fixture.detectChanges();

    const de = fixture.debugElement.query(By.css('button:nth-child(2)'));
    click(de);

    fixture.whenStable().then(() => {
      expect(component.cancel).toHaveBeenCalled();
    });
  }));

  it('should return an emty branch name for a given user if it is not unique', () => {
    let returnBranchName = '';
    returnBranchName = component.getUniqueBranchNameForUser(FILTER_MATRIX_NONE_SELECTED.responsibilityContainerMatrix, 'max');

    expect(returnBranchName).toBe('');
});

  it('should return a branch name for a given user if it is unique', () => {
    component.sessionContext.setGridTerritories(GRIDTERRITORIES);
    let returnBranchName = '';
    let returnBranchName2 = '';

    returnBranchName = component.getUniqueBranchNameForUser(FILTER_MATRIX_UNIQUE_BRANCH.responsibilityContainerMatrix, 'max');
    returnBranchName2 = component.getUniqueBranchNameForUser(FILTER_MATRIX_UNIQUE_BRANCH.responsibilityContainerMatrix, 'pete');
    expect(returnBranchName).toBe('S');
    expect(returnBranchName2).toBe('F');

  });

  it('should return an emty gridterritory name for a given user if it is not unique', () => {
    component.sessionContext.setGridTerritories(GRIDTERRITORIES);
    let returnGridTerritoryName = '';

    returnGridTerritoryName = component.getUniqueBranchNameForUser(FILTER_MATRIX_NONE_SELECTED.responsibilityContainerMatrix, 'max');
    expect(returnGridTerritoryName).toBe('');
  });

  it('should return a gridterritory name for a given user if it is unique', () => {
    component.sessionContext.setGridTerritories(GRIDTERRITORIES);

    let returnGridTerritoryName = '';
    let returnGridTerritoryName2 = '';
    let returnGridTerritoryName3 = '';

    returnGridTerritoryName = component.getUniqueGridTerritoryNameForUser(
      FILTER_MATRIX_UNIQUE_GRIDTERRITORY.responsibilityContainerMatrix, 'max');
    expect(returnGridTerritoryName).toBe('Mannheim');

    returnGridTerritoryName2 = component.getUniqueGridTerritoryNameForUser(
      FILTER_MATRIX_UNIQUE_GRIDTERRITORY.responsibilityContainerMatrix, 'pete');
    expect(returnGridTerritoryName2).toBe('Kassel');

    returnGridTerritoryName3 = component.getUniqueGridTerritoryNameForUser(
      FILTER_MATRIX_UNIQUE_GRIDTERRITORY.responsibilityContainerMatrix, 'otto');
    expect(returnGridTerritoryName3).toBe('Offenbach 1');
  });

});
