import { Component, Element, Host, Method, Prop, h } from '@stencil/core';
import { closestElementCrossShadowBoundary } from '../../utils';
import { HiddenFormInputSlot, connectForm, disconnectForm } from '../../utils';
/** @slot - A slot for adding text and a component that can be labeled. */
export class Radio {
  constructor() {
    /** initial render status */
    this.isInitialRender = true;
    //--------------------------------------------------------------------------
    //
    // Private Methods
    //
    //--------------------------------------------------------------------------
    this.onClick = () => {
      this.radioGroup.forEach((radio) => {
        radio.checked = false;
      });
      this.checked = true;
      this.setFocus();
    };
    this.onKeyDown = (event) => {
      const keys = ['ArrowLeft', 'ArrowUp', 'ArrowRight', 'ArrowDown', ' '];
      const key = event.key;
      if (keys.indexOf(key) === -1)
        return;
      event.preventDefault();
      if (key === ' ') {
        this.onClick();
        return;
      }
      const enabledRadioGroup = this.radioGroup.filter(({ disabled }) => !disabled);
      const getRoundRobinIndex = (index, total, next) => {
        index = next ? index + 1 : Math.max(index - 1, -1);
        return (index + total) % total;
      };
      const selectItem = (items, selectedIndex) => {
        items[selectedIndex].click();
      };
      let currentIndex = 0;
      enabledRadioGroup.some(({ checked }, index) => {
        if (checked) {
          currentIndex = index;
          return true;
        }
      });
      if (key === 'ArrowLeft' || key === 'ArrowUp') {
        selectItem(enabledRadioGroup, getRoundRobinIndex(currentIndex, enabledRadioGroup.length));
      }
      else if (key === 'ArrowDown' || key === 'ArrowRight') {
        selectItem(enabledRadioGroup, getRoundRobinIndex(currentIndex, enabledRadioGroup.length, true));
      }
    };
    //--------------------------------------------------------------------------
    //
    // Props
    //
    //--------------------------------------------------------------------------
    /** aligns input and label */
    this.alignment = 'start';
    /** host's checked state */
    // eslint-disable-next-line @stencil/strict-mutable
    this.checked = false;
    /** disables radio from interaction */
    this.disabled = false;
    /** sets radio as required, validation to be implemented by user */
    this.required = false;
  }
  //--------------------------------------------------------------------------
  //
  // Public Methods
  //
  //--------------------------------------------------------------------------
  /**
   * Sets blur on `abds-radio`
   * @internal
   */
  async setBlur() {
    var _a;
    (_a = this.toggleEl) === null || _a === void 0 ? void 0 : _a.blur();
  }
  /**
   * Sets focus on native `input` in `abds-radio`
   * @internal
   */
  async setFocus() {
    var _a;
    (_a = this.toggleEl) === null || _a === void 0 ? void 0 : _a.focus();
  }
  //--------------------------------------------------------------------------
  //
  // Lifecycle Methods
  //
  //--------------------------------------------------------------------------
  componentWillLoad() {
    if (!this.host.id)
      this.host.setAttribute('id', `abds-radio-id${crypto.getRandomValues(new Uint16Array(1))[0]}`);
  }
  componentDidRender() {
    if (this.isInitialRender)
      this.isInitialRender = false;
  }
  connectedCallback() {
    /**
     * Finds closest parent <form> element OR if there isn't one, it goes to
     * the the document root to find all radio buttons to treat as siblings in
     * this radio group. If it goes to the document root and there are other
     * radios with the same name attr within forms in the same document, they
     * would all be added to this effective radio group, which is not desired
     * or native behavior. Use unique names between groups of radio buttons.
     */
    const radioGroupDOMRoot = closestElementCrossShadowBoundary(this.host, 'form') || this.host.ownerDocument.documentElement;
    this.radioGroup = [
      ...radioGroupDOMRoot.querySelectorAll(`abds-radio[name=${this.name}]`),
    ];
    connectForm(this);
  }
  disconnectedCallback() {
    disconnectForm(this);
  }
  render() {
    return (h(Host, { onClick: this.disabled ? null : this.onClick, onKeyDown: this.disabled ? null : this.onKeyDown },
      h(HiddenFormInputSlot, { component: this, type: "radio" }),
      h("div", { "aria-checked": this.checked.toString(), "aria-labelledby": "radio-label", class: "radio-container", ref: (toggleEl) => (this.toggleEl = toggleEl), role: "radio", tabIndex: this.disabled ? undefined : 0 }),
      h("abds-label", { for: this.host.id || null, id: "radio-label", required: this.required, tabindex: "-1", tooltip: this.tooltip, weight: "medium" },
        h("slot", null))));
  }
  static get is() { return "abds-radio"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() { return {
    "$": ["radio.css"]
  }; }
  static get styleUrls() { return {
    "$": ["radio.css"]
  }; }
  static get properties() { return {
    "alignment": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "Alignment",
        "resolved": "\"end\" | \"start\"",
        "references": {
          "Alignment": {
            "location": "import",
            "path": "../types"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "aligns input and label"
      },
      "attribute": "alignment",
      "reflect": true,
      "defaultValue": "'start'"
    },
    "checked": {
      "type": "boolean",
      "mutable": true,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "host's checked state"
      },
      "attribute": "checked",
      "reflect": true,
      "defaultValue": "false"
    },
    "disabled": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "disables radio from interaction"
      },
      "attribute": "disabled",
      "reflect": true,
      "defaultValue": "false"
    },
    "name": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": true,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "host's name"
      },
      "attribute": "name",
      "reflect": true
    },
    "required": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "sets radio as required, validation to be implemented by user"
      },
      "attribute": "required",
      "reflect": true,
      "defaultValue": "false"
    },
    "tooltip": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "optional tooltip string will cause tooltip icon to be shown"
      },
      "attribute": "tooltip",
      "reflect": true
    },
    "value": {
      "type": "string",
      "mutable": true,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": true,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "value to be submitted to form if selected"
      },
      "attribute": "value",
      "reflect": true
    }
  }; }
  static get methods() { return {
    "setBlur": {
      "complexType": {
        "signature": "() => Promise<void>",
        "parameters": [],
        "references": {
          "Promise": {
            "location": "global"
          }
        },
        "return": "Promise<void>"
      },
      "docs": {
        "text": "Sets blur on `abds-radio`",
        "tags": [{
            "name": "internal",
            "text": undefined
          }]
      }
    },
    "setFocus": {
      "complexType": {
        "signature": "() => Promise<void>",
        "parameters": [],
        "references": {
          "Promise": {
            "location": "global"
          }
        },
        "return": "Promise<void>"
      },
      "docs": {
        "text": "Sets focus on native `input` in `abds-radio`",
        "tags": [{
            "name": "internal",
            "text": undefined
          }]
      }
    }
  }; }
  static get elementRef() { return "host"; }
}
//# sourceMappingURL=radio.js.map