@use "@db-ui/foundations/build/styles/variables";
@use "@db-ui/foundations/build/styles/colors";
@use "@db-ui/foundations/build/styles/fonts";
@use "@db-ui/foundations/build/styles/helpers";
@use "@db-ui/foundations/build/styles/icons";
@use "../../styles/internal/form-components";

// We need some fixed padding here to avoid layout shifts
/* stylelint-disable-next-line db-ui/use-spacings */
$switch-fixed-padding: helpers.px-to-rem(2);

$switch-inactive-thumb-size: calc(
	#{form-components.$font-size-height} - #{$switch-fixed-padding} * 2
);

$switch-active-thumb-size: calc(#{form-components.$font-size-height});

$checked-active-transition-size: calc(
	#{form-components.$font-size-height} - #{$switch-fixed-padding} * 2
);

%active-transition {
	&::before {
		inline-size: calc(
			#{$switch-active-thumb-size} - #{$switch-fixed-padding} * 2 +
				#{variables.$db-spacing-fixed-2xs}
		);
		margin: 0;
	}

	&:checked {
		&::before {
			block-size: $checked-active-transition-size;
		}
	}
}

.db-switch {
	@include form-components.set-default-check-element(check);

	user-select: none;

	// This is needed when clicking on the label instead of the input
	@include helpers.active {
		> input {
			@extend %active-transition;
		}
	}

	> input {
		--db-icon-margin-start: 0;
		--thumb-offset-x: #{$switch-fixed-padding};

		@extend %db-overwrite-font-size-sm;

		@include icons.set-icon("cross", "after");

		appearance: none;
		inline-size: calc(
			#{form-components.$font-size-height} * 2 + #{$switch-fixed-padding}
		);
		block-size: form-components.$font-size-height;
		box-sizing: content-box;
		display: flex;
		align-items: center;
		/* stylelint-disable-next-line db-ui/use-spacings */
		gap: $switch-fixed-padding;
		background-color: colors.$db-adaptive-bg-basic-transparent-full-default;
		border-radius: variables.$db-border-radius-full;

		&::after {
			visibility: hidden;
			align-self: center;
			aspect-ratio: 1;
		}

		// thumb
		&::before {
			content: "O";
			text-align: center;
			align-content: center;
			aspect-ratio: 1;
			block-size: $switch-inactive-thumb-size;
			background-color: colors.$db-adaptive-bg-inverted-contrast-max-default;
			color: colors.$db-adaptive-bg-inverted-contrast-max-default;
			border-radius: variables.$db-border-radius-full;
			transform: translateX(var(--thumb-offset-x));
			margin-inline-end: calc(
				#{$switch-active-thumb-size} - #{$switch-inactive-thumb-size}
			);

			@media screen and (prefers-reduced-motion: no-preference) {
				transition:
					margin variables.$db-transition-duration-fast
						variables.$db-transition-timing-emotional,
					inline-size variables.$db-transition-duration-fast
						variables.$db-transition-timing-emotional,
					block-size variables.$db-transition-duration-fast
						variables.$db-transition-timing-emotional,
					transform variables.$db-transition-duration-fast
						variables.$db-transition-timing-emotional;
			}
		}

		/* positioned at the end of the track: track length - 100% (thumb width) */
		&:checked {
			--thumb-offset-x: calc(100% + #{$switch-fixed-padding});

			@include colors.set-current-colors(
				colors.$db-adaptive-bg-inverted-contrast-max-default,
				colors.$db-adaptive-on-bg-inverted-default,
				colors.$db-adaptive-bg-inverted-contrast-max-hovered,
				colors.$db-adaptive-bg-inverted-contrast-max-pressed
			);

			border-color: colors.$db-adaptive-on-bg-basic-emphasis-100-default;

			@include helpers.hover {
				border-color: colors.$db-adaptive-on-bg-basic-emphasis-100-hovered;
			}

			@include helpers.active {
				border-color: colors.$db-adaptive-on-bg-basic-emphasis-100-pressed;
			}

			&::before {
				block-size: $switch-active-thumb-size;
				background-color: colors.$db-adaptive-on-bg-inverted-default;
				color: colors.$db-adaptive-on-bg-inverted-default;
				margin: 0;
			}
		}

		&:focus-visible {
			// Overwrite default border-radius
			border-radius: variables.$db-border-radius-full;
		}

		&[data-aid-icon]:not(:checked)::after {
			--db-icon-after: attr(data-aid-icon);
		}

		&[data-aid-icon-after]:checked::after {
			--db-icon-after: attr(data-aid-icon-after);
		}

		@media screen and (prefers-reduced-motion: no-preference) {
			// Overwrite default transition for switch border
			transition: none;
		}
	}

	&[data-hide-label="true"] {
		gap: 0;
	}

	&[data-size="small"] {
		gap: variables.$db-spacing-fixed-2xs;

		> input {
			@extend %db-overwrite-font-size-xs;
		}
	}

	&[data-emphasis="strong"] {
		> input {
			--db-check-element-border-color: #{colors.$db-adaptive-bg-basic-transparent-full-default};

			@extend %db-critical-variables;

			background-color: colors.$db-adaptive-bg-inverted-contrast-low-default;
			color: colors.$db-adaptive-on-bg-inverted-default;
			border-color: colors.$db-adaptive-on-bg-basic-emphasis-70-default;

			@include helpers.hover {
				background-color: colors.$db-adaptive-bg-inverted-contrast-low-hovered;
				border-color: colors.$db-adaptive-on-bg-basic-emphasis-70-hovered;
			}

			@include helpers.active {
				background-color: colors.$db-adaptive-bg-inverted-contrast-low-pressed;
				border-color: colors.$db-adaptive-on-bg-basic-emphasis-70-pressed;

				&::before {
					block-size: $checked-active-transition-size;
				}
			}

			&:not(:checked) {
				--thumb-offset-x: 0;
			}

			&:checked {
				@extend %db-successful-variables;

				&::before {
					background-color: colors.$db-adaptive-on-bg-inverted-default;
					color: colors.$db-adaptive-on-bg-inverted-default;
				}
			}

			&::before {
				background-color: colors.$db-adaptive-on-bg-inverted-default;
				color: colors.$db-adaptive-on-bg-inverted-default;
				block-size: $switch-active-thumb-size;
				margin: 0;
			}
		}
	}

	&[data-emphasis="strong"],
	&[data-visual-aid="true"] {
		> input {
			&::after {
				visibility: visible;
				block-size: $switch-active-thumb-size;
			}

			&:checked {
				&:not([data-aid-icon]) {
					@include icons.set-icon("check", "after");
				}

				&::after {
					transform: translateX(
						calc(-100% - #{$switch-fixed-padding})
					);
					block-size: $switch-active-thumb-size;
				}
			}
		}
	}
}
