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

import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { of } from 'rxjs';
import { BciSidebarService } from '../bci-sidebar/bci-sidebar.service';
import { SidebarNavItem } from '../bci-sidebar/sidebar-nav-item.model';

import { BciSidebarNavListComponent } from './bci-sidebar-nav-list.component';

const navigation: SidebarNavItem[] = [
  {
    title: 'Overview',
    url: '/',
    position: 0,
    icon: 'Bosch-Ic-grid',
    routerLinkActiveOptions: {
      exact: true,
    },
  },
  {
    title: 'Form controls',
    url: 'form-controls',
    position: 1,
    icon: 'Bosch-Ic-tune',
    items: [
      {
        title: 'Checkbox',
        url: 'form-controls/checkbox-demo',
        routerLinkActiveOptions: {
          exact: true,
        },
      },
      {
        title: 'Datepicker',
        url: 'form-controls/datapicker-demo',
      },
      {
        title: 'Input field',
        url: 'form-controls/input-field-demo',
      },
    ],
  },
  {
    title: 'Navigation',
    url: 'navigation',
    position: 2,
    icon: 'Bosch-Ic-menu-tree',
    items: [
      {
        title: 'Breadcrumb',
        url: 'navigation/breadcrumbs-demo',
        routerLinkActiveOptions: {
          exact: true,
        },
      },
      {
        title: 'Side navigation',
        url: 'navigation/side-navigation-demo',
      },
    ],
  },
  {
    title: 'Colors',
    url: 'colors',
    position: 8,
    icon: 'Bosch-Ic-color-picker',
    routerLinkActiveOptions: {
      exact: true,
    },
  },
];

