import Calendar from '..';
import { mount, later } from '../../../test';
import { getNextDay } from '../utils';

const now = new Date();
const minDate = new Date(2010, 0, 10);
const maxDate = new Date(2010, 0, 20);

function formatDate(date) {
  if (date) {
    return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
  }

  return '';
}

function formatRange([start, end]) {
  return `${formatDate(start)}-${formatDate(end)}`;
}

test('select event when type is single', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      minDate,
      maxDate,
      poppable: false
    }
  });

  await later();

  wrapper
    .findAll('.van-calendar__day')
    .at(15)
    .trigger('click');

  expect(formatDate(wrapper.emitted('select')[0][0])).toEqual('2010/1/16');
});

test('select event when type is range', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      type: 'range',
      minDate,
      maxDate,
      poppable: false
    }
  });

  await later();

  const days = wrapper.findAll('.van-calendar__day');
  days.at(15).trigger('click');
  days.at(15).trigger('click');
  days.at(16).trigger('click');
  days.at(15).trigger('click');
  days.at(12).trigger('click');

  const emittedSelect = wrapper.emitted('select');
  expect(formatRange(emittedSelect[0][0])).toEqual('2010/1/16-');
  expect(formatRange(emittedSelect[1][0])).toEqual('2010/1/16-2010/1/17');
  expect(formatRange(emittedSelect[2][0])).toEqual('2010/1/16-');
  expect(formatRange(emittedSelect[3][0])).toEqual('2010/1/13-');
});

test('should not trigger select event when click disabled day', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      minDate,
      maxDate,
      poppable: false
    }
  });

  await later();

  wrapper
    .findAll('.van-calendar__day')
    .at(1)
    .trigger('click');

  expect(formatDate(wrapper.emitted('select'))).toBeFalsy();
});

test('confirm event when type is single', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      minDate,
      maxDate,
      poppable: false
    }
  });

  await later();

  wrapper
    .findAll('.van-calendar__day')
    .at(15)
    .trigger('click');

  expect(wrapper.emitted('confirm')).toBeFalsy();

  wrapper.find('.van-calendar__confirm').trigger('click');
  expect(formatDate(wrapper.emitted('confirm')[0][0])).toEqual('2010/1/16');
});

test('confirm event when type is range', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      type: 'range',
      minDate,
      maxDate,
      poppable: false
    }
  });

  await later();

  const days = wrapper.findAll('.van-calendar__day');
  days.at(15).trigger('click');
  days.at(18).trigger('click');

  expect(wrapper.emitted('confirm')).toBeFalsy();

  wrapper.find('.van-calendar__confirm').trigger('click');
  expect(formatRange(wrapper.emitted('confirm')[0][0])).toEqual(
    '2010/1/16-2010/1/19'
  );
});

test('default single date', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      poppable: false
    }
  });

  await later();

  wrapper.find('.van-calendar__confirm').trigger('click');
  expect(formatDate(wrapper.emitted('confirm')[0][0])).toEqual(formatDate(now));
});

test('default range date', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      type: 'range',
      poppable: false
    }
  });

  await later();

  wrapper.find('.van-calendar__confirm').trigger('click');
  expect(formatRange(wrapper.emitted('confirm')[0][0])).toEqual(
    formatRange([now, getNextDay(now)])
  );
});

test('reset method', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      minDate,
      maxDate,
      type: 'range',
      poppable: false
    }
  });

  await later();

  const days = wrapper.findAll('.van-calendar__day');
  days.at(15).trigger('click');
  days.at(18).trigger('click');

  wrapper.vm.reset();

  wrapper.find('.van-calendar__confirm').trigger('click');
  expect(formatRange(wrapper.emitted('confirm')[0][0])).toEqual(
    '2010/1/10-2010/1/11'
  );
});

test('set show-confirm to false', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      minDate,
      maxDate,
      type: 'range',
      poppable: false,
      showConfirm: false
    }
  });

  await later();

  const days = wrapper.findAll('.van-calendar__day');
  days.at(15).trigger('click');
  days.at(18).trigger('click');

  expect(formatRange(wrapper.emitted('confirm')[0][0])).toEqual(
    '2010/1/16-2010/1/19'
  );
});

