/**
******************************************************************************
* 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, fakeAsync, ComponentFixture, TestBed, tick, inject } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Injectable, DebugElement, Component } 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';


export class EntryComponentMocker {
  public static getComponentMocks() {
    return [
      MockComponent({ selector: 'app-entry' }),      
      MockComponent({ selector: 'app-remove-button', inputs: ['nullableAttribute'], outputs: ['nullableAttribute'] }),
      MockComponent({
        selector: 'app-autocomplete',
        inputs: ['notification'],
        outputs: ['notification']
      }),
    ];

  }
}

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: ['notification'],
          outputs: ['notification']
        }),
        MockComponent({ 
          selector: 'app-remove-button',
          inputs: ['nullableAttribute'],
          outputs: ['nullableAttribute']
        })
      ],
      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');
  });

});
