/**
 * Copyright (c) HashiCorp, Inc.
 * SPDX-License-Identifier: MPL-2.0
 */

import Component from '@ember/component';
import { inject as service } from '@ember/service';

export default Component.extend({
  dom: service('dom'),
  tagName: '',
  checked: false,
  onchange: function () {},
  // TODO: reserved for the moment but we don't need it yet
  onblur: function () {},
  init: function () {
    this._super(...arguments);
    this.guid = this.dom.guid(this);
    this._listeners = this.dom.listeners();
  },
  willDestroyElement: function () {
    this._super(...arguments);
    this._listeners.remove();
  },
  didReceiveAttrs: function () {
    this._super(...arguments);
    if (this.checked) {
      this.addClickOutsideListener();
    } else {
      this._listeners.remove();
    }
  },
  addClickOutsideListener: function () {
    // default onblur event
    this._listeners.remove();
    this._listeners.add(this.dom.document(), 'click', (e) => {
      if (this.dom.isOutside(this.label, e.target)) {
        if (this.dom.isOutside(this.label.nextElementSibling, e.target)) {
          if (this.input.checked) {
            this.input.checked = false;
            // TODO: This should be an event
            this.onchange({ target: this.input });
          }
          this._listeners.remove();
        }
      }
    });
  },
  actions: {
    click: function (e) {
      // only preventDefault if the target isn't an external link
      // TODO: this should be changed for an explicit close
      if ((e.target.rel || '').indexOf('noopener') === -1) {
        e.preventDefault();
      }
      this.input.checked = !this.input.checked;
      // manually dispatched mouse events have a detail = 0
      // real mouse events have the number of click counts
      if (e.detail !== 0) {
        e.target.blur();
      }
      this.actions.change.apply(this, [e]);
    },
    change: function (e) {
      if (this.input.checked) {
        this.addClickOutsideListener();
      }
      // TODO: This should be an event
      this.onchange({ target: this.input });
    },
  },
});