test('row-height prop', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      minDate,
      maxDate,
      poppable: false,
      rowHeight: 50
    }
  });

  await later();

  expect(wrapper).toMatchSnapshot();
});

test('formatter prop', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      minDate,
      maxDate,
      poppable: false,
      formatter(day) {
        const date = day.date.getDate();

        switch (date) {
          case 11:
            day.topInfo = 'Top Info';
            break;
          case 12:
            day.bottomInfo = 'Bottom Info';
            break;
          case 13:
            day.text = 'Text';
            break;
          case 14:
            day.className = 'test';
            break;
        }

        return day;
      }
    }
  });

  await later();

  expect(wrapper).toMatchSnapshot();
});

test('title & footer slot', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      minDate,
      maxDate,
      poppable: false
    },
    scopedSlots: {
      title: () => 'Custom Title',
      footer: () => 'Custom Footer'
    }
  });

  await later();

  expect(wrapper).toMatchSnapshot();
});

test('should reset when type changed', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      minDate,
      maxDate,
      poppable: false
    }
  });

  await later();

  wrapper.find('.van-calendar__confirm').trigger('click');
  expect(formatDate(wrapper.emitted('confirm')[0][0])).toEqual('2010/1/10');

  wrapper.setProps({ type: 'range' });
  wrapper.find('.van-calendar__confirm').trigger('click');
  expect(formatRange(wrapper.emitted('confirm')[1][0])).toEqual(
    '2010/1/10-2010/1/11'
  );
});

test('default-date prop in single type', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      minDate,
      maxDate,
      defaultDate: getNextDay(minDate),
      poppable: false
    }
  });

  await later();

  wrapper.find('.van-calendar__confirm').trigger('click');
  expect(formatDate(wrapper.emitted('confirm')[0][0])).toEqual('2010/1/11');

  wrapper.setProps({ defaultDate: maxDate });
  wrapper.find('.van-calendar__confirm').trigger('click');
  expect(formatDate(wrapper.emitted('confirm')[1][0])).toEqual('2010/1/20');
});

test('default-date prop in range type', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      type: 'range',
      minDate,
      maxDate,
      poppable: false
    }
  });

  await later();

  wrapper.setProps({ defaultDate: [] });
  wrapper.find('.van-calendar__confirm').trigger('click');
  expect(wrapper.emitted('confirm')).toBeFalsy();

  const days = wrapper.findAll('.van-calendar__day');
  days.at(15).trigger('click');
  days.at(18).trigger('click');
  wrapper.find('.van-calendar__confirm').trigger('click');
  expect(formatRange(wrapper.emitted('confirm')[0][0])).toEqual(
    '2010/1/16-2010/1/19'
  );
});

test('popup wrapper', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      minDate,
      maxDate
    },
    listeners: {
      input(value) {
        wrapper.setProps({ value });
      }
    }
  });

  await later();
  expect(wrapper).toMatchSnapshot();

  wrapper.setProps({ value: true });
  await later();

  expect(wrapper).toMatchSnapshot();

  wrapper.find('.van-popup__close-icon').trigger('click');
  expect(wrapper.element.style.display).toEqual('none');
});

test('set show-mark prop to false', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      minDate,
      maxDate,
      showMark: false,
      poppable: false
    }
  });

  await later();

  expect(wrapper.find('.van-calendar__month-mark').element).toBeFalsy();
});

test('color prop when type is single', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      minDate,
      maxDate,
      color: 'blue',
      poppable: false
    }
  });

  await later();

  expect(wrapper).toMatchSnapshot();
});

test('color prop when type is range', async () => {
  const wrapper = mount(Calendar, {
    propsData: {
      defaultDate: [minDate, maxDate],
      type: 'range',
      minDate,
      maxDate,
      color: 'blue',
      poppable: false
    }
  });

  await later();

  expect(wrapper).toMatchSnapshot();
});
