import { async, fakeAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { click } from '../../testing/index';
import { NgModule } from '@angular/core';
import { DebugElement, EventEmitter, SimpleChange } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MdDialogModule, MaterialModule, MdDialog, MdDialogConfig, Overlay, OverlayContainer, OVERLAY_PROVIDERS } from '@angular/material';
import { AbstractListComponent } from '../../lists/abstract-list/abstract-list.component';
import { AbstractMockObservableService } from '../../common/abstract-mock-observable.service';
import { MockComponent } from '../../testing/mock.component';
import { Router } from '@angular/router';
import { User } from '../../model/user';
import { LoginCredentials } from '../../model/login-credentials';
import { SessionContext } from '../../common/session-context';
import { FormattedTimestampPipe } from '../../common-components/pipes/formatted-timestamp.pipe';
import { StringToDatePipe } from '../../common-components/pipes/string-to-date.pipe';
import { DaterangepickerConfig } from 'ng2-daterangepicker';
import { NotificationService } from '../../services/notification.service';
import { ResponsibilityService } from '../../services/responsibility.service';
import { MessageService } from '../../services/message.service';
import { REMINDER_NOTIFICATIONS } from '../../test-data/reminder-notifications';
import { AppModule } from '../../app.module';
import { EntryComponent } from '../../dialogs/entry/entry.component';
import { MainNavigationComponent } from '../../common-components/main-navigation/main-navigation.component';
import { CurrentRemindersComponent } from '../../lists/current-reminders/current-reminders.component';
import { ReminderComponent } from './reminder.component';
import { ReminderSearchFilter } from '../../model/reminder-search-filter';
import { ReminderService } from '../../services/reminder.service';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ShiftChangeProtocolComponent } from '../../dialogs/shift-change-protocol/shift-change-protocol.component';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
import { FilterComponent } from '../../filter/filter.component';

class FakeRouter {
  navigate(commands: any[]) {
    return commands[0];
  }
}
@NgModule({
  declarations: [EntryComponent, ShiftChangeProtocolComponent],
  entryComponents: [
    EntryComponent, ShiftChangeProtocolComponent
  ]
})
class TestModule { }

