import { expect } from 'chai';
import { Tree, TreeNode, TreeRaw } from '../src/tree';

function getIDList(nodes: TreeNode[]): string[] {
  return nodes.map(node => node.ID);
}

describe('NodeCtx', () => {
  const rawData: TreeRaw[] = [
    { ID: '1', parentID: '-1', seq: 1 },
    { ID: '2', parentID: '-1', seq: 3 },
    { ID: '3', parentID: '-1', seq: 2 },
    { ID: '4', parentID: '-1', seq: 4 },
    { ID: '5', parentID: '-1', seq: 5 },
    { ID: '6', parentID: '1', seq: 2 },
    { ID: '7', parentID: '1', seq: 1 },
    { ID: '8', parentID: '7', seq: 1 },
    { ID: '9', parentID: '2', seq: 1 },
  ];

  const tree = new Tree(rawData);

  it('row', () => {
    const node = tree.find('4');
    if (node) {
      const row = node.getCtx().row();
      expect(row).to.equal(7);
    }
  });

  it('depth', () => {
    const node = tree.find('1');
    if (node) {
      const depth = node.getCtx().depth();
      expect(depth).to.equal(0);
    }
    const deepNode = tree.find('8');
    if (deepNode) {
      const depth = deepNode.getCtx().depth();
      expect(depth).to.equal(2);
    }
  });

  it('visible', () => {
    const node = tree.find('1');
    if (node) {
      node.getCtx().expanded = true;
      const testNode = tree.find('8');
      if (testNode) {
        const visibleA = testNode.getCtx().visible();
        expect(visibleA).to.equal(false);
        node.getCtx().expanded = false;
        const visibleB = testNode.getCtx().visible();
        expect(visibleB).to.equal(false);
      }
    }
  });

  it('parent', () => {
    const node = tree.find('6');
    if (node) {
      const parent = node.getCtx().parent();
      expect(parent).to.have.property('ID', '1');
    }
  });

  it('parent', () => {
    const node = tree.find('6');
    if (node) {
      const parent = node.getCtx().parent();
      expect(parent).to.have.property('ID', '1');
    }
  });

  it('next', () => {
    const node = tree.find('1');
    if (node) {
      const next = node.getCtx().next();
      expect(next).to.have.property('ID', '3');
    }
  });

  it('prev', () => {
    const node = tree.find('3');
    if (node) {
      const prev = node.getCtx().prev();
      expect(prev).to.have.property('ID', '1');
    }
  });

  it('children', () => {
    const node = tree.find('1');
    if (node) {
      const children = node.getCtx().children();
      const IDList = getIDList(children);
      expect(IDList).to.have.ordered.members(['7', '6']);
    }
  });

  it('firstChild', () => {
    const node = tree.find('1');
    if (node) {
      const firstChild = node.getCtx().firstChild();
      expect(firstChild).to.have.property('ID', '7');
    }
  });

  it('lastChild', () => {
    const node = tree.find('1');
    if (node) {
      const lastChild = node.getCtx().lastChild();
      expect(lastChild).to.have.property('ID', '6');
    }
  });

  it('posterity', () => {
    const node = tree.find('1');
    if (node) {
      const posterity = node.getCtx().posterity();
      const IDList = getIDList(posterity);
      expect(IDList).to.have.ordered.members(['7', '8', '6']);
    }
  });

  it('progenitor', () => {
    const node = tree.find('8');
    if (node) {
      const progenitor = node.getCtx().progenitor();
      if (progenitor) {
        expect(progenitor).to.have.property('ID', '1');
      }
    }
  });

  it('ancestor', () => {
    const node = tree.find('8');
    if (node) {
      const ancestor = node.getCtx().ancestor();
      const IDList = getIDList(ancestor);
      expect(IDList).to.have.ordered.members(['7', '1']);
    }
  });

  it('brothers', () => {
    const node = tree.find('6');
    if (node) {
      const brothers = node.getCtx().brothers();
      const IDList = getIDList(brothers);
      expect(IDList).to.have.ordered.members(['7', '6']);

      const excludeBrothers = node.getCtx().brothers(false);
      const exIDList = getIDList(excludeBrothers);
      expect(exIDList).to.have.ordered.members(['7']);
    }
  });

  it('nextBrothers', () => {
    const node = tree.find('2');
    if (node) {
      const nextBrothers = node.getCtx().nextBrothers();
      const IDList = getIDList(nextBrothers);
      expect(IDList).to.have.ordered.members(['4', '5']);
    }
  });

  it('prevBrothers', () => {
    const node = tree.find('2');
    if (node) {
      const prevBrothers = node.getCtx().prevBrothers();
      const IDList = getIDList(prevBrothers);
      expect(IDList).to.have.ordered.members(['1', '3']);
    }
  });
});
