import { test } from 'ember-qunit';
import sinon from 'sinon';
import hbs from 'htmlbars-inline-precompile';
import moduleForComponent from 'web-client/tests/helpers/module-for-component';
import { KEY_CODES } from 'web-client/utilities/keyboard';

const MODAL_CONTAINER_SELECTOR = '[data-test-selector="modal-container"]';
const MODAL_CONTENT_SELECTOR = '[data-test-selector="modal-content"]';
const MODAL_CLOSE_SELECTOR = '[data-test-selector="modal-close-btn"]';

moduleForComponent('common/modal-dialog', 'Integration | Component | common/modal-dialog', {
  beforeEach() {
    this.onOpenSpy = sinon.spy();
    this.onCloseSpy = sinon.spy();

    this.set('customHeight', '');
    this.set('customWidth', '');
    this.set('onOpen', this.onOpenSpy);
    this.set('onClose', this.onCloseSpy);
    this.set('renderInPlace', true);
    this.set('showModal', null);

    this.template = hbs`
      {{#common/modal-dialog
        customHeight=customHeight
        customWidth=customWidth
        onClose=onClose
        onOpen=onOpen
        renderInPlace=renderInPlace
        showModal=showModal
      }}
        <div data-test-selector="nested-div"></div>
      {{/common/modal-dialog}}
    `;
    this.render(this.template);
  }
});

test('rendering the modal', function(assert) {
  assert.ok(this.onOpenSpy.called, 'should have invoked the provided onOpen action');
  assert.elementCount(MODAL_CONTAINER_SELECTOR, 1, 'should show the modal');
  assert.elementCount('[data-test-selector="nested-div"]', 1, 'should render modal content');
  let $modalContent = this.$(MODAL_CONTENT_SELECTOR);
  assert.equal($modalContent.css('width'), '420px', 'should set a default width');
});

test('when showModal is set to false', function(assert) {
  assert.expect(1);

  this.set('showModal', false);
  assert.elementCount(MODAL_CONTAINER_SELECTOR, 0, 'hides the modal');
});

test('when showModal is set to true', function(assert) {
  assert.expect(1);

  this.set('showModal', true);
  assert.elementCount(MODAL_CONTAINER_SELECTOR, 1, 'does not hide the modal');
});

test('clicking the modal close button', function(assert) {
  this.$(MODAL_CLOSE_SELECTOR).click();

  assert.ok(this.onCloseSpy.called, 'should invoke the provided onClose action');
  assert.elementCount(MODAL_CONTAINER_SELECTOR, 0, 'should dismiss the modal');
});

test('clicking outside of the modal content area', function(assert) {
  this.$(MODAL_CONTAINER_SELECTOR).click();

  assert.ok(this.onCloseSpy.called, 'should invoke the provided onClose action');
  assert.elementCount(MODAL_CONTAINER_SELECTOR, 0, 'should dismiss the modal');
});

test('clicking outside of the modal content area when showModal is set to true', function(assert) {
  this.set('showModal', true);
  this.$(MODAL_CONTAINER_SELECTOR).click();

  assert.ok(this.onCloseSpy.called, 'should invoke the provided onClose action');
  assert.elementCount(MODAL_CONTAINER_SELECTOR, 1, 'should not dismiss the modal');
});

test('clicking the modal content area', function(assert) {
  this.$(MODAL_CONTENT_SELECTOR).click();

  assert.elementCount(MODAL_CONTAINER_SELECTOR, 1, 'should not dismiss the modal');
  assert.notOk(this.onCloseSpy.called, 'should not invoke the provided onClose action');
});

test('pressing the escape key', function(assert) {
  this.$(document.body).trigger({
    type: 'keydown',
    keyCode: KEY_CODES['esc']
  });

  assert.ok(this.onCloseSpy.called, 'should invoke the provided onClose action');
  assert.elementCount(MODAL_CONTAINER_SELECTOR, 0, 'should dismiss the modal');
});

test('setting a custom modal size', function(assert) {
  let expectedHeight = '500px';
  let expectedWidth = '500px';

  this.set('customHeight', expectedHeight);
  this.set('customWidth', expectedWidth);

  assert.elementCount(MODAL_CONTAINER_SELECTOR, 1, 'should show the modal');
  let $modalContent = this.$(MODAL_CONTENT_SELECTOR);
  assert.equal($modalContent.css('height'), expectedHeight, 'should set a custom height style');
  assert.equal($modalContent.css('width'), expectedWidth, 'should set a custom width style');
});
