import { getBackgroundColor, isThemeOrColorKey } from "../styles/themes.js";
import { applyTypography } from "../styles/typography.js";
import { select } from "../utils/emotion.js";
import { renderTypography } from "./typography/renderTypography.js";
import { Link } from "../router.js";
import { getFocusOutline } from "../styles/common.js";
import { Icon } from "./Icon/Icon.js";
import { Loading } from "./Loading.js";
import { Tooltip } from "./Tooltip.js";
import { UnstyledButton } from "./UnstyledButton.js";
import styled from "@emotion/styled";
import { uniqueId } from "lodash-es";
import { Fragment, forwardRef, useRef } from "react";
import { css, useTheme } from "@emotion/react";
import { jsx, jsxs } from "@emotion/react/jsx-runtime";
//#region src/components/Button.tsx
const buttonKinds = [
	"secondary",
	"primary",
	"ghost",
	"transparent",
	"green33",
	"green37",
	"purple55",
	"blue43",
	"blue39",
	"linkLight",
	"danger",
	"warning",
	"warningLight",
	"tertiary",
	"quaternary",
	"roundSingleChar",
	"roundIcon",
	"gray",
	"grayGradient",
	"gray99",
	"white21",
	"locked",
	"warningLight"
];
function resolveBackgroundColorKey(theme, kind, defaultKey) {
	let backgroundColorKey = theme.buttons.kinds[kind]?.[defaultKey];
	if (!backgroundColorKey && isThemeOrColorKey(kind)) backgroundColorKey = kind;
	const defaultBackgroundColor = theme.buttons[defaultKey];
	return getBackgroundColor(theme, backgroundColorKey, defaultBackgroundColor);
}
function resolveProp(prop, kind, defaultKey, theme) {
	return prop || theme.buttons.kinds[kind]?.[defaultKey] || theme.buttons[defaultKey];
}
function resolveProps(props, theme) {
	const isSingleCharRoundButton = Boolean(props.text && props.text.length === 1 && !props.icon);
	const isRoundIconButton = Boolean(!props.text && props.icon);
	const defaultKind = isSingleCharRoundButton ? "roundSingleChar" : isRoundIconButton ? "roundIcon" : "secondary";
	const { kind = defaultKind, size: sizeProp, gap: gapProp, paddingY: paddingYType = "regular", borderRadius, typography: typographyProp, ...rest } = props;
	const size = resolveProp(sizeProp, kind, "defaultSize", theme);
	const defaultPaddingY = resolveProp(null, kind, "defaultPaddingsY", theme)[size];
	const numericDefaultPaddingY = typeof defaultPaddingY === "number" ? defaultPaddingY : defaultPaddingY[paddingYType];
	const defaultPaddingX = resolveProp(null, kind, "defaultPaddingsX", theme)[size];
	const backgroundColor = resolveBackgroundColorKey(theme, kind, "defaultBackgroundColor");
	const borderColor = resolveBackgroundColorKey(theme, kind, "defaultBorderColor");
	const hoverBackgroundColor = resolveBackgroundColorKey(theme, kind, "defaultHoverBackgroundColor");
	const hoverBorderColor = resolveBackgroundColorKey(theme, kind, "defaultHoverBorderColor");
	const activeBackgroundColor = resolveBackgroundColorKey(theme, kind, "defaultActiveBackgroundColor");
	const activeBorderColor = resolveBackgroundColorKey(theme, kind, "defaultActiveBorderColor");
	const gap = resolveProp(props.gap, kind, "defaultGap", theme);
	const typography = {
		type: typographyProp?.type || resolveProp(null, kind, "defaultTypographyType", theme),
		color: typographyProp?.color || resolveProp(null, kind, "defaultColor", theme),
		size
	};
	return {
		...rest,
		kind,
		size,
		typography,
		...props.text ? {
			paddingY: numericDefaultPaddingY,
			paddingX: defaultPaddingX
		} : {
			paddingY: numericDefaultPaddingY,
			paddingX: numericDefaultPaddingY
		},
		borderRadius: kind === "roundSingleChar" || kind === "roundIcon" ? 999 : resolveProp(borderRadius, kind, "defaultBorderRadius", theme),
		backgroundColor,
		borderColor,
		hoverBackgroundColor,
		hoverBorderColor,
		activeBackgroundColor,
		activeBorderColor,
		gap
	};
}
const Button = forwardRef((props, ref) => {
	const { kind, typography, size, paddingX, paddingY, text, to, id, hash, externalLink, filename, toParams, onClick, onMouseEnter, onMouseDown, onMouseUp, onMouseLeave, onFocus, onBlur, icon, backgroundColor, borderColor, hoverBackgroundColor, hoverBorderColor, activeBackgroundColor, activeBorderColor, justifyContent = "center", gap, iconSide = "left", loading = false, loadingKind = "primary", fullWidth = false, disabled = false, mt = 0, ml = 0, mb = 0, type = "button", newTab = false, zIndex = void 0, tooltipText, borderRadius } = resolveProps(props, useTheme());
	const tooltipId = useRef(uniqueId());
	const defaultIconWidth = size === "ExtraSmall" ? 12 : 16;
	let currentIcon = null;
	if (loading) currentIcon = /* @__PURE__ */ jsx(ButtonIcon, {
		iconSide,
		text,
		typography,
		kind,
		paddingX,
		children: /* @__PURE__ */ jsx(Loading, {
			size: defaultIconWidth,
			center: false,
			kind: loadingKind
		})
	});
	else if (icon) currentIcon = /* @__PURE__ */ jsx(ButtonIcon, {
		iconSide,
		text,
		typography,
		kind,
		paddingX,
		children: /* @__PURE__ */ jsx(Icon, {
			...icon,
			width: icon.width || defaultIconWidth,
			square: icon.square === void 0 ? true : icon.square,
			color: icon.color || typography.color
		})
	});
	const content = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
		...tooltipText ? { "data-tooltip-id": tooltipId.current } : {},
		css: {
			display: "flex",
			alignItems: "center",
			justifyContent,
			gap: gap ? `${gap}px` : void 0,
			overflow: "hidden"
		},
		children: [
			iconSide === "left" && currentIcon,
			text && /* @__PURE__ */ jsx("div", {
				css: {
					textOverflow: "ellipsis",
					overflow: "hidden"
				},
				children: renderTypography(typography.type, {
					children: text,
					color: typography.color,
					size: typography.size
				})
			}),
			iconSide === "right" && currentIcon
		]
	}), tooltipText ? /* @__PURE__ */ jsx(Tooltip, {
		id: tooltipId.current,
		content: tooltipText
	}) : null] });
	const commonProps = {
		id,
		kind,
		type,
		typography,
		onClick,
		onMouseEnter,
		onMouseDown,
		onMouseUp,
		onMouseLeave,
		onFocus,
		onBlur,
		fullWidth,
		iconSide,
		paddingX,
		paddingY,
		backgroundColor,
		borderColor,
		hoverBackgroundColor,
		hoverBorderColor,
		activeBackgroundColor,
		activeBorderColor,
		isLoading: loading,
		disabled: disabled || loading,
		css: {
			marginTop: mt ? typeof mt === "number" ? `${mt}px` : "auto" : void 0,
			marginLeft: ml ? typeof ml === "number" ? `${ml}px` : "auto" : void 0,
			marginBottom: mb ? typeof mb === "number" ? `${mb}px` : "auto" : void 0
		},
		newTab,
		borderRadius,
		zIndex
	};
	if (to) return /* @__PURE__ */ jsx(ButtonLink, {
		...commonProps,
		to,
		params: toParams,
		hash,
		ref,
		children: content
	});
	return externalLink ? /* @__PURE__ */ jsx(ButtonHrefLink, {
		...commonProps,
		href: externalLink,
		download: filename,
		target: "_blank",
		ref,
		children: content
	}) : /* @__PURE__ */ jsx(StyledButton, {
		...commonProps,
		ref,
		children: content
	});
});
Button.displayName = "Button";
const buttonStyle = ({ paddingX, paddingY, kind, theme, disabled, isLoading, typography, fullWidth, zIndex, iconSide, borderColor: borderColorProp, borderRadius, backgroundColor, hoverBackgroundColor, hoverBorderColor, activeBackgroundColor, activeBorderColor }) => {
	const borderColor = borderColorProp || backgroundColor;
	return css`
    display: inline-flex;
    opacity: ${disabled && !isLoading ? .2 : 1};
    transition: opacity 0.2s;
    position: relative;

    ${zIndex && `z-index: ${zIndex};`}

    ${applyTypography(theme, typography.type, typography.size, typography.color)}

    &:focus-visible {
      outline: ${getFocusOutline({ theme })};
      /* Slightly different offset for buttons so the outline is visible: */
      outline-offset: 0px;
    }

    width: ${fullWidth ? "100%" : "fit-content"};

    & > * {
      width: 100%;
      text-align: center;
      white-space: nowrap;
      background-color: ${backgroundColor};
      box-sizing: content-box;
      border: 1px solid;
      border-color: ${borderColor};
      border-radius: ${typeof borderRadius === "number" ? `${borderRadius}px` : borderRadius};
      padding: ${paddingY}px ${paddingX}px;
      transition:
        background-color 0.2s ease-out,
        border-color 0.2s ease-out;

      &:hover {
        background-color: ${hoverBackgroundColor};
        border-color: ${hoverBorderColor};
      }

      &:active {
        background-color: ${activeBackgroundColor};
        border-color: ${activeBorderColor};
      }
    }
  `;
};
const ButtonIcon = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  ${({ iconSide, paddingX }) => `${iconSide}: ${paddingX}px;`}
`;
const LinkWithoutTypography = forwardRef((props, ref) => {
	return /* @__PURE__ */ jsx(Link, {
		...props,
		ref
	});
});
const StyledButton = styled(UnstyledButton)`
  ${(props) => buttonStyle(props)}
`;
const ButtonLink = styled(LinkWithoutTypography)`
  ${(props) => buttonStyle(props)}
`;
const ButtonHrefLink = styled.a`
  ${(props) => buttonStyle(props)}
`;
const ButtonSelector = (prepend = "", append = "") => `${prepend}*:is(${select(StyledButton)}, ${select(ButtonLink)}, ${select(ButtonHrefLink)})${append}`;
//#endregion
export { Button, ButtonSelector, StyledButton, buttonKinds };
