import React from 'react';
import { shallow, mount } from 'enzyme';
import toJson from 'enzyme-to-json';
import ToDoApp from '../ToDoApp';

/**
|--------------------------------------------------
| Add tests for
|   updateToDoTags
|--------------------------------------------------
*/
describe('<ToDoApp />”', () => {
  beforeEach(() => {
    global.taskata = () => {};
    global.taskata.subscribers = {};
    global.taskata.subscribers.authChanges = {};
    global.taskata.subscribe = jest.fn();
    global.taskata.unsubscribe = jest.fn();
    global.taskata.auth = {};
    global.taskata.createItem = jest.fn();
    global.taskata.updateItem = jest.fn()
    global.taskata.destroyItem = jest.fn()  
  });
  
  it('should use handleUpdate to set new state', () => {
    let wrapper  = shallow(<ToDoApp />);
    let fakeData = { val: () => {
      return  { one: { text: 'foo',  completed: false, tags: ['Testing'] },
                two: { text: 'bar',  completed: false, tags: ['FooBar'] } };
    }}

    wrapper.instance().handleUpdate('todos', fakeData)

    expect(wrapper.state('todos')).toEqual(fakeData.val());
  });

  it('should not accidentally update state to undefined', () => {
    let wrapper  = shallow(<ToDoApp />);
    let todo   = { one: { text: 'foo', completed: false, tags: ['Testing']}};
    wrapper.setState({todos: todo})

    let badFakeData = { value: () => { return 'bar' } }

    wrapper.instance().handleUpdate('todos', badFakeData);

    expect(wrapper.state('todos')).toBe(todo);
  });

  describe('filterData function', () => {
    // beforeEach(() => {
      const data = { text: 'New Todo Item',
                      completed: false,
        tags: { 'oneTag':  {tagName: 'tagOne',  tagColor: 'blue' },
                'twoTag':  {tagName: 'tagTwo',  tagColor: 'purple' },
                'threeTag':  {tagName: 'tagThree',  tagColor: 'blue' },
                'fiveTag':  {tagName: 'tagFive',  tagColor: 'blue' }
        }
      };
      const existingTags = { 
        'one': { tagName: 'tagOne', tagColor: 'green' },
        'two': { tagName: 'tagTwo', tagColor: 'red' },
        'three': { tagName: 'tagThree', tagColor: 'blue' },
        'four': { tagName: 'tagFour', tagColor: 'purple' },
      }
    // });

    it('should create todo object to push to DB', () => {
      let wrapper  = shallow(<ToDoApp />);
      let expectedData = { text: data.text, 
                           completed: false, 
                           priority: false,
                           tags: ['tagOne', 'tagTwo', 'tagThree', 'tagFive']}
      
      let { todoToCreate } = 
                      wrapper.instance().filterData(data, existingTags);

      expect(todoToCreate).toEqual(expectedData);
    });
    
    it('should filter out unchanged tags before pushing to DB', () => {
      let wrapper  = shallow(<ToDoApp />);

      let { tagsToUpdate } = 
                      wrapper.instance().filterData(data, existingTags);

      expect(tagsToUpdate['three']).toBe(undefined)
    });

    it('should find changed existing tags and update their colors', () => {
      let wrapper  = shallow(<ToDoApp />);
      let expectedData = {'one': { tagName: 'tagOne', tagColor: 'blue' },
                          'two': { tagName: 'tagTwo', tagColor: 'purple' } }

      let { tagsToUpdate } = 
                      wrapper.instance().filterData(data, existingTags);

      expect(tagsToUpdate['one']).toEqual(expectedData['one']);
      expect(tagsToUpdate['two']).toEqual(expectedData['two']);
    });
    
    it('should filter new tags before pushing to DB', () => {
      let wrapper  = shallow(<ToDoApp />);
      let expectedData = [{tagName: 'tagFive',  tagColor: 'blue' }];

      let { tagsToCreate } = 
                      wrapper.instance().filterData(data, existingTags);

      expect(tagsToCreate).toEqual(expectedData);                      
    });
  });
  
  it('should define a getTagColor method for tag components to use', () => {
    let wrapper  = shallow(<ToDoApp />);
    let tags = { one: { tagName: 'foo',  tagColor: 'green' },
                two: { tagName: 'bar',  tagColor: 'blue' } };
    wrapper.setState({tags: tags});

    expect(wrapper.instance().getTagColor('foo')).toBe('green');
    expect(wrapper.instance().getTagColor('bar')).toBe('blue');
  });

  it('should call taskata.createItem', () => {
    let wrapper = shallow(<ToDoApp />);
    let data = {text: 'Foo', completed: false, tags: {}};
    let expectedData = { text: 'Foo', 
                         completed: false, 
                         priority: false,
                         tags: []};
    wrapper.instance().addToDo(data);
    expect(global.taskata.createItem).toHaveBeenCalledWith({
      type: 'todos',
      data: expectedData
    });
  });

  it('should call taskata.updateItem', () => {
    let wrapper = shallow(<ToDoApp />)
    wrapper.instance().toggleComplete('fakeKey', true);
    expect(global.taskata.updateItem).toHaveBeenCalledWith({
      type: 'todos',
      dbKey: 'fakeKey',
      data: { completed: true }
    });
  });
  
  it('should call taskata.destroyItem', () => {
    let wrapper = shallow(<ToDoApp />)
    wrapper.instance().handleRemove('fakeKey');
    expect(global.taskata.destroyItem).toHaveBeenCalledWith({
      type: 'todos',
      dbKey: 'fakeKey'
    });
  });
  
  it('should render correct components', () => {
    let wrapper = shallow(<ToDoApp/>);
    expect(toJson(wrapper)).toMatchSnapshot();
  });
});