/*
 * Copyright (C) 2018 Robert Bosch GmbH Copyright (C) 2018 Robert Bosch Manufacturing Solutions GmbH, Germany. All rights reserved.
 */
/* eslint-disable @typescript-eslint/no-empty-function */

import { SimpleChange } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { CatalogConf } from '../models/catalog-conf';
import { Widget } from '../models/widget';
import { WidgetContentComponent } from '../models/widget-content-component';
import { WidgetDefinition } from '../models/widget-definition';
import { PinboardModule } from '../pinboard.module';
import { WidgetDefinitionService } from '../services/widget-definition.service';
import { TestTextWidgetUserSetting } from '../widget/test-text-widget-component';
import { PinboardGridComponent } from './pinboard-grid.component';

describe('PinboardGridComponent', () => {
  let component: PinboardGridComponent;
  let fixture: ComponentFixture<PinboardGridComponent>;
  let widgetDefService: WidgetDefinitionService;
  let w1: Widget;
  let def1: WidgetDefinition<WidgetContentComponent, TestTextWidgetUserSetting, any>;
  let def2: WidgetDefinition<WidgetContentComponent, TestTextWidgetUserSetting, any>;

  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        imports: [NoopAnimationsModule, PinboardModule],
        providers: [WidgetDefinitionService],
      }).compileComponents();

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

  beforeEach(() => {
    fixture = TestBed.createComponent(PinboardGridComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();

    def1 = new WidgetDefinition<WidgetContentComponent, TestTextWidgetUserSetting, any>(
      '11',
      {} as CatalogConf,
      'TextWidget'
    );
    def2 = new WidgetDefinition<WidgetContentComponent, TestTextWidgetUserSetting, any>(
      '12',
      {} as CatalogConf,
      'TextWidget'
    );
    w1 = new Widget('22');
    w1.widgetDefinition = def1;
    widgetDefService.defineWidget(def1);
    widgetDefService.defineWidget(def2);
  });

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

  it('#checkForWidgetCollision should autoposition overlapping widgets', () => {
    // mock gridster api
    component.gridsterOptions.api = {
      optionsChanged: () => {},
      getNextPossiblePosition: () => {
        return true;
      },
    };

    jest.spyOn(component.gridsterOptions.api, 'getNextPossiblePosition').mockImplementation(() => {
      return true;
    });

    jest.spyOn(component.gridsterOptions.api, 'optionsChanged').mockImplementation(() => {});

    const widget1 = component.addWidgetToGrid(def1);
    const widget2 = component.addWidgetToGrid(def2);

    widget1.gridsterItem.x = 0;
    widget1.gridsterItem.y = 0;

    widget2.gridsterItem.x = 0;
    widget2.gridsterItem.y = 0;

    expect(component.checkForWidgetCollision(widget1)).toBeTruthy();
  });

  it('#addWidget and #getWidgets should add and get widgets to the grid', () => {
    const initLength = component.getWidgets().length;
    component.addWidgetToGrid(def1);
    expect(component.getWidgets().length).toEqual(initLength + 1);
  });

  it('#setGridWidgets should set widgets on the grid', () => {
    const widget1 = component.addWidgetToGrid(def1);
    const widget2 = component.addWidgetToGrid(def2);
    const w = [widget1, widget2];
    component.setGridWidgets(w);
    expect(component.getWidgets()).toEqual(w);
  });

  it('#removeWidget should remove widgets from grid', () => {
    component.addWidgetToGrid(def1);
    component.removeWidget(w1);
    expect(component.getWidgets()).toEqual([]);
  });

  it('should deep compare filter object onchange', () => {
    const widgetFiltersChange: SimpleChange = {
      previousValue: [{ facilityId: 1 }],
      currentValue: [{ facilityId: 2 }],
      firstChange: false,
      isFirstChange: () => false,
    };
    component.addWidgetToGrid(def1);
    component.getWidgets()[0].isLinkedToFilter = true;
    component.getWidgets()[0].widgetFilters = [];
    component.ngOnChanges({ widgetFilters: widgetFiltersChange });
    expect(component.getWidgets()[0].widgetFilters).toEqual([{ facilityId: 2 }]);
  });
});
