import { query, state, property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { literal, html } from 'lit/static-html.js';
import { boolean } from '../../internal/boolean.mjs';
import { FlowRdfFormControl } from '../../internal/flow-ui-rdf-element.mjs';
import { FormControlController, validValidityState } from '../../internal/form.mjs';
import { HasSlotController } from '../../internal/slot.mjs';
import { watch } from '../../internal/watch.mjs';
import { LocalizeController } from '../../utilities/localize.mjs';
import buttonStyles from './button.styles.mjs';

var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result)
    __defProp(target, key, result);
  return result;
};
class FlowUiButton extends FlowRdfFormControl {
  constructor() {
    super(...arguments);
    this.formControlController = new FormControlController(this, {
      form: (input) => {
        if (input.hasAttribute("form")) {
          const doc = input.getRootNode();
          const formId = input.getAttribute("form");
          return doc.getElementById(formId);
        }
        return input.closest("form");
      },
      assumeInteractionOn: ["click"]
    });
    this.hasSlotController = new HasSlotController(this, "[default]", "prefix", "suffix");
    this.localize = new LocalizeController(this);
    this.hasFocus = false;
    this.label = "";
    this.variant = "default";
    this.size = "medium";
    this.caret = false;
    this.disabled = false;
    this.loading = false;
    this.outline = false;
    this.pill = false;
    this.fabCircle = false;
    this.fabSquare = false;
    this.type = "button";
    this.name = "";
    this.value = "";
    this.href = "";
    this.rel = "noreferrer noopener";
  }
  /** Gets the validity state object */
  get validity() {
    if (this.isButton()) {
      return this.button.validity;
    }
    return validValidityState;
  }
  /** Gets the validation message */
  get validationMessage() {
    if (this.isButton()) {
      return this.button.validationMessage;
    }
    return "";
  }
  connectedCallback() {
    super.connectedCallback();
    this.caret = boolean(this.caret, true);
    this.disabled = boolean(this.disabled, true);
    this.loading = boolean(this.loading, true);
    this.outline = boolean(this.outline, true);
    this.pill = boolean(this.pill, true);
    this.fabCircle = boolean(this.fabCircle, true);
    this.fabSquare = boolean(this.fabSquare, true);
    this.handleHostClick = this.handleHostClick.bind(this);
    this.addEventListener("click", this.handleHostClick);
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    this.removeEventListener("click", this.handleHostClick);
  }
  firstUpdated() {
    if (this.isButton()) {
      this.formControlController.updateValidity();
    }
  }
  handleBlur() {
    this.hasFocus = false;
    this.emit("flow-ui-blur");
  }
  handleFocus() {
    this.hasFocus = true;
    this.emit("flow-ui-focus");
  }
  handleClick() {
    if (this.type === "submit") {
      this.formControlController.submit(this);
    }
    if (this.type === "reset") {
      this.formControlController.reset(this);
    }
  }
  handleHostClick(event) {
    if (this.disabled || this.loading) {
      event.preventDefault();
      event.stopImmediatePropagation();
    }
  }
  handleInvalid(event) {
    this.formControlController.setValidity(false);
    this.formControlController.emitInvalidEvent(event);
  }
  isButton() {
    return this.href ? false : true;
  }
  isLink() {
    return this.href ? true : false;
  }
  handleDisabledChange() {
    if (this.isButton()) {
      this.formControlController.setValidity(this.disabled);
    }
  }
  /** Simulates a click on the button. */
  click() {
    this.button.click();
  }
  /** Sets focus on the button. */
  focus(options) {
    this.button.focus(options);
  }
  /** Removes focus from the button. */
  blur() {
    this.button.blur();
  }
  /** Checks for validity but does not show a validation message. Returns `true` when valid and `false` when invalid. */
  checkValidity() {
    if (this.isButton()) {
      return this.button.checkValidity();
    }
    return true;
  }
  /** Gets the associated form, if one exists. */
  getForm() {
    return this.formControlController.getForm();
  }
  /** Checks for validity and shows the browser's validation message if the control is invalid. */
  reportValidity() {
    if (this.isButton()) {
      return this.button.reportValidity();
    }
    return true;
  }
  /** Sets a custom validation message. Pass an empty string to restore validity. */
  setCustomValidity(message) {
    if (this.isButton()) {
      this.button.setCustomValidity(message);
      this.formControlController.updateValidity();
    }
  }
  render() {
    const isLink = this.isLink();
    const tag = isLink ? literal`a` : literal`button`;
    return html`
      <${tag}
        part="base"
        class=${classMap({
      button: true,
      "button--default": this.variant === "default",
      "button--primary": this.variant === "primary",
      "button--secondary": this.variant === "secondary",
      "button--success": this.variant === "success",
      "button--neutral": this.variant === "neutral",
      "button--warning": this.variant === "warning",
      "button--danger": this.variant === "danger",
      "button--text": this.variant === "text",
      "button--small": this.size === "small",
      "button--medium": this.size === "medium",
      "button--large": this.size === "large",
      "button--caret": this.caret,
      "button--fab": this.fabCircle || this.fabSquare,
      "button--circle": this.fabCircle,
      "button--square": this.fabSquare,
      "button--disabled": this.disabled,
      "button--focused": this.hasFocus,
      "button--loading": this.loading,
      "button--standard": !this.outline,
      "button--outline": this.outline,
      "button--pill": this.pill,
      "button--rtl": this.localize.dir() === "rtl",
      "button--has-label": this.hasSlotController.test("[default]"),
      "button--has-prefix": this.hasSlotController.test("prefix"),
      "button--has-suffix": this.hasSlotController.test("suffix")
    })}
        ?disabled=${ifDefined(isLink ? void 0 : this.disabled)}
        type=${ifDefined(isLink ? void 0 : this.type)}
        title=${this.label}
        name=${ifDefined(isLink ? void 0 : this.name)}
        value=${ifDefined(isLink ? void 0 : this.value)}
        href=${ifDefined(isLink ? this.href : void 0)}
        target=${ifDefined(isLink ? this.target : void 0)}
        download=${ifDefined(isLink ? this.download : void 0)}
        rel=${ifDefined(isLink ? this.rel : void 0)}
        role=${ifDefined(isLink ? void 0 : "button")}
        aria-disabled=${this.disabled ? "true" : "false"}
        tabindex=${this.disabled ? "-1" : "0"}
        @blur=${this.handleBlur}
        @focus=${this.handleFocus}
        @invalid=${this.isButton() ? this.handleInvalid : null}
        @click=${this.handleClick}
      >
        <slot name="prefix" part="prefix" class="button__prefix"></slot>
        <slot part="label" class="button__label"></slot>
        <slot name="suffix" part="suffix" class="button__suffix"></slot>
        ${this.caret ? html`
                <flow-ui-icon part="caret" class="button__caret" library="system" name="caret"></flow-ui-icon>
              ` : ""}
        ${this.loading ? html`
                <flow-ui-progress-ring
                  size=${this.size === "large" ? "medium" : this.size}
                  indeterminate
                ></flow-ui-progress-ring>
              ` : ""}
      </${tag}>
    `;
  }
}
FlowUiButton.styles = buttonStyles;
__decorateClass([
  query(".button")
], FlowUiButton.prototype, "button", 2);
__decorateClass([
  state()
], FlowUiButton.prototype, "hasFocus", 2);
__decorateClass([
  property()
], FlowUiButton.prototype, "label", 2);
__decorateClass([
  property({ reflect: true })
], FlowUiButton.prototype, "variant", 2);
__decorateClass([
  property({ reflect: true })
], FlowUiButton.prototype, "size", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], FlowUiButton.prototype, "caret", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], FlowUiButton.prototype, "disabled", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], FlowUiButton.prototype, "loading", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], FlowUiButton.prototype, "outline", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], FlowUiButton.prototype, "pill", 2);
__decorateClass([
  property({ type: Boolean, reflect: true, attribute: "fab-circle" })
], FlowUiButton.prototype, "fabCircle", 2);
__decorateClass([
  property({ type: Boolean, reflect: true, attribute: "fab-square" })
], FlowUiButton.prototype, "fabSquare", 2);
__decorateClass([
  property()
], FlowUiButton.prototype, "type", 2);
__decorateClass([
  property()
], FlowUiButton.prototype, "name", 2);
__decorateClass([
  property()
], FlowUiButton.prototype, "value", 2);
__decorateClass([
  property()
], FlowUiButton.prototype, "href", 2);
__decorateClass([
  property()
], FlowUiButton.prototype, "target", 2);
__decorateClass([
  property()
], FlowUiButton.prototype, "rel", 2);
__decorateClass([
  property()
], FlowUiButton.prototype, "download", 2);
__decorateClass([
  property()
], FlowUiButton.prototype, "form", 2);
__decorateClass([
  property({ attribute: "formaction" })
], FlowUiButton.prototype, "formAction", 2);
__decorateClass([
  property({ attribute: "formenctype" })
], FlowUiButton.prototype, "formEnctype", 2);
__decorateClass([
  property({ attribute: "formmethod" })
], FlowUiButton.prototype, "formMethod", 2);
__decorateClass([
  property({ attribute: "formnovalidate", type: Boolean })
], FlowUiButton.prototype, "formNoValidate", 2);
__decorateClass([
  property({ attribute: "formtarget" })
], FlowUiButton.prototype, "formTarget", 2);
__decorateClass([
  watch("disabled", { waitUntilFirstUpdate: true })
], FlowUiButton.prototype, "handleDisabledChange", 1);

export { FlowUiButton as default };
