/*
 * 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 { HttpClientTestingModule } from '@angular/common/http/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormBuilder } from '@angular/forms';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { CategoryService, InputType, PinboardGridComponent, Widget } from '../..';
import { Category } from '../../models/category';
import { WidgetTypes } from '../../models/definitions';
import { UserSetting } from '../../models/userSetting';
import { WidgetDefinition } from '../../models/widget-definition';
import { PinboardInteractionService } from '../../services/pinboard-interaction.service';
import { WidgetDefinitionService } from '../../services/widget-definition.service';
import { TestTextContentComponent, TestTextWidgetUserSetting } from '../../widget/test-text-widget-component';
import { WidgetSettingsFormComponent } from './widget-settings-form.component';

describe('WidgetSettingsFormComponent', () => {
  let component: WidgetSettingsFormComponent;
  let fixture: ComponentFixture<WidgetSettingsFormComponent>;
  let widget: Widget;
  let categoryService: CategoryService;
  let defService: WidgetDefinitionService;
  let interactionService: PinboardInteractionService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [NoopAnimationsModule, HttpClientTestingModule],
      declarations: [PinboardGridComponent, WidgetSettingsFormComponent],
      providers: [PinboardInteractionService, FormBuilder, CategoryService, WidgetDefinitionService],
    });

    categoryService = TestBed.inject<CategoryService>(CategoryService);
    defService = TestBed.inject<WidgetDefinitionService>(WidgetDefinitionService);
    interactionService = TestBed.inject<PinboardInteractionService>(PinboardInteractionService);

    WidgetTypes.splice(0, WidgetTypes.length);
    WidgetTypes.push({
      widgetType: 'TextWidget',
      contentComponentType: <any>TestTextContentComponent,
      widgetUserSettingType: TestTextWidgetUserSetting,
    });

    categoryService.addCategory({
      id: 'cat',
      description: '',
      title: '',
      visible: true,
    });
    const wDef = new WidgetDefinition<any, TestTextWidgetUserSetting, any>(
      '1',
      {
        id: 'def',
        visible: true,
        categoryIds: ['cat'],
        icon: '',
        description: '',
        title: '',
      },
      'TextWidget'
    );

    wDef.userSettings.push({
      id: 'text',
      defaultValue: 'test',
      categoryId: 'cat',
      inputType: InputType.TextBox,
      label: '',
    });

    defService.defineWidget(wDef);

    fixture = TestBed.createComponent(WidgetSettingsFormComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();

    const gridFixture = TestBed.createComponent(PinboardGridComponent);
    const gridComponent = gridFixture.componentInstance;
    gridFixture.detectChanges();
    interactionService.setPinboardGridComponent(gridComponent);
    widget = gridComponent.addWidgetToGrid(wDef);

    jest.spyOn(interactionService, "handleWidgetResize").mockReturnValue(true);
  });

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

  it('#buildFormsForWidget should create formGroups', () => {
    component.buildFormsForWidget(widget);
    expect(Object.keys(component.formGroup.controls).length).toBeGreaterThan(0);
  });

  it('#getAvailableCategories should get cat', () => {
    component.buildFormsForWidget(widget);
    const expect1 = component.getAvailableCategories().map((x) => x.id);
    expect(expect1).toEqual(['set_general', 'cat']);
  });

  it('#getUserSettingsOfCategory should get user settings for a widget', () => {
    jest.spyOn(component, 'getUserSettingsOfCategory').mockImplementation(() => {
      return [
        {
          id: 'test',
          categoryId: 'cat',
          inputType: 'text',
          label: 'test',
        } as UserSetting,
      ];
    });
    const category: Category = {
      id: 'cat',
      description: '',
      title: '',
      visible: true,
    };
    const response = component.getUserSettingsOfCategory(category);
    expect(response.length).toBeGreaterThanOrEqual(1);
    expect(response[0].categoryId).toEqual(category.id);
  });

  it('#cancel edit should revert all changes to a widget', (done) => {
    widget.title = 'Title';
    widget.gridsterItem.cols = 4;
    widget.gridsterItem.rows = 3;
    component.buildFormsForWidget(widget);

    setTimeout(() => {
      component.formGroup.get('title').setValue('New Title');
      component.formGroup.get('width').setValue(5);
      component.formGroup.get('height').setValue(4);
      component.cancelEdit();
      expect(widget.title).toEqual('Title');
      expect(widget.gridsterItem.cols).toEqual(4);
      expect(widget.gridsterItem.rows).toEqual(3);
      done();
    }, 1);
  });

  it('check the default value is true for show widget title field', () => {
    expect(widget.showWidgetTitle).toBeTruthy();
  });

  it('check the default value for widget configuration', () => {
    expect(widget.widgetDefinition.configuration).toEqual({ availableWidths: [4, 5, 6, 7, 8], availableHeights: [3, 4, 5, 6] });
  });

  it('#saveEdit should persist the widget configurations', (done) => {
    widget.title = 'Title';
    component.buildFormsForWidget(widget);
    setTimeout(() => {
      component.formGroup.get('title').setValue('New Title');
      component.formGroup.get('showWidgetTitle').setValue(false);
      component.formGroup.get('width').setValue(4);
      component.formGroup.get('height').setValue(3);
      component.saveEdit();
      expect(widget.title).toEqual('New Title');
      expect(widget.showWidgetTitle).toBeFalsy();
      expect(widget.gridsterItem.cols).toEqual(4);
      expect(widget.gridsterItem.rows).toEqual(3);
      expect(widget.sizeArray).toEqual([3, 4]);
      done();
    }, 1);
  });
});
