import { createComponentFactory, Spectator, SpyObject } from '@ngneat/spectator';
import { CommonModule } from '@angular/common';
import { RouterTestingModule } from '@angular/router/testing';
import { UiIconModule } from '@ui/icon';
import { Router } from '@angular/router';
import { UiFilter } from '@ui/filter';
import { MessageBoardItemDTO } from 'apps/hub/notifications/src/lib/defs';
import { Component } from '@angular/core';
import { ModalNotificationsListItemComponent } from '../notifications-list-item/notifications-list-item.component';
import { ModalNotificationsRemissionGroupComponent } from './notifications-remission-group.component';

// DummyComponent Class
@Component({
  selector: 'dummy-component',
  template: '<div></div>',
})
class DummyComponent {
  constructor() {}
}

describe('ModalNotificationsRemissionGroupComponent', () => {
  let spectator: Spectator<ModalNotificationsRemissionGroupComponent>;
  let uiFilterMock: SpyObject<UiFilter>;
  let router: Router;

  const createComponent = createComponentFactory({
    component: ModalNotificationsRemissionGroupComponent,
    declarations: [ModalNotificationsListItemComponent],
    imports: [
      CommonModule,
      RouterTestingModule.withRoutes([
        { path: 'filiale/goods/in/results', component: DummyComponent },
        { path: 'filiale/remission/create', component: DummyComponent },
      ]),
      UiIconModule,
    ],
    providers: [],
    mocks: [UiFilter],
  });

  beforeEach(() => {
    spectator = createComponent({ props: { notifications: [] } });
    router = spectator.inject(Router);
    uiFilterMock = spectator.inject(UiFilter);
  });

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

  describe('notifications input', () => {
    it('should display the right notification-counter value based on the length of the input array', () => {
      spectator.setInput({ notifications: [{}, {}, {}] });
      expect(spectator.query('.notification-counter')).toHaveText('3');
    });

    it('should not display notification-counter if input array has length 0', () => {
      spectator.setInput({ notifications: [] });
      expect(spectator.query('.notification-counter')).toHaveText('');
    });

    it('should render modal-notifications-list-item based on the input array', () => {
      const notifications = [{}, {}];
      spectator.setInput({ notifications });
      spectator.detectComponentChanges();
      expect(spectator.queryAll('modal-notifications-list-item')).toHaveLength(notifications.length);
    });
  });

  describe('itemSelected()', () => {
    it('should navigate to results with queryParams from UiFilter.getQueryParamsFromQueryTokenDTO()', () => {
      const item: MessageBoardItemDTO = { queryToken: { input: { main_qs: 'test' } } };
      spyOn(UiFilter, 'getQueryParamsFromQueryTokenDTO').and.returnValue(item.queryToken.input);
      spyOn(router, 'navigate');
      spectator.component.itemSelected(item);
      expect(router.navigate).toHaveBeenCalledWith(['/filiale/goods/in/results'], { queryParams: item.queryToken.input });
    });

    it('should emit the navigated event after select item', () => {
      const item: MessageBoardItemDTO = { queryToken: { input: { main_qs: 'test' } } };
      spyOn(spectator.component.navigated, 'emit');
      spectator.component.itemSelected(item);
      expect(spectator.component.navigated.emit).toHaveBeenCalled();
    });
  });

  describe('actions CTA', () => {
    it('should navigate to remission page after clicking the CTA', () => {
      const cta = spectator.query('.cta-primary');
      expect(cta).toHaveText('Zur Remission');
      expect(cta).toHaveAttribute('href', '/filiale/remission/create');
    });

    it('should emit the navigated event after clicking the CTA', () => {
      const cta = spectator.query('.cta-primary') as HTMLAnchorElement;
      spyOn(spectator.component.navigated, 'emit');
      spectator.click(cta);
      expect(spectator.component.navigated.emit).toHaveBeenCalled();
    });
  });
});
