import { get, set } from '@ember/object';
import { inject as service } from '@ember/service';
import DomBufferComponent from 'consul-ui/components/dom-buffer';
import SlotsMixin from 'block-slots';
import WithResizing from 'consul-ui/mixins/with-resizing';

import templatize from 'consul-ui/utils/templatize';
export default DomBufferComponent.extend(SlotsMixin, WithResizing, {
  dom: service('dom'),
  checked: true,
  height: null,
  // dialog is a reference to the modal-dialog 'panel' so its 'window'
  dialog: null,
  overflowingClass: 'overflowing',
  onclose: function() {},
  onopen: function() {},
  _open: function(e) {
    set(this, 'checked', true);
    if (this.height === null) {
      if (this.element) {
        const dialogPanel = this.dom.element('[role="dialog"] > div > div', this.element);
        const rect = dialogPanel.getBoundingClientRect();
        set(this, 'dialog', dialogPanel);
        set(this, 'height', rect.height);
      }
    }
    this.didAppear();
    this.onopen(e);
  },
  didAppear: function() {
    this._super(...arguments);
    if (this.checked) {
      this.dom.root().classList.add(...templatize(['with-modal']));
    }
  },
  _close: function(e) {
    set(this, 'checked', false);
    const dialogPanel = this.dialog;
    if (dialogPanel) {
      const overflowing = this.overflowingClass;
      if (dialogPanel.classList.contains(overflowing)) {
        dialogPanel.classList.remove(overflowing);
      }
    }
    // TODO: should we make a didDisappear?
    this.dom.root().classList.remove(...templatize(['with-modal']));
    this.onclose(e);
  },
  didReceiveAttrs: function() {
    this._super(...arguments);
    // TODO: Why does setting name mean checked it false?
    // It's because if it has a name then it is likely to be linked
    // to HTML state rather than just being added via HTMLBars
    // and therefore likely to be immediately on the page
    // It's not our usecase just yet, but this should check the state
    // of the thing its linked to, incase that has a `checked` of true
    // right now we know ours is always false.
    if (this.name) {
      set(this, 'checked', false);
    }
    if (this.element) {
      if (this.checked) {
        // TODO: probably need an event here
        // possibly this.element for the target
        // or find the input
        this._open({ target: {} });
      }
    }
  },
  didInsertElement: function() {
    this._super(...arguments);
    if (this.checked) {
      // TODO: probably need an event here
      // possibly this.element for the target
      // or find the input
      this._open({ target: {} });
    }
  },
  didDestroyElement: function() {
    this._super(...arguments);
    this.dom.root().classList.remove(...templatize(['with-modal']));
  },
  resize: function(e) {
    if (this.checked) {
      const height = this.height;
      if (height !== null) {
        const dialogPanel = this.dialog;
        const overflowing = this.overflowingClass;
        if (height > e.detail.height) {
          if (!dialogPanel.classList.contains(overflowing)) {
            dialogPanel.classList.add(overflowing);
          }
          return;
        } else {
          if (dialogPanel.classList.contains(overflowing)) {
            dialogPanel.classList.remove(overflowing);
          }
        }
      }
    }
  },
  actions: {
    change: function(e) {
      if (get(e, 'target.checked')) {
        this._open(e);
      } else {
        this._close(e);
      }
    },
    close: function() {
      const $close = this.dom.element('#modal_close');
      $close.checked = true;
      const $input = this.dom.element('input[name="modal"]', this.element);
      $input.onchange({ target: $input });
    },
  },
});
