@use '../tokens/index.scss' as tokens;
@use '../mixins/index.scss' as mixins;

$button-color: tokens.$text !default;
$button-background-color: tokens.$body-background !default;

$button-lg-font-size: tokens.$font-size-6 !default;
$button-sm-font-size: tokens.$font-size-8 !default;

$button-icon-font-size: 0.875em !default;

$button-border-color: tokens.$control-border !default;
$button-border-width: mixins.$control-border-width !default;
$button-border-radius: mixins.$control-radius !default;

$button-padding-vertical: calc(0.375em - #{$button-border-width}) !default;
$button-padding-horizontal: 0.75em !default;

$button-hover-color: tokens.$text !default;
$button-hover-border-color: tokens.$default-hover !default;
$button-hover-background-color: tokens.$default-hover-invert !default;

$button-disabled-background-color: tokens.$body-background-medium !default;
$button-disabled-shadow: none !default;
$button-disabled-opacity: 0.5 !default;

$button-selected-background-color: tokens.$selected-background !default;
$button-selected-border-color: tokens.$selected-stroke !default;
$button-selected-color: tokens.$selected-foreground !default;

$button-icon-spacing: 0.375em !default;
$button-font-weight: tokens.$weight-semibold !default;

.button {
	@include mixins.control;
	@include mixins.unselectable;

	justify-content: center;
	padding-block: $button-padding-vertical;
	border-width: $button-border-width;
	border-radius: $button-border-radius;
	border-color: $button-border-color;
	background-color: $button-background-color;
	color: $button-color;
	font-weight: $button-font-weight;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	padding-inline: $button-padding-horizontal;

	strong {
		color: inherit;
	}

	.icon {
		font-size: $button-icon-font-size;

		&:only-child {
			margin: 0;
		}

		&:first-child:not(:only-child) {
			margin-inline-end: $button-icon-spacing;
		}

		&:last-child:not(:only-child) {
			margin-inline-start: $button-icon-spacing;
		}
	}

	&:hover,
	&.is-hovered {
		border-color: $button-hover-border-color;
		background-color: $button-hover-background-color;
		color: $button-hover-color;
	}

	&:visited {
		color: $button-color;
	}

	// Sizes

	&.button-sm {
		font-size: $button-sm-font-size;
	}

	&.button-lg {
		font-size: $button-lg-font-size;
	}

	// Modifiers

	&.is-selected:not(:hover, .is-hovered) {
		border-color: $button-selected-border-color;
		background-color: $button-selected-background-color;
		color: $button-selected-color;
	}

	&.is-disabled,
	&[disabled] {
		border-color: currentColor;
		background-color: $button-disabled-background-color;
		opacity: $button-disabled-opacity;
		box-shadow: $button-disabled-shadow;
	}

	&.button-block {
		display: flex;
		width: 100%;
	}

	&.is-loading {
		color: transparent !important;
		pointer-events: none;

		&::after {
			@include mixins.loader;
			@include mixins.center(1em);

			position: absolute !important;
			border-block-end-color: tokens.$text;
			border-inline-start-color: tokens.$text;
		}
	}

	@each $name, $color-set in tokens.$colors {
		$base: nth($color-set, tokens.$color-index-base);
		$dark: nth($color-set, tokens.$color-index-dark);
		$background: nth($color-set, tokens.$color-index-background);
		$background-selected: nth($color-set, tokens.$color-index-background-selected);
		$selected: nth($color-set, tokens.$color-index-selected);
		$foreground-selected: nth($color-set, tokens.$color-index-foreground-selected);
		$border-selected: nth($color-set, tokens.$color-index-stroke-selected);

		&.button-#{$name} {
			@if $name == 'warning' {
				border-color: $dark;
				color: $dark;
			} @else {
				border-color: $base;
				color: $base;
			}

			&:hover,
			&.is-hovered {
				background-color: $background;
				color: $dark;
			}

			&.is-selected:not(:hover, .is-hovered) {
				border-color: $border-selected;
				background-color: $background-selected;
				color: $foreground-selected;
			}

			&.is-selected.is-loading::after {
				border-color: transparent transparent $foreground-selected $foreground-selected !important;
			}

			&.is-loading::after {
				border-color: transparent transparent $base $base !important;
			}
		}
	}
}

