import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { Component, DebugElement } from '@angular/core';
import { BixiEditableTableModule } from '../src/editable-table.module';
import { BixiEditableTableComponent } from '../src/editable-table.component';
import { NzTableModule } from 'ng-zorro-antd/table';
import { By } from '@angular/platform-browser';
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
import { EEditableColType } from '../src/editable-table.type';
import { PlusOutline } from '@ant-design/icons-angular/icons';
import { NzIconModule, NzFormModule } from 'ng-zorro-antd';
import { FormGroup, FormBuilder, ReactiveFormsModule } from '@angular/forms';

const icons = [PlusOutline];

describe('bixi editable table', () => {
  let fixture: ComponentFixture<SimpleTestComponent>;
  let context: SimpleTestComponent;
  let debugEle: DebugElement;

  beforeEach(async () => {
    TestBed.configureTestingModule({
      imports: [BixiEditableTableModule, NzTableModule, NzIconModule.forRoot(icons), BrowserAnimationsModule, NoopAnimationsModule],
      declarations: [SimpleTestComponent]
    });

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

  afterEach(() => {
    fixture.destroy();
  });

  it('should be work', () => {
    fixture.detectChanges();
    const editTable = debugEle.query(By.directive(BixiEditableTableComponent));
    expect(editTable).not.toBeNull();
    let editBtn = debugEle.query(By.css('.bixi-table-actions>.bixi-action-btn'));
    expect(editBtn.nativeElement.textContent).toBe('编辑');
    editBtn.triggerEventHandler('click', 'click 编辑');
    fixture.detectChanges();
    editBtn = debugEle.query(By.css('.bixi-table-actions>.bixi-action-btn'));
    expect(editBtn.nativeElement.textContent).toBe('保存');
  });

  it('should be footer work', () => {
    fixture.detectChanges();
    let addBtn = debugEle.query(By.css('.bixi-editable-add-btn'));
    expect(addBtn.nativeElement.textContent).toContain('新增内容');
    context.footer = null;
    fixture.detectChanges();
    addBtn = debugEle.query(By.css('.bixi-editable-footer'));
    expect(addBtn).toBeNull();
  });

  it('should be header tooltip', () => {
    fixture.detectChanges();
    let tootipIcon = debugEle.query(By.css('.ant-table-cell>.anticon'));
    expect(tootipIcon).toBeNull()
    context.cols = [
      {
        key: 'name',
        name: '审核点'
      },
      {
        key: 'relation',
        titleTipContent: 'tootip',
        name: '关系'
      }
    ]
    fixture.detectChanges();
    tootipIcon = debugEle.query(By.css('.ant-table-cell>.anticon'));
    expect(tootipIcon).not.toBeNull();
  });

  it('should be add work', fakeAsync(() => {
    fixture.detectChanges();
    const activeInput = debugEle.queryAll(By.css('.bixi-editable-active'));
    expect(activeInput.length).toBe(0);
    const addBtn = debugEle.query(By.css('.bixi-editable-footer'));
    addBtn.triggerEventHandler('click', 'add btn clicked');
    fixture.detectChanges();
    tick(200);
    expect(context.addRow).toHaveBeenCalledTimes(1);
  }));

  it('should be edit type', () => {
    context.cols = [
      {
        key: 'name',
        name: '审核点'
      },
      {
        key: 'relation',
        name: 'select 编辑列',
        type: EEditableColType.select,
        options: [
          {
            name: 'shanghai',
            value: 'shanghai'
          },
          {
            name: 'beijing',
            value: 'beijing'
          }
        ]
      }
    ]
    fixture.detectChanges();
    const editBtn = debugEle.query(By.css('.bixi-table-actions>.bixi-action-btn'));
    expect(editBtn.nativeElement.textContent).toBe('编辑');
    editBtn.triggerEventHandler('click', 'click 编辑');
    fixture.detectChanges();
    const activeSelect = debugEle.queryAll(By.css('.bixi-editable-active .ant-select'));
    expect(activeSelect.length).toBe(1);
  });

  it('should be validate', () => {
    fixture.detectChanges();
    const editBtn = debugEle.query(By.css('.bixi-table-actions>.bixi-action-btn'));
    editBtn.triggerEventHandler('click', 'click 编辑');
    fixture.detectChanges();
    const activeInputEle = debugEle.query(By.css('.bixi-editable-active .ant-input')).nativeElement;
    activeInputEle.value = '123';
    const saveBtn = debugEle.query(By.css('.bixi-table-actions>.bixi-action-btn'));
    saveBtn.triggerEventHandler('click', 'click save');
    expect(context.editValidate).toHaveBeenCalledTimes(1);
  })

  it('should be dragable', () => {
    fixture.detectChanges();
    const dragRow = debugEle.queryAll(By.css('.cdk-drag-disable'));
    expect(dragRow.length).toBe(0);
    context.dragable = false;
    fixture.detectChanges();
    const dragDisable = debugEle.queryAll(By.css('.cdk-drag-disabled'));
    expect(dragDisable.length).not.toBe(0);
  })
});

@Component({
  selector: 'bixi-editable-demo-simple',
  template: `
    <bixi-editable-table [(rows)]="rows" [cols]="cols" [footer]="footer" (addRow)="addRow($event)" [validate]="editValidate" [dragable]="dragable"></bixi-editable-table>
  `
})
export class SimpleTestComponent {
  footer: any;
  dragable = true;
  addRow = jasmine.createSpy('addRow callback');
  editValidate = jasmine.createSpy('validate');
  onChange = jasmine.createSpy('col onChange');

  cols: any[] = [
    {
      key: 'name',
      name: '审核点',
      onChange: this.onChange
    },
    {
      key: 'relation',
      name: 'shanghai'
    }
  ];
  rows = [
    {
      name: '组合1',
      relation: '等于'
    }
  ]
}

describe('editable table form', () => {
  let fixture: ComponentFixture<SimpleTestFormComponent>;
  let context: SimpleTestFormComponent;
  let debugEle: DebugElement;

  beforeEach(async () => {
    TestBed.configureTestingModule({
      imports: [BixiEditableTableModule, NzTableModule, NzFormModule, ReactiveFormsModule, NzIconModule.forRoot(icons), BrowserAnimationsModule, NoopAnimationsModule],
      declarations: [SimpleTestFormComponent]
    });

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

  afterEach(() => {
    fixture.destroy();
  });

  it('should be work', () => {
    fixture.detectChanges();
    const editableForm = debugEle.query(By.css('.ant-form-item-control'));
    expect(editableForm).not.toBeNull();
  })

  it('form be work', () => {
    fixture.detectChanges();
    expect(context.form.value.editableForm).not.toBe(null);
  })
})

@Component({
  selector: 'bixi-editable-form-simple',
  template: `
  <form nz-form [formGroup]="form" (ngSubmit)="submitForm()">
    <nz-form-item>
      <nz-form-label> 可编辑表格 </nz-form-label>
      <nz-form-control>
        <bixi-editable-table [cols]="cols" formControlName="editableForm"></bixi-editable-table>
      </nz-form-control>
    </nz-form-item>
  </form>
  `
})
export class SimpleTestFormComponent {
  footer: any;
  dragable = true;
  addRow = jasmine.createSpy('addRow callback');
  editValidate = jasmine.createSpy('validate');
  onChange = jasmine.createSpy('col onChange');

  form: FormGroup;
  formValue = '';
  constructor(
    private fb: FormBuilder,
  ) {
    this.form = this.fb.group({
      input: ['1'],
      editableForm: [this.rows]
    })
  }

  cols: any[] = [
    {
      key: 'name',
      name: '审核点',
      onChange: this.onChange
    },
    {
      key: 'relation',
      name: 'shanghai'
    }
  ];
  rows = [
    {
      name: '组合1',
      relation: '等于'
    }
  ]
}
