import React from 'react';
import karmadataTheme from '../../themes/karmadata.scss';
import { FilterItem } from 'karmadata';
import { ANY, USER_SPECIFIED_OPTION } from '../../constants';
import { mount } from 'enzyme';
import isEqual from 'lodash/isEqual'
import renderer from 'react-test-renderer';

import KdSelectEntity from '../../components/KdSelectEntity';
import { chicklets, events, autoCompleteOptions, initialValues } from '../__utils';

const mainSelectorOptions = {
  visible: true,
  notSelectedOption: { label: 'Any label' },
  userSpecifiedOption: { label: 'Search' },
  optionGroups: [{
    label: 'first group',
    options: [
      {
        label: 'test2',
        values: [
          {
            value: '1653225',
            label: '0.98 ML Etanercept 50 MG/ML Auto-Injector [Enbrel]',
            EntityType: 'KdDrugRxNorm',
          },
          {
            value: '262095',
            label: 'atorvastatin 80 MG Oral Tablet [Lipitor]',
            EntityType: 'KdDrugRxNorm',
          },
        ],
      },
      {
        label: 'test',
        values: [
          {
            value: '262095',
            label: 'atorvastatin 80 MG Oral Tablet [Lipitor]',
            EntityType: 'KdDrugRxNorm',
          },
        ],
      },
    ],
  }],
};

const props = {
  mainSelector: mainSelectorOptions,
  selectedValuesInitial: initialValues,
  autoComplete: autoCompleteOptions,
  events,
  chicklets,
};