$button-clear-hover-background-color: transparentize(#8e8e8e, 0.95) !default;
$button-clear-selected-background-color: tokens.$selected-background-subtle !default;

.button.button-clear {
	border-color: transparent;
	background-color: transparent;

	&.border {
		// an allowed hack to make for flexible outlined buttons
		// does not support loading states
		border-color: currentColor !important;
	}

	&,
	&:visited {
		color: currentColor;
	}

	&.is-hovered,
	&:hover,
	&:active {
		background-color: $button-clear-hover-background-color;
	}

	&.is-selected:not(:hover, .is-hovered) {
		border-color: transparent;
		background-color: $button-clear-selected-background-color;
		color: $button-selected-color;
	}

	@each $name, $color-set in tokens.$colors {
		$base: nth($color-set, tokens.$color-index-base);
		$dark: nth($color-set, tokens.$color-index-dark);
		$background: nth($color-set, tokens.$color-index-background);
		$background-selected: nth($color-set, tokens.$color-index-background-selected);
		$selected: nth($color-set, tokens.$color-index-selected);
		$foreground-selected: nth($color-set, tokens.$color-index-foreground-selected);

		&.button-#{$name} {
			color: $base;

			@if $name == 'warning' {
				color: $dark;
			}

			&:hover,
			&.is-hovered {
				background-color: $background;
				color: $dark;
			}

			&.is-selected:not(:hover, .is-hovered) {
				background-color: $background-selected;
				color: $foreground-selected;
			}

			&.is-disabled,
			&[disabled] {
				background-color: transparent;
				color: $base;
				box-shadow: none;
			}
		}
	}
}

$button-filled-background-color: tokens.$alternate-background-medium !default;
$button-filled-background-color-hover: tokens.$alternate-background !default;
$button-filled-text-color: tokens.$text-invert !default;
$button-filled-background-color-selected: tokens.$secondary-selected !default;

.button.button-filled {
	border-color: $button-filled-background-color;
	background-color: $button-filled-background-color;
	color: $button-filled-text-color;

	&:hover,
	&.is-hovered {
		background-color: $button-filled-background-color-hover;
	}

	&.is-selected:not(:hover, .is-hovered) {
		border-color: $button-filled-background-color-selected;
		background-color: $button-filled-background-color-selected;
		color: $button-filled-text-color;
	}

	&.is-loading::after {
		@include mixins.loader;

		border-color: transparent transparent $button-filled-text-color $button-filled-text-color !important;
	}

	@each $name, $color-set in tokens.$colors {
		$base: nth($color-set, tokens.$color-index-base);
		$hover: nth($color-set, tokens.$color-index-hover);
		$active: nth($color-set, tokens.$color-index-active);
		$invert: nth($color-set, tokens.$color-index-invert);
		$background: nth($color-set, tokens.$color-index-background);
		$selected: nth($color-set, tokens.$color-index-selected);
		$selected-invert: nth($color-set, tokens.$color-index-foreground-selected-invert);

		&.button-#{$name} {
			border-color: $base;
			background-color: $base;
			color: $invert;

			&:hover,
			&.is-hovered {
				border-color: $hover;
				background-color: $hover;
				color: $invert;
			}

			&.is-selected:not(:hover, .is-hovered) {
				border-color: $selected;
				background-color: $selected;
				color: $selected-invert;
			}

			&.is-selected.is-loading::after {
				@include mixins.loader;

				border-color: transparent transparent $selected-invert $selected-invert !important;
			}

			&.is-loading::after {
				@include mixins.loader;

				border-color: transparent transparent $invert $invert !important;
			}
		}
	}
}