describe('BciSidebarNavListComponent', () => {
  let component: BciSidebarNavListComponent;
  let fixture: ComponentFixture<BciSidebarNavListComponent>;
  let router: any;

  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        imports: [RouterTestingModule, NoopAnimationsModule, BrowserAnimationsModule],
        declarations: [BciSidebarNavListComponent],
        providers: [
          {
            provide: Router,
            useValue: {
              url: '/',
              events: of(undefined),
            },
          },
        ],
      }).compileComponents();
    })
  );

  beforeEach(() => {
    fixture = TestBed.createComponent(BciSidebarNavListComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    router = TestBed.inject(Router);
  });

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

  describe('two level navigation', () => {
    beforeEach(() => {
      component.navItems = navigation;
      component.ngOnInit();
    });

    it('should highlight home navigation', () => {
      expect(component.navItems.filter((item) => item.url === '/')[0].active).toBeTruthy();
    });

    it('should highlight a navigated page', () => {
      router.url = '/colors';
      component.ngOnInit();
      expect(component.navItems.filter((item) => item.url === '/')[0].active).toBeFalsy();
      expect(component.navItems.filter((item) => item.url === 'colors')[0].active).toBeTruthy();
    });

    it('should highlight a navigated sub page', () => {
      router.url = '/form-controls/datapicker-demo';
      component.ngOnInit();
      expect(component.navItems.filter((item) => item.url === '/')[0].active).toBeFalsy();
      expect(component.navItems[1].expanded).toBeTruthy();
      expect(
        component.navItems[1].items.filter((item) => item.url === 'form-controls/datapicker-demo')[0].active
      ).toBeTruthy();
    });

    it('should highlight multiple open menus', () => {
      router.url = '/form-controls/datapicker-demo';
      component.ngOnInit();

      component.navItems[2].expanded = true;
      fixture.detectChanges();

      expect(component.navItems.filter((item) => item.url === '/')[0].active).toBeFalsy();
      expect(component.navItems[1].expanded).toBeTruthy();
      expect(
        component.navItems[1].items.filter((item) => item.url === 'form-controls/datapicker-demo')[0].active
      ).toBeTruthy();
      expect(component.navItems[2].expanded).toBeTruthy();
    });

    it('should have the same state if sidebar is closed and opened', () => {
      router.url = '/form-controls/datapicker-demo';
      component.ngOnInit();

      component.navItems[2].expanded = true;
      fixture.detectChanges();

      const sidebar = TestBed.inject(BciSidebarService);
      sidebar.setSidebarState(false);
      sidebar.setSidebarState(true);

      expect(component.navItems.filter((item) => item.url === '/')[0].active).toBeFalsy();
      expect(component.navItems[1].expanded).toBeTruthy();
      expect(
        component.navItems[1].items.filter((item) => item.url === 'form-controls/datapicker-demo')[0].active
      ).toBeTruthy();
      expect(component.navItems[2].expanded).toBeTruthy();
    });
  });

  describe('two level navigation', () => {
    beforeEach(() => {
      navigation[2].items[0].items = [
        {
          title: 'Breadcrumb Subpage',
          url: 'navigation/breadcrumbs-demo/sub-page',
        },
      ];
      component.navItems = navigation;
      component.ngOnInit();
    });

    it('should highlight home navigation', () => {
      expect(component.navItems.filter((item) => item.url === '/')[0].active).toBeTruthy();
    });

    it('should highlight a navigated page', () => {
      router.url = '/colors';
      component.ngOnInit();
      expect(component.navItems.filter((item) => item.url === '/')[0].active).toBeFalsy();
      expect(component.navItems.filter((item) => item.url === 'colors')[0].active).toBeTruthy();
    });

    it('should highlight a navigated sub page', () => {
      router.url = '/form-controls/datapicker-demo';
      component.ngOnInit();
      expect(component.navItems.filter((item) => item.url === '/')[0].active).toBeFalsy();
      expect(component.navItems[1].expanded).toBeTruthy();
      expect(
        component.navItems[1].items.filter((item) => item.url === 'form-controls/datapicker-demo')[0].active
      ).toBeTruthy();
    });

    it('should highlight a navigated sub sub page', () => {
      router.url = '/navigation/breadcrumbs-demo/sub-page';
      component.ngOnInit();
      expect(component.navItems.filter((item) => item.url === '/')[0].active).toBeFalsy();
      expect(component.navItems[2].expanded).toBeTruthy();
      expect(component.navItems[2].items[0].expanded).toBeTruthy();
      expect(
        component.navItems[2].items[0].items.filter((item) => item.url === 'navigation/breadcrumbs-demo/sub-page')[0]
          .active
      ).toBeTruthy();
    });

    it('should highlight multiple open menus', () => {
      router.url = '/form-controls/datapicker-demo';
      component.ngOnInit();

      component.navItems[2].expanded = true;
      fixture.detectChanges();

      expect(component.navItems.filter((item) => item.url === '/')[0].active).toBeFalsy();
      expect(component.navItems[1].expanded).toBeTruthy();
      expect(
        component.navItems[1].items.filter((item) => item.url === 'form-controls/datapicker-demo')[0].active
      ).toBeTruthy();
      expect(component.navItems[2].expanded).toBeTruthy();
    });

    it('should highlight multiple open menus and sub menus', () => {
      router.url = '/navigation/breadcrumbs-demo/sub-page';
      component.ngOnInit();

      component.navItems[1].expanded = true;
      fixture.detectChanges();

      expect(component.navItems.filter((item) => item.url === '/')[0].active).toBeFalsy();
      expect(component.navItems[1].expanded).toBeTruthy();
      expect(component.navItems[2].expanded).toBeTruthy();
      expect(component.navItems[2].items[0].expanded).toBeTruthy();
      expect(
        component.navItems[2].items[0].items.filter((item) => item.url === 'navigation/breadcrumbs-demo/sub-page')[0]
          .active
      ).toBeTruthy();
    });

    it('should have the same state if sidebar is closed and opened', () => {
      router.url = '/navigation/breadcrumbs-demo/sub-page';
      component.ngOnInit();

      component.navItems[1].expanded = true;
      fixture.detectChanges();

      const sidebar = TestBed.inject(BciSidebarService);
      sidebar.setSidebarState(false);
      sidebar.setSidebarState(true);

      expect(component.navItems.filter((item) => item.url === '/')[0].active).toBeFalsy();
      expect(component.navItems[1].expanded).toBeTruthy();
      expect(component.navItems[2].expanded).toBeTruthy();
      expect(component.navItems[2].items[0].expanded).toBeTruthy();
      expect(
        component.navItems[2].items[0].items.filter((item) => item.url === 'navigation/breadcrumbs-demo/sub-page')[0]
          .active
      ).toBeTruthy();
    });
  });
});