describe('KdSelectEntity', () => {
  let kdFilterModel;
  beforeEach(() => {
    kdFilterModel = FilterItem('KdDrugClassEPC', 'KdId', 'KdDrugClassEPC');
  });

  describe('Setup', () => {
    it('renders correctly', () => {
      const tree = renderer.create(
        <KdSelectEntity
          kdFilterModel={kdFilterModel}
          theme={karmadataTheme}
          {...props}
        />
      ).toJSON();
      expect(tree).toMatchSnapshot();
    });

    it('should set values from model', () => {
      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={kdFilterModel}
          theme={karmadataTheme}
          {...props}
        />);
      expect(wrapper.instance().getChicklets().length).toBe(kdFilterModel.getSelected().length);
    });
  });

  describe('Values Limit', () => {
    const customProps = { ...props, selectBehavior: 'AddChicklet' };
    const values = [
      {
        KdId: '1653225',
        KdLabel: '0.98 ML Etanercept 50 MG/ML Auto-Injector [Enbrel]',
        EntityType: 'KdDrugRxNorm',
      },
      {
        KdId: '262095',
        KdLabel: 'atorvastatin 80 MG Oral Tablet [Lipitor]',
        EntityType: 'KdDrugRxNorm',
      },
    ];

    it('without limit', () => {
      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={FilterItem('KdDrugRxNorm', 'DrugScheduleDEA', 'KdDrugRxNorm', 'Eq', values)}
          theme={karmadataTheme}
          {...customProps}
        />);
      expect(wrapper.instance().getChicklets().length).toBe(values.length);
    });

    it('limit and initial values', () => {
      const limit = 1;
      const filter = FilterItem('KdDrugRxNorm', 'DrugScheduleDEA', 'KdDrugRxNorm', 'Eq', values);
      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={filter}
          theme={karmadataTheme}
          {...customProps}
          valuesLimit={limit}
        />);
      expect(wrapper.instance().getChicklets().length).toBe(limit);
      expect(filter.getSelected().length).toBe(limit);
    });


    // it('add value', () => {
    //   // TO DO
    // });

    it('uses last values', () => {
      const limit = 1;
      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={FilterItem('KdDrugRxNorm', 'DrugScheduleDEA', 'KdDrugRxNorm', 'Eq', values)}
          theme={karmadataTheme}
          {...props}
          valuesLimit={limit}
        />);
      const kdChicklets = wrapper.instance().getChicklets().map(v => v.value);
      expect(isEqual(kdChicklets.slice(-limit), values.map(v => v.KdId).slice(-limit))).toBe(true);
      expect(wrapper.instance().getChicklets().length).toBe(limit);
    });
  });


  describe('mainSelector', () => {
    it('visible', () => {
      const customProps = { ...props, mainSelector: mainSelectorOptions };
      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={kdFilterModel}
          theme={karmadataTheme}
          {...customProps}
        />);
      expect(wrapper.find('select').length).toBe(1);
      expect(wrapper.find('input.o-kd-autocomplete-input').length).toBe(1);
    });

    it('not visible', () => {
      const mainSelector = { ...mainSelectorOptions, visible: false };
      const customProps = { ...props, mainSelector };
      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={kdFilterModel}
          theme={karmadataTheme}
          {...customProps}
        />);
      expect(wrapper.find('select').length).toBe(0);
      expect(wrapper.find('input.o-kd-autocomplete-input').length).toBe(1);
    });

    it('Any option visible', () => {
      const customProps = { ...props, mainSelector: mainSelectorOptions };
      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={kdFilterModel}
          theme={karmadataTheme}
          {...customProps}
        />);
      expect(wrapper.find(`option[value="${ANY}"]`).length).toBe(1);
    });

    it('User specified options visible', () => {
      const customProps = { ...props, mainSelector: mainSelectorOptions };
      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={kdFilterModel}
          theme={karmadataTheme}
          {...customProps}
        />);
      expect(wrapper.find(`option[value="${USER_SPECIFIED_OPTION}"]`).length).toBe(1);
    });

    it('Custom values visible', () => {
      const customProps = { ...props, mainSelector: mainSelectorOptions };
      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={kdFilterModel}
          theme={karmadataTheme}
          {...customProps}
        />);
      expect(wrapper.find('option[value="test"]').length).toBe(1);
    });
  });

  describe('Events', () => {
    it('Not generate on change with initials', () => {
      const onChange = jest.fn();
      const customProps = {
        ...props,
        mainSelector: mainSelectorOptions,
        events: { onChange },
      };
      mount(
        <KdSelectEntity
          kdFilterModel={kdFilterModel}
          theme={karmadataTheme}
          {...customProps}
        />
      );

      expect(onChange.mock.calls.length).toBeGreaterThanOrEqual(0);
    });

    it('onChange', () => {
      const onChange = jest.fn();
      const customProps = {
        ...props,
        mainSelector: mainSelectorOptions,
        selectedValuesInitial: [],
        events: { onChange },
      };
      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={kdFilterModel}
          theme={karmadataTheme}
          {...customProps}
        />
      );

      wrapper.find('select').simulate('change', { target: { value: 'test' } });
      expect(onChange.mock.calls.length).toBeGreaterThanOrEqual(1);
    });

    it('onSelect', () => {
      const onSelect = jest.fn();
      const customProps = {
        ...props,
        mainSelector: mainSelectorOptions,
        selectedValuesInitial: [],
        events: { onSelect },
      };
      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={kdFilterModel}
          theme={karmadataTheme}
          {...customProps}
        />
      );

      wrapper.find('select').simulate('change', { target: { value: 'test' } });
      expect(onSelect.mock.calls.length).toBeGreaterThanOrEqual(1);
    });
  });

  describe('behavior', () => {
    it('Be disabled', () => {
      const customProps = {
        ...props,
        mainSelector: mainSelectorOptions,
        isDisabled: true,
      };
      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={kdFilterModel}
          theme={karmadataTheme}
          {...customProps}
        />
      );

      expect(wrapper.find('.u-disabled').length).toBe(1);
    });

    it('Be active', () => {
      const customProps = {
        ...props,
        mainSelector: mainSelectorOptions,
        isDisabled: false,
      };
      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={kdFilterModel}
          theme={karmadataTheme}
          {...customProps}
        />
      );

      expect(wrapper.find('.u-disabled').length).toBe(0);
    });

    describe('None', () => {
      it('Set input value with model value', () => {
        const customProps = {
          ...props,
          mainSelector: mainSelectorOptions,
          selectBehavior: 'None',
        };
        const value = val => ({
          KdId: val,
          KdLabel: `label ${val}`,
          EntityType: 'KdDrugRxNorm',
        });

        const model = FilterItem('KdDrugClassEPC', 'KdId', 'KdDrugClassEPC', 'Eq', [value('test'), value('test2')]);
        const wrapper = mount(
          <KdSelectEntity
            kdFilterModel={model}
            theme={karmadataTheme}
            {...customProps}
          />
        );

        expect(wrapper.find('input.o-kd-autocomplete-input').length).toBe(1);
        const inputValue = wrapper.find('input.o-kd-autocomplete-input').props().defaultValue;
        expect(inputValue).toBe(value('test').KdLabel);
      });

      it('Add a value', () => {
        const customProps = {
          ...props,
          mainSelector: mainSelectorOptions,
          selectBehavior: 'None',
        };
        const wrapper = mount(
          <KdSelectEntity
            kdFilterModel={kdFilterModel}
            theme={karmadataTheme}
            {...customProps}
          />
        );

        wrapper.find('select').simulate('change', { target: { value: 'test' } });

        expect(wrapper.find('.c-kd-selected-chicklets').length).toBe(0);
        expect(wrapper.instance().getChicklets().length).toBe(1);
      });
    });

    it('AddChicklet', () => {
      const customProps = {
        ...props,
        mainSelector: mainSelectorOptions,
        selectedValuesInitial: [],
        selectBehavior: 'AddChicklet',
      };

      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={kdFilterModel}
          theme={karmadataTheme}
          {...customProps}
        />
      );

      wrapper.find('select').simulate('change', { target: { value: 'test' } });
      expect(wrapper.find('.c-kd-selected-chicklets').length).toBe(1);
      expect(wrapper.instance().getChicklets().length).toBe(1);

      wrapper.find('select').simulate('change', { target: { value: 'test2' } });
      expect(wrapper.find('.c-kd-selected-chicklets').length).toBe(1);
      expect(wrapper.find('.c-kd-selected-chicklets').children().length).toBe(2);
      expect(wrapper.instance().getChicklets().length).toBe(2);
    });

    it('AddChickletSingle', () => {
      console.log('Review this behavior')
      const customProps = {
        ...props,
        mainSelector: mainSelectorOptions,
        selectedValuesInitial: [],
        selectBehavior: 'AddChickletSingle',
      };
      const wrapper = mount(
        <KdSelectEntity
          kdFilterModel={kdFilterModel}
          theme={karmadataTheme}
          {...customProps}
        />
      );

      wrapper.find('select').simulate('change', { target: { value: 'test' } });
      expect(wrapper.find('.c-kd-selected-chicklets').length).toBe(1);
      expect(wrapper.instance().getChicklets().length).toBe(1);

      wrapper.find('select').simulate('change', { target: { value: 'test2' } });
      expect(wrapper.find('.c-kd-selected-chicklets').length).toBe(1);
      expect(wrapper.find('.c-kd-selected-chicklets').children().length).toBe(2);
      expect(wrapper.instance().getChicklets().length).toBe(2);
    });
  });
});
