import { LabelHub } from './label.hub';
import { PdfMode, LabelTextMode, ILabel, ISerarchParams, ISearchResult, ISearchLabelByUuidParams, ISearchLabelByIndexParams, ISearchTableCellParams } from './label.type';
import { NzSafeAny } from 'ng-zorro-antd/core/types';

describe('#@bixi/label LabelHub', () => {
  const INIT_OPTIONS = {
    id: '111',
    pdfUrl: '',
    pdfCharsUrl: '',
    pdfInfoUrl: '',
    pdfMode: PdfMode.full,
    labelMode: LabelTextMode.textSlip
  };
  const LABELS: ILabel[] = [{
    index: 1,
    word: '1',
  }, {
    index: 2,
    word: '2',
  }];
  const TABLES = [1, 2, 3];
  let api: NzSafeAny;
  let hub: LabelHub;
  beforeEach(() => {
    api = jasmine.createSpyObj('api', [
      'init',
      'setPage',
      'setZoom',
      'setLabelMode',
      'setPdfMode',
      'setLabels',
      'restore',
      'search',
      'scrollToLabel',
      'scrollToLabelByIdx',
      'scrollToTableCell',
      'setTables',
      'getTableMatrix',
      'getViewport',
      'getSelectedLabels'
    ]);
    hub = new LabelHub({
      dev: false,
      logAllEvents: false,
      logIgnoreEvents: [],
      logUnhandledEvents: false
    });
  });

  function init() {
    hub.setApi(api);
    hub.setLoaded(true);
    hub.setReady(true);
    hub.init(INIT_OPTIONS);
  }

  it('# loaded/ready', () => {
    expect(hub.api).toBeUndefined();
    expect(hub.loaded).toBeFalse();
    expect(hub.loaded$.getValue()).toBeFalse();
    expect(hub.ready).toBeFalse();
    expect(hub.ready$.getValue()).toBeFalse();
    hub.setApi(api);
    hub.setLoaded(true);
    hub.setReady(true);
    expect(hub.api).toBeDefined();
    expect(hub.loaded).toBeTrue();
    expect(hub.loaded$.getValue()).toBeTrue();
    expect(hub.ready).toBeTrue();
    expect(hub.ready$.getValue()).toBeTrue();
  })

  it('# init', () => {
    expect(hub.init$.getValue()).toBeNull();
    init();
    expect(hub.id).toBe('111');
    expect(hub.init$.getValue()).toEqual(INIT_OPTIONS);

  })

  it('# setLabels', () => {
    init();
    hub.setLabels(LABELS);
    expect(hub.labels$.getValue()).toEqual(LABELS);
  })

  it('# setTables', () => {
    init();
    hub.setTables(TABLES);
    expect(hub.tables$.getValue()).toEqual(TABLES);
  })

  it('# getTableMatrix', () => {
    init();
    api.getTableMatrix.and.returnValue(111);
    hub.getTableMatrix();
    expect(api.getTableMatrix.calls.count()).toBe(1);
    expect(api.getTableMatrix.calls.mostRecent().returnValue).toBe(111);
  })

  it('# hoverInLabels in', (done) => {
    const hoverData = {
      data: [{ index: 1, word: '1' }],
      position: {
        top: 1,
        left: 1,
        width: 1,
        height: 1
      }
    };
    init();
    hub.hoverInLabelsEvent$.subscribe(e => {
      expect(hub.hoverInLabelsEvent).toEqual(hoverData);
      expect(e).toEqual(hoverData);
      done();
    })
    hub.hoverInLabels(hoverData);
  })

  it('# setPagination full', () => {
    init();
    hub.setPagination({
      pageCount: 2,
      pageNumber: 2
    });
    expect(hub.getPagination()).toEqual({
      pageCount: 2,
      pageNumber: 2
    });
    expect(hub.pagination$.getValue()).toEqual({
      pageCount: 2,
      pageNumber: 2
    });
  })

  it('# setPagination partial', () => {
    init();
    hub.setPagination({
      pageCount: 10,
      pageNumber: 1,
    });
    hub.setPagination({
      pageNumber: 2
    });
    expect(hub.getPagination()).toEqual({
      pageCount: 10,
      pageNumber: 2
    });
    expect(hub.pagination$.getValue()).toEqual({
      pageCount: 10,
      pageNumber: 2
    });
    expect(api.setPage.calls.count()).toBe(1);
    expect(api.setPage).toHaveBeenCalledWith(2);
  })

  it('# innerSetPagination', () => {
    init();
    hub.innerSetPagination({
      pageCount: 10
    });
    expect(hub.getPagination()).toEqual({
      pageCount: 10,
      pageNumber: 1
    });
    expect(hub.pagination$.getValue()).toEqual({
      pageCount: 10,
      pageNumber: 1
    });
    expect(api.setPage.calls.count()).toBe(0, '不应该调用标注器');
  })

  it('# setZoom', () => {
    init();
    hub.setZoom(2);
    expect(hub.getZoom()).toBe(2);
    expect(hub.zoom$.getValue()).toBe(2);
    expect(api.setZoom.calls.count()).toBe(1);
    expect(api.setZoom).toHaveBeenCalledWith(2);
  })

  it('# setPdfMode', () => {
    init();
    hub.setPdfMode(PdfMode.deleteonly);
    expect(api.setPdfMode.calls.count()).toBe(1);
    expect(api.setPdfMode).toHaveBeenCalledWith(PdfMode.deleteonly);
  })

  it('# startLabeling', (done) => {
    const labelData = {
      data: [{ index: 1, word: '1' }],
      position: {
        top: 1,
        left: 1,
        width: 1,
        height: 1
      }
    };
    init();
    expect(hub.labeling).toBeFalse();
    hub.labelingEvent$.subscribe((e) => {
      expect(hub.labeling).toBeTrue();
      expect(e).toEqual(labelData);
      done();
    });
    hub.startLabeling(labelData);
  })

  it('# stopLabeling', (done) => {
    const labelData = {
      data: [{ index: 1, word: '1' }],
      position: {
        top: 1,
        left: 1,
        width: 1,
        height: 1
      }
    };
    init();
    hub.startLabeling(labelData);
    expect(hub.labeling).toBeTrue();
    hub.labelingEvent$.subscribe((e) => {
      expect(hub.labeling).toBeFalse();
      expect(e).toBeNull();
      done();
    });
    hub.stopLabeling();
  })

  it('# search', () => {
    init();
    const searchParams: ISerarchParams = {
      keyword: '111',
      caseSensitive: false
    };
    hub.search(searchParams);
    expect(api.search.calls.count()).toBe(1);
    expect(api.search).toHaveBeenCalledWith(searchParams);
    expect(hub.searchResult$.getValue()).toEqual({
      keyword: '',
      caseSensitive: false,
      result: []
    });
    const searchResult: ISearchResult = {
      keyword: '111',
      caseSensitive: false,
      result: {
        '0': [{
          pageNumber: 1,
          pre: '1',
          next: '2'
        }]
      }
    }
    hub.setSearchResult(searchResult);
    expect(hub.searchResult$.getValue()).toEqual(searchResult);
  })

  it('# restore', () => {
    init();
    hub.restore();
    expect(api.restore.calls.count()).toBe(1);
  })

  it('# scrollToLabelByUuid', () => {
    const params: ISearchLabelByUuidParams = {
      uuid: '1'
    };
    init();
    hub.scrollToLabelByUuid(params);
    expect(api.scrollToLabel.calls.count()).toBe(1);
    expect(api.scrollToLabel).toHaveBeenCalledWith(params);
  })

  it('# scrollToLabelByIndex', () => {
    const params: ISearchLabelByIndexParams = {
      index: 1,
    };
    init();
    hub.scrollToLabelByIndex(params);
    expect(api.scrollToLabelByIdx.calls.count()).toBe(1);
    expect(api.scrollToLabelByIdx).toHaveBeenCalledWith(params);
  })

  it('# scrollToTableCell', () => {
    const params: ISearchTableCellParams = {
      pageNumber: 1,
      x: 1,
      y: 1
    };
    init();
    hub.scrollToTableCell(params);
    expect(api.scrollToTableCell.calls.count()).toBe(1);
    expect(api.scrollToTableCell).toHaveBeenCalledWith(params);
  })

  it('# getViewport', () => {
    init();
    api.getViewport.and.returnValue(111);
    hub.getViewport();
    expect(api.getViewport.calls.count()).toBe(1);
    expect(api.getViewport.calls.mostRecent().returnValue).toBe(111);
  })

  it('# getViewport', () => {
    init();
    api.getSelectedLabels.and.returnValue(LABELS);
    hub.getSelectedLabels();
    expect(api.getSelectedLabels.calls.count()).toBe(1);
    expect(api.getSelectedLabels.calls.mostRecent().returnValue).toBe(LABELS);
  })
});
