/*!
 * Portions of this file are based on code from chakra-ui.
 * MIT Licensed, Copyright (c) 2019 Segun Adebayo.
 *
 * Credits to the Chakra UI team:
 * https://github.com/chakra-ui/chakra-ui/blob/7d7e04d53d871e324debe0a2cb3ff44d7dbf3bca/packages/components/button/src/button.tsx
 */
import { createTagName } from "@hope-ui/primitives";
import { createHopeComponent, hope, mergeThemeProps, STYLE_CONFIG_PROP_NAMES, } from "@hope-ui/styles";
import { mergeRefs } from "@hope-ui/utils";
import { clsx } from "clsx";
import { createMemo, createSignal, onMount, Show, splitProps } from "solid-js";
import { mergeDefaultProps } from "../utils";
import { useButtonStyleConfig } from "./button.styles";
import { ButtonContext, useButtonContext } from "./button-context";
import { useButtonGroupContext } from "./button-group";
import { ButtonIcon } from "./button-icon";
import { ButtonLoader } from "./button-loader";
import { isButton } from "./is-button";
/**
 * Button is used to trigger an action or event,
 * such as submitting a form, opening a dialog, canceling an action, or performing a delete operation.
 */
export const Button = createHopeComponent(props => {
    let ref;
    const buttonGroupContext = useButtonGroupContext();
    const propsWithButtonGroupDefaults = mergeDefaultProps({
        get variant() {
            return buttonGroupContext?.variant;
        },
        get colorScheme() {
            return buttonGroupContext?.colorScheme;
        },
        get size() {
            return buttonGroupContext?.size;
        },
        get isDisabled() {
            return buttonGroupContext?.isDisabled;
        },
    }, props);
    props = mergeThemeProps("Button", {
        loaderPlacement: "start",
    }, propsWithButtonGroupDefaults);
    const [local, contentProps, styleConfigProps, others] = splitProps(props, [
        "ref",
        "class",
        "type",
        "as",
        "isLoading",
        "loaderPlacement",
        "loadingText",
        "loader",
        "isDisabled",
    ], ["children", "leftIcon", "rightIcon"], [...STYLE_CONFIG_PROP_NAMES, "colorScheme", "variant", "size", "isFullWidth", "isIconButton"]);
    const tagName = createTagName(() => ref, () => props.as || "button");
    const [isNativeButton, setIsNativeButton] = createSignal(tagName() != null && isButton({ tagName: tagName(), type: local.type }));
    const type = createMemo(() => {
        if (local.type != null) {
            return local.type;
        }
        return isNativeButton() ? "button" : undefined;
    });
    const { baseClasses, styleOverrides } = useButtonStyleConfig("Button", styleConfigProps);
    onMount(() => {
        ref != null && setIsNativeButton(isButton(ref));
    });
    return (<ButtonContext.Provider value={{ baseClasses, styleOverrides }}>
      <hope.button as={local.as} ref={mergeRefs(el => (ref = el), local.ref)} role={!isNativeButton() && tagName() !== "a" ? "button" : undefined} type={type()} tabIndex={!isNativeButton() ? 0 : undefined} disabled={local.isDisabled} data-loading={local.isLoading || undefined} class={clsx(baseClasses().root, local.class)} __css={styleOverrides().root} {...others}>
        <Show when={local.isLoading && local.loaderPlacement === "start"}>
          <ButtonLoader hasLoadingText={!!local.loadingText}>{local.loader}</ButtonLoader>
        </Show>
        <Show when={local.isLoading} fallback={<ButtonContent {...contentProps}/>}>
          <Show when={local.loadingText} fallback={<span style={{ opacity: 0 }}>
                <ButtonContent {...contentProps}/>
              </span>}>
            {local.loadingText}
          </Show>
        </Show>
        <Show when={local.isLoading && local.loaderPlacement === "end"}>
          <ButtonLoader hasLoadingText={!!local.loadingText}>{local.loader}</ButtonLoader>
        </Show>
      </hope.button>
    </ButtonContext.Provider>);
});
function ButtonContent(props) {
    const buttonContext = useButtonContext();
    return (<>
      <Show when={props.leftIcon}>
        <ButtonIcon class={buttonContext.baseClasses().leftIcon} __css={buttonContext.styleOverrides().leftIcon}>
          {props.leftIcon}
        </ButtonIcon>
      </Show>
      {props.children}
      <Show when={props.rightIcon}>
        <ButtonIcon class={buttonContext.baseClasses().rightIcon} __css={buttonContext.styleOverrides().rightIcon}>
          {props.rightIcon}
        </ButtonIcon>
      </Show>
    </>);
}
