/*
 * Copyright (C) 2018 Robert Bosch GmbH Copyright (C) 2018 Robert Bosch Manufacturing Solutions GmbH, Germany. All rights reserved.
 */

import { Component, NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MatTabGroup } from '@angular/material/tabs';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ModalWindowService } from '@bci-web-core/core';
import { CatalogConf } from '../models/catalog-conf';
import { PinboardConfig } from '../models/pinboard-config';
import { WidgetDefinition } from '../models/widget-definition';
import { PinboardModule } from '../pinboard.module';
import { CategoryService } from '../services/category.service';
import { WidgetDefinitionService } from '../services/widget-definition.service';
import { TestTextContentComponent, TestTextWidgetUserSetting } from '../widget/test-text-widget-component';
import { PinboardComponent } from './pinboard.component';

@Component({
  selector: 'bci-test-pinboard-cmp',
  template: ` <bci-pinboard>
    <bci-widget-settings></bci-widget-settings>
    <bci-widget-catalog></bci-widget-catalog>
    <bci-pinboard-grid></bci-pinboard-grid>
  </bci-pinboard>`,
})
class TestWrapperComponent {}

describe('PinboardComponent', () => {
  let component: PinboardComponent;
  let fixture: ComponentFixture<TestWrapperComponent>;
  let widgetDefinitionService: WidgetDefinitionService;

  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        imports: [NoopAnimationsModule, PinboardModule, FormsModule],
        providers: [
          WidgetDefinitionService,
          ModalWindowService,
          CategoryService,
          { provide: MAT_DIALOG_DATA, useValue: {} },
          { provide: MatDialogRef, useValue: {} },
          { provide: MatTabGroup, useValue: {} },
        ],
        declarations: [TestWrapperComponent],
        schemas: [NO_ERRORS_SCHEMA],
      }).compileComponents();

      widgetDefinitionService = TestBed.inject(WidgetDefinitionService);
    })
  );

  beforeEach(() => {
    fixture = TestBed.createComponent(TestWrapperComponent);
    component = fixture.debugElement.children[0].componentInstance;
    component.dashboards = [
      { id: 'foo', label: 'Dashboard 1', priority: 0, settings: [] },
      { id: 'bar', label: 'Dashboard 2', priority: 1, settings: [] },
    ];
    component.activeDashboard = component.dashboards[0];
    component.openDashboard(0);
    component.tabGroup = MatTabGroup.prototype;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('#defineWidget should add WidgetDefinitions', () => {
    const def = new WidgetDefinition<TestTextContentComponent, TestTextWidgetUserSetting, any>(
      '12',
      {} as CatalogConf,
      'TextWidget'
    );
    component.defineWidget(def);
    const defFromService = widgetDefinitionService.getWidgetDefinitions('12')[0];
    expect(defFromService).toBe(def);
  });

  it('#getDefinedWidgets should return all defined WidgetDefinitions', () => {
    const def = new WidgetDefinition<TestTextContentComponent, TestTextWidgetUserSetting, any>(
      '12',
      {} as CatalogConf,
      'TextWidget'
    );
    const def1 = new WidgetDefinition<TestTextContentComponent, TestTextWidgetUserSetting, any>(
      '13',
      {} as CatalogConf,
      'TextWidget'
    );
    component.defineWidget(def);
    component.defineWidget(def1);
    const defarr = [def, def1];
    const defarr1 = component.getDefinedWidgets();
    expect(defarr1).toEqual(defarr);
  });

  it('#exportPinboardConfig should return a valid PinboardConfig', () => {
    const def = new WidgetDefinition<TestTextContentComponent, TestTextWidgetUserSetting, any>(
      '12',
      {} as CatalogConf,
      'TextWidget'
    );
    component.defineWidget(def);
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    const gridComponent = component.pinboardGridComponent;
    gridComponent.addWidgetToGrid(def);
    const pinboardConfig = component.exportPinboardConfig('', '');
    // Can't compare copied object, so we only compare length
    expect(pinboardConfig.settings.length).toBe(gridComponent.getWidgets().length);
  });

  it('#loadPinboardConfig should add Widgets to grid', () => {
    const def = new WidgetDefinition<TestTextContentComponent, TestTextWidgetUserSetting, any>(
      '12',
      {} as CatalogConf,
      'TextWidget'
    );
    component.defineWidget(def);
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    const gridComponent = component.pinboardGridComponent;
    const widget = gridComponent.addWidgetToGrid(def);
    const pinboardConfig = {} as PinboardConfig;
    pinboardConfig.settings = [];
    pinboardConfig.settings.push(widget);

    component.loadPinboardConfig(pinboardConfig);

    expect(pinboardConfig.settings).toEqual(gridComponent.getWidgets());
  });

  it('#openDashboard should emit an event to open the specified dashboard', () => {
    component.openDashboard(1);
    expect(component.activeDashboard.id).toEqual(component.dashboards[1].id);

    component.dashboardOpened.subscribe((res: PinboardConfig) => {
      expect(res.id).toEqual(component.activeDashboard.id);
    });
  });
});
