@import '@financial-times/math';
@import '@financial-times/o-brand/main';
@import '@financial-times/o-private-foundation/main';

@import './src/scss/brand';
@import './src/scss/variables';
@import './src/scss/mixins';

/// Output all o-message features. Accepts an options map to include features granularly.
/// Options include which types, states, and layouts of o-message to include.
/// See the README for more details.
/// @example To include all o-message styles.
///     @include oMessage();
/// @example To include only error and success alert styles.
///     @include oMessage($opts: (
///     	'types': ('alert'),
///     	'states': ('error', 'success'),
///     ));
/// @param {Map} $opts ['types': ('alert', 'notice', 'action), 'states': ('error', 'success', 'inform', 'neutral', 'inform-inverse', 'warning', 'warning-light', 'feedback'), 'layouts': ('inner')]
@mixin oMessage(
	$opts: (
		'types': (
			'action',
			'alert',
			'notice',
		),
		'states': (
			'error',
			'success',
			'neutral',
			'inform',
			'inform-inverse',
			'warning',
			'warning-light',
			'feedback',
		),
		'layouts': (
			'inner',
		),
	)
) {
	@include oPrivateFoundation();

	$types: map-get($opts, 'types');
	$states: map-get($opts, 'states');
	$layouts: map-get($opts, 'layouts');

	$alert: index($types, 'alert') != null and _oMessageSupports('alert');
	$notice: index($types, 'notice') != null and _oMessageSupports('notice');
	$action: index($types, 'action') != null and _oMessageSupports('action');
	$inner: index($layouts, 'inner');

	.o-message {
		font-family: oPrivateFoundationGet('o3-type-body-base-font-family');
		font-size: oPrivateFoundationGet('o3-type-body-base-font-size');
		font-weight: oPrivateFoundationGet('o3-type-body-base-font-weight');
		line-height: oPrivateFoundationGet('o3-type-body-base-line-height');

		.o-message__container {
			@include oPrivateGridContainer($bleed: true);
			display: flex;
			align-items: baseline;
			padding: $_o-message-default-block-spacing
				$_o-message-default-inline-spacing;
		}

		// Content

		// Add space between content items. Use negative margin on the content
		// element to ensure there is no excess margin when content wraps onto
		// a new line. I.e. when message actions wrap onto a new line.
		.o-message__content {
			margin-left: -#{$_o-message-default-content-spacing};
			margin-bottom: -#{$_o-message-default-content-spacing};
			& > * {
				margin: 0 0 $_o-message-default-content-spacing
					$_o-message-default-content-spacing;
			}
		}

		.o-message__content-main {
			display: inline-block;
		}

		.o-message__content-highlight {
			font-family: oPrivateFoundationGet('o3-type-body-highlight-font-family');
			font-size: oPrivateFoundationGet('o3-type-body-highlight-font-size');
			font-weight: oPrivateFoundationGet('o3-type-body-highlight-font-weight');
			line-height: oPrivateFoundationGet('o3-type-body-highlight-line-height');
		}

		.o-message__content-main a,
		.o-message__content-additional a {
			@include oPrivateTypographyLink();
			font-family: oPrivateFoundationGet('o3-type-body-base-font-family');
			font-size: oPrivateFoundationGet('o3-type-body-base-font-size');
			font-weight: oPrivateFoundationGet('o3-type-body-base-font-weight');
			line-height: oPrivateFoundationGet('o3-type-body-base-line-height');
			border-width: 1px;
			text-decoration-thickness: 1px;
		}

		// Actions

		.o-message__actions {
			display: inline-block;
		}

		.o-message__actions__primary {
			margin-right: $_o-message-default-content-spacing;
			&:only-child {
				margin-right: 0;
			}
		}

		.o-message__actions__secondary {
			@include oPrivateTypographyLink();
			font-family: oPrivateFoundationGet('o3-type-body-base-font-family');
			font-size: oPrivateFoundationGet('o3-type-body-base-font-size');
			font-weight: oPrivateFoundationGet('o3-type-body-base-font-weight');
			line-height: oPrivateFoundationGet('o3-type-body-base-line-height');
			white-space: nowrap;
		}
	}

	// Close Button
	// The is defensive CSS. No close icon should be added when the close
	// attribute is set to false, hence it does not support the deprecated
	// `data-close` option.
	.o-message[data-o-message-close='false'] .o-message__close {
		display: none;
	}

	.o-message--closed {
		display: none;
	}

	// Inner Variant
	@if $inner {
		.o-message--inner .o-message__content {
			max-width: oPrivateTypographyMaxLineWidth();
		}
	}

	// Alert/Notice Message Types

	// Alert/notice types of message are similar but the alert message has extra
	// iconography.
	@if $alert or $notice {
		// By default alert and notice messages are dismissible. Unless
		// configured otherwise, create space to accommodate the close button
		// with padding, so the close button can be added by JS without reflow.
		// @deprecated the `data-close` attribute is deprecated in favour of `data-o-message-close`.
		.o-message--notice:not([data-close='false']):not(
				[data-o-message-close='false']
			)
			.o-message__container,
		.o-message--alert:not([data-close='false']):not(
				[data-o-message-close='false']
			)
			.o-message__container {
			padding-right: $_o-message-close-inline-spacing;
		}

		.o-message--notice .o-message__close,
		.o-message--alert .o-message__close {
			// start: undo default button styles
			appearance: none;
			border: 0;
			font: inherit;
			outline: inherit;
			padding: 0;
			// end: undo default button styles
			content: '';
			position: absolute;
			// Use negative margins to effectively remove the whitespace from
			// the icon svg, to to position the visible close icon more
			// intuitively
			margin: -$_o-message-close-icon-inbuilt-space;
			right: $_o-message-default-block-spacing;
			// Match message padding plus a "magic" rem value to center with
			// the message.
			top: calc(#{$_o-message-default-block-spacing} + 0.35rem);
		}
	}

	@if $alert {
		// Icon svgs are drawn to a 40px grid with 10px whitespace either side.
		// This is what the size of the close alert would be without the whitespace.
		$true-alert-icon-size: div($_o-message-alert-icon-size, 2);
		$alert-icon-left-padding: oPrivateSpacingByName('s4');
		$alert-icon-right-padding: oPrivateSpacingByName('s2');

		.o-message--alert .o-message__container {
			// Add padding for the icon to sit in:
			// whitespace, icon, whitespace.
			padding-left: calc(
				#{$alert-icon-left-padding} +
					#{$true-alert-icon-size} +
					#{$alert-icon-right-padding}
			);
			&:before {
				content: '';
				position: absolute;
				// Use negative margins to effectively remove the whitespace
				// from the icon svg, to to position the visible alert icon more
				// intuitively
				margin: -$_o-message-alert-icon-inbuilt-space;
				left: $alert-icon-left-padding;
				// Match message padding plus a "magic" rem value to center with
				// the message.
				top: calc(#{$_o-message-default-block-spacing} + 0.1rem);
			}
		}
	}

	// Action Message Type

	@if $action {
		.o-message--action {
			.o-message__container {
				@include oPrivateGridRespondTo(S) {
					padding: oPrivateSpacingByName('m12') oPrivateSpacingByName('s6');
				}
			}

			.o-message__content--center-align {
				@include oPrivateGridRespondTo(S) {
					width: 100%;
					text-align: center;
				}
			}
		}
	}

	// Message States
	// E.g. success, error, inform, etc.

	@each $state in $states {
		$state-supported: index($o-message-states, $state) and
			_oMessageSupports($state);
		@if $state-supported {
			$state-types: map-get($_o-message-states-to-types, $state);
			@include oMessageAddState(
				$name: $state,
				$opts: null,
				$types: $state-types
			);
		}
	}
}

@if ($o-message-is-silent == false) {
	@include oMessage();

	// Set to silent again to avoid being output twice
	$o-message-is-silent: true !global;
}
