<script>
  /**
   * Specify the kind of button
   * @type {"primary" | "secondary" | "tertiary" | "ghost" | "danger" | "danger-tertiary" | "danger-ghost"}
   */
  export let kind = "primary";

  /**
   * Specify the size of button
   * @type {"default" | "field" | "small"}
   */
  export let size = "default";

  /** Set to `true` for the icon-only variant */
  export let hasIconOnly = false;

  /**
   * Specify the icon from `carbon-icons-svelte` to render
   * @type {typeof import("carbon-icons-svelte/lib/Add16").default}
   */
  export let icon = undefined;

  /**
   * Specify the ARIA label for the button icon
   * @type {string}
   */
  export let iconDescription = undefined;

  /**
   * Set the alignment of the tooltip relative to the icon
   * `hasIconOnly` must be set to `true`
   * @type {"start" | "center" | "end"}
   */
  export let tooltipAlignment = undefined;

  /**
   * Set the position of the tooltip relative to the icon
   * @type {"top" | "right" | "bottom" | "left"}
   */
  export let tooltipPosition = undefined;

  /**
   * Set to `true` to render a custom HTML element
   * Props are destructured as `props` in the default slot (e.g. <Button let:props><div {...props}>...</div></Button>)
   */
  export let as = false;

  /** Set to `true` to display the skeleton state */
  export let skeleton = false;

  /** Set to `true` to disable the button */
  export let disabled = false;

  /**
   * Set the `href` to use an anchor link
   * @type {string}
   */
  export let href = undefined;

  /** Specify the tabindex */
  export let tabindex = "0";

  /** Specify the `type` attribute for the button element */
  export let type = "button";

  /**
   * Obtain a reference to the HTML element
   * @type {null | HTMLAnchorElement | HTMLButtonElement}
   */
  export let ref = null;

  import { getContext } from "svelte";
  import ButtonSkeleton from "./ButtonSkeleton.svelte";

  const ctx = getContext("ComposedModal");

  $: if (ctx && ref) {
    ctx.declareRef(ref);
  }
  $: buttonProps = {
    role: "button",
    type: href && !disabled ? undefined : type,
    tabindex,
    disabled,
    href,
    ...$$restProps,
    class: [
      "bx--btn",
      size === "field" && "bx--btn--field",
      size === "small" && "bx--btn--sm",
      kind && `bx--btn--${kind}`,
      disabled && "bx--btn--disabled",
      hasIconOnly && "bx--btn--icon-only",
      hasIconOnly && "bx--tooltip__trigger",
      hasIconOnly && "bx--tooltip--a11y",
      hasIconOnly && tooltipPosition && `bx--tooltip--${tooltipPosition}`,
      hasIconOnly &&
        tooltipAlignment &&
        `bx--tooltip--align-${tooltipAlignment}`,
      $$restProps.class,
    ]
      .filter(Boolean)
      .join(" "),
  };
</script>

{#if skeleton}
  <ButtonSkeleton
    href="{href}"
    size="{size}"
    {...$$restProps}
    style="{hasIconOnly && 'width: 3rem;'}"
    on:click
    on:mouseover
    on:mouseenter
    on:mouseleave
  />
{:else}
  {#if as}
    <slot props="{buttonProps}" />
  {:else if href && !disabled}
    <!-- svelte-ignore a11y-missing-attribute -->
    <a
      bind:this="{ref}"
      {...buttonProps}
      on:click
      on:mouseover
      on:mouseenter
      on:mouseleave
    >
      {#if hasIconOnly}
        <span class:bx--assistive-text="{true}">{iconDescription}</span>
      {/if}
      <slot />
      {#if icon}
        <svelte:component
          this="{icon}"
          aria-hidden="true"
          class="bx--btn__icon"
          aria-label="{iconDescription}"
        />
      {/if}
    </a>
  {:else}
    <button
      bind:this="{ref}"
      {...buttonProps}
      on:click
      on:mouseover
      on:mouseenter
      on:mouseleave
    >
      {#if hasIconOnly}
        <span class:bx--assistive-text="{true}">{iconDescription}</span>
      {/if}
      <slot />
      {#if icon}
        <svelte:component
          this="{icon}"
          aria-hidden="true"
          class="bx--btn__icon"
          aria-label="{iconDescription}"
        />
      {/if}
    </button>
  {/if}
{/if}