describe('ReminderComponent', () => {
  const sessionContext: SessionContext = new SessionContext();
  let component: ReminderComponent;
  let fixture: ComponentFixture<ReminderComponent>;
  let router: Router;
  let mockNotificationService: MockNotificationService;
  let mockReminderService: MockReminderService;
  let mockRespService: MockResponsibilityService;
  let messageService;
  

  const correctUser: User = {
    id: 44, username: 'carlo', password: 'serverPwd'
    , name: 'Carlo Cottura', specialUser: true, itemName: this.userName
  };

  class MockResponsibilityService extends AbstractMockObservableService {
    plannedResponsibilities = null;
    responsibilities = null;

    getPlannedResponsibilities() {
      const resptService = new MockResponsibilityService();
      resptService.content = this.plannedResponsibilities;
      return resptService;
    };
    getResponsibilities() {
      const resptService = new MockResponsibilityService();
      resptService.content = this.responsibilities;
      return resptService;
    }
  }

  class MockReminderService extends AbstractMockObservableService {
    itemChanged$ = new EventEmitter();
    itemAdded$ = new EventEmitter();
    loadCalled = false;
    currentReminders = null;

    reminderSearchFilter: ReminderSearchFilter = {
      reminderDate: '2017-08-17 15:00', responsibilityFilterList: []
    };
        
    public getCurrentReminders(reminderSearchFilter) {
      this.loadCalled = true;
      const reminderService = new MockReminderService();
      reminderService.content = this.currentReminders;
      return reminderService;      
    };
  }

  class MockNotificationService extends AbstractMockObservableService {
    itemChanged$ = new EventEmitter();
    itemAdded$ = new EventEmitter();
    loadCalled = false;
    public getOpenNotifications(notificationType: string) {
      this.loadCalled = true;
      return this;
    };
  }

  class MockAuthService extends AbstractMockObservableService {

    login(creds: LoginCredentials) {
      return this;
    }
  }

  let mockAuthService;

  beforeEach(async(() => {
    messageService = new MessageService();
    mockRespService = new MockResponsibilityService();    
    mockReminderService = new MockReminderService();
    mockNotificationService = new MockNotificationService();
    mockAuthService = new MockAuthService();
    router = new FakeRouter() as any as Router;

    TestBed.overrideModule(BrowserDynamicTestingModule, {
      set: {
        entryComponents: [EntryComponent, ShiftChangeProtocolComponent]
      }
    });

    TestBed.configureTestingModule({
      imports: [
        FormsModule,
        MdDialogModule,
        BrowserAnimationsModule,
        MaterialModule.forRoot()],
      declarations: [
        ReminderComponent,        
        EntryComponent,
        ShiftChangeProtocolComponent,
        MainNavigationComponent,
        CurrentRemindersComponent,
        FormattedTimestampPipe,
        StringToDatePipe,
        MockComponent({ 
          selector: 'app-filter',
          inputs: [
            'shiftChangeProtocolConfirmed',
            'shiftChangeProtocolOpened',
            'filterExpanded'
          ]
        }),
        MockComponent({ selector: 'app-loading-spinner' }),
        MockComponent({ selector: 'app-entry' }),
        MockComponent({ selector: 'input', inputs: ['options'] }),
        MockComponent({
          selector: 'app-reminder',
          inputs: [
            'withCheckboxes', 'withEditButtons', 'isCollapsible'
          ]
        }),
        MockComponent({
          selector: 'app-responsibility', inputs: [
            'responsiblitySelection']
        }),
        MockComponent({
          selector: 'app-sorting', inputs: ['columnName', 'initColumnName', 'isDesc', 'defaultState']
        }),
        MockComponent({
          selector: 'app-autocomplete',
          inputs: ['responsibilityForwarding'],
          outputs: ['responsibilityForwarding']
        }),
        MockComponent({
          selector: 'app-abstract-list', inputs: [
            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId']
        }),
        MockComponent({
          selector: 'app-finished-notifications', inputs: [ 'responsiblitySelection',
            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId']
        }),
        MockComponent({
          selector: 'app-open-notifications', inputs: [ 'responsiblitySelection',
            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId']
        }),
        MockComponent({
          selector: 'app-future-notifications', inputs: [ 'responsiblitySelection',
            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId']
        }),
        MockComponent({
          selector: 'app-message-banner'
        })
      ],
      providers: [
        { provide: Router, useValue: router },
        { provide: SessionContext, useValue: sessionContext },
        { provide: DaterangepickerConfig, useClass: DaterangepickerConfig },
        { provide: Overlay, useClass: Overlay },
        { provide: OVERLAY_PROVIDERS, useClass: OVERLAY_PROVIDERS },
        { provide: ReminderService, useClass: ReminderService },
        { provide: ResponsibilityService, useValue: mockRespService },
        { provide: MessageService, useValue: messageService },
        { provide: NotificationService, useValue: mockNotificationService }
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ReminderComponent);
    component = fixture.componentInstance;
    //fixture.detectChanges();
  });

  it('should init correctly with correct user', async(() => {
    sessionContext.setCurrUser(correctUser);
    
    mockReminderService.currentReminders = [];
    fixture.detectChanges();
    expect(component.user.id).toBe(correctUser.id);
  }));

  it('should open a dialog to edit a notification on button click', async(() => {
    
    let entryOpend = false;
    let dialog;
    const testNotification = REMINDER_NOTIFICATIONS[0];
    
    sessionContext.setCurrUser(correctUser);
    
    fixture.detectChanges();

    component.dialog.afterOpen.subscribe((value) => {
      dialog = value.componentInstance;
      spyOn(dialog, 'setNotification');  
      entryOpend = true;
    });
    component.openDialogEditEntry(testNotification);

    fixture.whenStable().then(() => {
      fixture.detectChanges();    
      expect(entryOpend).toBe(true);
      expect(dialog.isEditDialog).toBe(true);
    
    });
  }));

  it('should open a dialog to view a notification on button click', async(() => {
    
    let entryOpend = false;
    let dialog;
    const testNotification = REMINDER_NOTIFICATIONS[0];
    
    sessionContext.setCurrUser(correctUser);
    
    fixture.detectChanges();

    component.dialog.afterOpen.subscribe((value) => {
      dialog = value.componentInstance;
      spyOn(dialog, 'setNotification');  
      entryOpend = true;
    });
    component.openDialogLookUpEntry(testNotification);

    fixture.whenStable().then(() => {
      fixture.detectChanges();    
      expect(entryOpend).toBe(true);
      expect(dialog.isEditDialog).toBe(false);
    
    });
  }));
});
