@use 'sass:map';

@use 'common/var' as *;
@use 'mixins/button' as *;
@use 'mixins/mixins' as *;
@use 'mixins/utils' as *;
@use 'mixins/var' as *;

$button-icon-span-gap: () !default;
$button-icon-span-gap: map.merge(
	(
		'large': 8px,
		'default': 6px,
		'small': 4px,
	),
	$button-icon-span-gap
);

@include b(button) {
	@include set-component-css-var('button', $button);
}

@include b(button) {
	display: inline-flex;
	justify-content: center;
	align-items: center;
	line-height: 1;

	// min-height will expand when in flex
	height: map.get($input-height, 'default');
	white-space: nowrap;
	cursor: pointer;
	color: getCssVar('button', 'text-color');
	text-align: center;
	box-sizing: border-box;
	outline: none;
	transition: 0.1s;
	font-weight: getCssVar('button', 'font-weight');
	user-select: none;
	vertical-align: middle;
	appearance: none;
	background-color: getCssVar('button', 'bg-color');
	border: getCssVar('border');
	border-color: getCssVar('button', 'border-color');

	& + & {
		margin-left: 12px;
	}

	&:hover {
		color: getCssVar('button', 'hover', 'text-color');
		border-color: getCssVar('button', 'hover', 'border-color');
		background-color: getCssVar('button', 'hover', 'bg-color');
		outline: none;
	}

	&:active {
		color: getCssVar('button', 'active', 'text-color');
		border-color: getCssVar('button', 'active', 'border-color');
		background-color: getCssVar('button', 'active', 'bg-color');
		outline: none;
	}

	&:focus-visible {
		outline: 2px solid getCssVar('button', 'outline-color');
		outline-offset: 1px;
		transition:
			outline-offset 0s,
			outline 0s;
	}

	> span {
		display: inline-flex;
		align-items: center;
	}

	> [class*='#{$namespace}-spinner'] {
		@include set-css-var-value(('spinner', 'size'), map.get($button-font-size, 'default'));
	}

	@include button-size(
		map.get($button-padding-vertical, 'default') - $button-border-width,
		map.get($button-padding-horizontal, 'default') - $button-border-width,
		map.get($button-font-size, 'default'),
		map.get($button-border-radius, 'default')
	);

	&::-moz-focus-inner {
		border: 0;
	}

	& [class*='#{$namespace}-spinner'],
	& [class*='#{$namespace}-icon'] {
		& + span {
			margin-left: map.get($button-icon-span-gap, 'default');
		}

		svg {
			vertical-align: bottom;
		}
	}

	@include when(plain) {
		@include css-var-from-global(('button', 'hover', 'text-color'), ('color', 'primary'));
		@include css-var-from-global(('button', 'hover', 'bg-color'), ('fill-color', 'blank'));
		@include css-var-from-global(('button', 'hover', 'border-color'), ('color', 'primary'));
	}

	@include when(active) {
		color: getCssVar('button', 'active', 'text-color');
		border-color: getCssVar('button', 'active', 'border-color');
		background-color: getCssVar('button', 'active', 'bg-color');
		outline: none;
	}

	@include when(disabled) {
		&,
		&:hover {
			color: getCssVar('button', 'disabled', 'text-color');
			cursor: not-allowed;
			background-image: none;
			background-color: getCssVar('button', 'disabled', 'bg-color');
			border-color: getCssVar('button', 'disabled', 'border-color');
		}
	}

	@include when(uppercase) {
		text-transform: uppercase;
	}

	@include when(block) {
		width: 100%;
	}

	@include when(loading) {
		position: relative;
		pointer-events: none;

		&::before {
			// mask the button
			z-index: 1;
			pointer-events: none;
			content: '';
			position: absolute;
			inset: -1px;
			border-radius: inherit;
			background-color: getCssVar('mask-color', 'extra-light');
		}
	}

	@include when(round) {
		border-radius: getCssVar('border-radius', 'round');
	}

	@include when(circle) {
		width: map.get($input-height, 'default');
		border-radius: 50%;
		padding: map.get($button-padding-vertical, 'default') - $button-border-width;
	}

	@include when(text) {
		color: getCssVar('button', 'text-color');
		border: 0 solid transparent;
		background-color: transparent;

		@include when(disabled) {
			color: getCssVar('button', 'disabled', 'text-color');
			background-color: transparent !important;
		}

		&:not(.is-disabled) {
			&:hover {
				background-color: getCssVar('fill-color', 'light');
			}

			&:focus-visible {
				outline: 2px solid getCssVar('button', 'outline-color');
				outline-offset: 1px;
				transition:
					outline-offset 0s,
					outline 0s;
			}

			&:active {
				background-color: getCssVar('fill-color');
			}

			@include when(has-bg) {
				background-color: getCssVar('fill-color', 'light');

				&:hover {
					background-color: getCssVar('fill-color');
				}

				&:active {
					background-color: getCssVar('fill-color', 'dark');
				}
			}
		}
	}

	@include e(text) {
		@include m(expand) {
			letter-spacing: 0.3em;
			margin-right: -0.3em;
		}
	}

	@include when(link) {
		border-color: transparent;
		color: getCssVar('button', 'text-color');
		background: transparent;
		padding: 2px;
		height: auto;

		&:hover {
			color: getCssVar('button', 'hover', 'link-text-color');
		}

		@include when(disabled) {
			color: getCssVar('button', 'disabled', 'text-color');
			background-color: transparent !important;
			border-color: transparent !important;
		}

		&:not(.is-disabled) {
			&:hover {
				border-color: transparent;
				background-color: transparent;
			}

			&:active {
				color: getCssVar('button', 'active-color');
				border-color: transparent;
				background-color: transparent;
			}
		}
	}

	@include m(text) {
		border-color: transparent;
		background: transparent;
		color: getCssVar('color', 'primary');
		padding-left: 0;
		padding-right: 0;
		@include when(disabled) {
			color: getCssVar('button', 'disabled', 'text-color');
			background-color: transparent !important;
			border-color: transparent !important;
		}

		&:not(.is-disabled) {
			&:hover {
				color: getCssVar('color', 'primary', 'light-3');
				border-color: transparent;
				background-color: transparent;
			}

			&:active {
				color: getCssVar('color', 'primary', 'dark-2');
				border-color: transparent;
				background-color: transparent;
			}
		}
	}

	@include e(link) {
		@include m(expand) {
			letter-spacing: 0.3em;
			margin-right: -0.3em;
		}
	}

	@each $variant in (primary, default, info, success, warning, danger) {
		@include m(variant-#{$variant}) {
			@include button-variant($variant);
		}
	}

	@each $size in (large, small) {
		@include m(size-#{$size}) {
			@include set-css-var-value(('button', 'size'), map.get($input-height, $size));

			height: getCssVar('button', 'size');

			> [class*='#{$namespace}-spinner'] {
				@include set-css-var-value(('spinner', 'size'), map.get($button-font-size, $size));
			}

			& [class*='#{$namespace}-spinner'],
			& [class*='#{$namespace}-icon'] {
				& + span {
					margin-left: map.get($button-icon-span-gap, $size);
				}
			}

			@include button-size(
				map.get($button-padding-vertical, $size) - $button-border-width,
				map.get($button-padding-horizontal, $size) - $button-border-width,
				map.get($button-font-size, $size),
				map.get($button-border-radius, $size)
			);

			@include when(circle) {
				width: getCssVar('button', 'size');
				padding: map.get($button-padding-vertical, $size) - $button-border-width;
			}
		}
	}
}
