import { ComponentFixture, fakeAsync, inject, TestBed, tick } from '@angular/core/testing';
import { BixiTableModule } from '../table.module';
import { Component, DebugElement } from '@angular/core';
import { ICols } from '../table.type';
import { By } from '@angular/platform-browser';
import { OverlayContainer } from '@angular/cdk/overlay';
import { NzToolTipModule } from 'ng-zorro-antd/tooltip';
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
import { dispatchMouseEvent } from '@bixi/testing';

describe('col base', () => {
  let fixture: ComponentFixture<TestComponent>;
  let context: TestComponent;
  let debugEle: DebugElement;
  let overlayContainerEle: HTMLElement;

  beforeEach(async () => {
    TestBed.configureTestingModule({
      imports: [ BixiTableModule, BrowserAnimationsModule, NzToolTipModule, NoopAnimationsModule ],
      declarations: [ TestComponent ]
    });

    fixture = TestBed.createComponent(TestComponent);
    context = fixture.componentInstance;
    debugEle = fixture.debugElement;
  });

  beforeEach(inject([ OverlayContainer ], (oc: OverlayContainer) => {
    overlayContainerEle = oc.getContainerElement();
  }));

  function waitingForTooltipToggling(): void {
    fixture.detectChanges();
    tick(500);
    fixture.detectChanges();
  }

  it('should init', () => {
    // when
    fixture.detectChanges();

    // then
    expect(context).toBeDefined();
  });

  it('should render text', () => {
    // given
    context.cols = [
      {
        name: '默认文字',
        key: 'name'
      }
    ];

    // when
    fixture.detectChanges();

    // then
    const title = debugEle.query(By.css('.ant-table-cell')).nativeElement.textContent;
    const content = debugEle.query(By.css('.bixi-table-col-text')).nativeElement.querySelector('div').textContent;
    expect(title).toContain('默认文字');
    expect(content).toBe(persons[0].name);
  });

  it('should show tooltip when mouseenter', fakeAsync(() => {
    // given
    context.cols = [
      {
        name: '默认文字',
        key: 'name'
      }
    ];

    // when
    fixture.detectChanges();
    const triggerEle = debugEle.query(By.css('.bixi-table-col-text')).nativeElement.querySelector('div span');
    dispatchMouseEvent(triggerEle, 'mouseenter');
    waitingForTooltipToggling();

    // then
    expect(overlayContainerEle.textContent).toContain(persons[0].name);
  }));

  it('should not show tooltip', fakeAsync(() => {
    // given
    context.cols = [
      {
        name: '默认文字',
        key: 'name',
        tooltip: false
      }
    ];

    // when
    fixture.detectChanges();
    const triggerEle = debugEle.query(By.css('.bixi-table-col-text')).nativeElement.querySelector('div span');
    dispatchMouseEvent(triggerEle, 'mouseenter');
    waitingForTooltipToggling();

    // then
    expect(overlayContainerEle.textContent).not.toContain(persons[0].name);
  }));

  it('should render col width and ellipse', () => {
    // given
    context.cols = [
      {
        name: '默认文字',
        key: 'name',
        width: '40px',
        ellipsis: true
      }
    ];

    // when
    fixture.detectChanges();

    // then
    const contentEl = (debugEle.query(By.css('.bixi-table-col-text')).nativeElement.querySelector('div'));
    const width = contentEl.style.width;
    const text = contentEl.style.textOverflow;
    expect(width).toBe('40px');
    expect(text).toBe('ellipsis');
  });

  it('should get value deeply', () => {
    // given
    context.cols = [
      {
        name: '深度取值',
        key: 'info.age'
      }
    ];

    // when
    fixture.detectChanges();

    // then
    const title = debugEle.query(By.css('.ant-table-cell')).nativeElement.textContent;
    const content = debugEle.query(By.css('.bixi-table-col-text')).nativeElement.querySelector('div').textContent;
    expect(title).toContain('深度取值');
    expect(content).toBe(persons[0].info.age.toString());
  });
});

interface IPerson {
  name: string;
  info: { [key: string]: number };
}

const persons: IPerson[] = [
  {
    name: '小明',
    info: {
      age: 12
    }
  }
];

@Component({
  template: `
    <bixi-table [rows]="rows" [cols]="cols"></bixi-table>
  `
})
class TestComponent {
  rows: IPerson[] = persons;
  cols: ICols = [];
}
