@use "@wordpress/base-styles/colors" as *;
@use "@wordpress/base-styles/variables" as *;
@use "../utils/theme-variables" as *;

/* Root of the component. */
// Internal variables
$wp-components-calendar-outline-focus: var(--wp-admin-border-width-focus)
	solid $components-color-accent;
$wp-components-calendar-button-height: $grid-unit-40;
$wp-components-calendar-button-width: $grid-unit-40;
$wp-components-calendar-nav-height: $grid-unit-40;
$wp-components-calendar-range-middle-background-color: color-mix(in srgb, $components-color-accent 4%, transparent);
$wp-components-calendar-preview-border-color: color-mix(in srgb, $components-color-accent 16%, transparent);

.components-calendar {
	// TODO: add font family rule when Theme is ready

	position: relative; /* Required to position the navigation toolbar. */
	box-sizing: border-box;
	display: inline flow-root;
	color: $components-color-foreground;
	background-color: $components-color-background;
	font-size: $font-size-medium;
	font-weight: $font-weight-regular;
	z-index: 0; // Create a stacking context and render on top of the background.

	*,
	*::before,
	*::after {
		box-sizing: border-box;
	}
}

.components-calendar__day {
	padding: 0;
	position: relative;

	// Setting text color on the day container instead of directly on the
	// day button to ensure that the color of the dot used to indicate today's
	// date follows the same color as the button's text, since the button
	// inherits its text color.
	&:has(.components-calendar__day-button:disabled) {
		// Use a lighter shade of gray for less visual prominence.
		color: $components-color-gray-400;
	}
	&:has(.components-calendar__day-button:hover:not(:disabled)),
	&:has(.components-calendar__day-button:focus-visible) {
		color: $components-color-accent;
	}
}

.components-calendar__day-button {
	background: none;
	padding: 0;
	margin: 0;
	cursor: var(--wpds-cursor-control);
	justify-content: center;
	align-items: center;
	display: flex;
	position: relative;

	width: $wp-components-calendar-button-width;
	height: $wp-components-calendar-button-height;

	border: none;
	border-radius: $radius-small;

	font: inherit;
	font-variant-numeric: tabular-nums;
	color: inherit;

	// Use the button's ::before to render date's background, which keeps the
	// border-radius of the button intact. This technique allows the focus ring
	// to have rounded corners even when the background needs square corners
	// (eg. in the middle of a date range).
	&::before {
		content: "";
		position: absolute;
		z-index: -1;
		inset: 0;
		border: none; // No default border to avoid polluting high-contrast mode.
		border-radius: $radius-small;
	}

	// Use the button's ::after to show the selection preview.
	&::after {
		content: "";
		position: absolute;
		z-index: 1;
		inset: 0;
		pointer-events: none;
	}

	&:disabled {
		cursor: revert;

		@media ( forced-colors: active ) {
			// As an extra visual cue, show a line-through on disabled days
			// in forced-colors (high-contrast) mode.
			text-decoration: line-through;
		}
	}

	&:focus-visible {
		outline: $wp-components-calendar-outline-focus;
		outline-offset: 1px;
	}
}

.components-calendar__caption-label {
	z-index: 1;

	position: relative;
	display: inline-flex;
	align-items: center;

	white-space: nowrap;
	border: 0;

	text-transform: capitalize;
}

.components-calendar__button-next,
.components-calendar__button-previous {
	border: none;
	border-radius: $radius-small;
	background: none;
	padding: 0;
	margin: 0;
	cursor: var(--wpds-cursor-control);
	appearance: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	position: relative;

	width: $wp-components-calendar-button-width;
	height: $wp-components-calendar-button-height;

	color: inherit;

	&:disabled,
	&[aria-disabled="true"] {
		cursor: revert;

		color: $components-color-disabled;
	}

	&:focus-visible {
		outline: $wp-components-calendar-outline-focus;
	}
}

.components-calendar__chevron {
	display: inline-block;
	fill: currentColor;
	width: $grid-unit-20;
	height: $grid-unit-20;
}

.components-calendar[dir="rtl"]
.components-calendar__nav
.components-calendar__chevron {
	transform: rotate(180deg);
	transform-origin: 50%;
}

.components-calendar__month-caption {
	display: flex;
	justify-content: center;
	align-content: center;

	height: $wp-components-calendar-nav-height;
	margin-bottom: $grid-unit-15;
}

.components-calendar__months {
	position: relative;
	display: flex;
	justify-content: center;
	flex-wrap: wrap;
	gap: $grid-unit-20;
	max-width: fit-content;
}

.components-calendar__month-grid {
	border-collapse: separate;
	border-spacing: 0 $grid-unit-05;
}

.components-calendar__nav {
	position: absolute;
	inset-block-start: 0;
	inset-inline-start: 0;
	inset-inline-end: 0;

	display: flex;
	align-items: center;
	justify-content: space-between;

	height: $wp-components-calendar-nav-height;
}

.components-calendar__weekday {
	width: $wp-components-calendar-button-width;
	height: $wp-components-calendar-button-height;
	padding: 0;

	color: $components-color-gray-700;
	text-align: center;
	text-transform: uppercase;
}

/* DAY MODIFIERS */
// Today's date: show a dot in the top-right corner of the button
.components-calendar__day--today::after {
	content: "";
	position: absolute;
	z-index: 1;
	inset-block-start: 2px;
	inset-inline-end: 2px;
	width: 0;
	height: 0;
	border-radius: 50%;
	border: 2px solid currentColor;
}

// Selected date button (individual date, range start, and range end)
.components-calendar__day--selected:not(.components-calendar__range-middle) {
	&:has(
	.components-calendar__day-button,
	.components-calendar__day-button:hover:not(:disabled)
) {
		color: $components-color-foreground-inverted;
	}

	.components-calendar__day-button {
		&::before {
			background-color: $components-color-foreground;
			// Render a transparent border to highlight the selected day in
			// forced-colors (high-contrast) mode, since the background is not
			// visible.
			border: 1px solid transparent;
		}

		&:disabled::before {
			background-color: $components-color-gray-400;
		}

		&:hover:not(:disabled)::before {
			background-color: $components-color-gray-800;
		}
	}
}

// Outside month days (visible when showOutsideDays is true): use a lighter text color.
.components-calendar__day--outside {
	color: $components-color-gray-600;
}

// Hidden button (ie. outside current month but still rendered)
.components-calendar__day--hidden {
	visibility: hidden;
}

// Range start button, but not when start and end are the same day.
.components-calendar__range-start:not(.components-calendar__range-end)
.components-calendar__day-button {
	// Apply border-radius changes to the button itself too, so that the focus
	// ring follows the same shape as the button's background.
	&,
	&::before {
		border-start-end-radius: 0;
		border-end-end-radius: 0;
	}
}

// Middle of date range
.components-calendar__range-middle .components-calendar__day-button {
	&::before {
		background-color: $wp-components-calendar-range-middle-background-color;
		border-radius: 0;

		// Render a top and bottom transparent border to highlight the selected
		// day in forced-colors (high-contrast) mode, since the background is not
		// visible.
		border-width: 1px 0;
		border-color: transparent;
		border-style: solid;
	}
}

// Range end button, but not when start and end are the same day.
.components-calendar__range-end:not(.components-calendar__range-start)
.components-calendar__day-button {
	// Apply border-radius changes to the button itself too, so that the focus
	// ring follows the same shape as the button's background.
	&,
	&::before {
		border-start-start-radius: 0;
		border-end-start-radius: 0;
	}
}

/*
 * RANGE PREVIEW (range calendar only)
 *
 * The preview is rendered in the button's ::after pseudo-element, so that it
 * can be rendered over the button's contents.
 * The selection preview is shown with a dashed border. In order to have
 * control over the dash pattern (especially the seams between days), the
 * dashed borders are rendered as SVGs via the url() CSS function.
 * Since SVGs rendered in the url() function don't seem to be able to access
 * CSS variables, we're using the SVGs as masks, and using `background-color`
 * to consume the accent color variable.
 */
.components-calendar__day--preview svg {
	position: absolute;
	inset: 0;
	pointer-events: none;
	color: $wp-components-calendar-preview-border-color;

	@media ( forced-colors: active ) {
		color: inherit;
	}

	.components-calendar[dir="rtl"] & {
		transform: scaleX(-1);
	}
}

.components-calendar__day--preview.components-calendar__range-middle
.components-calendar__day-button::before {
	// Remove the transparent border shown on the middle of the range
	// in forced-colors (high-contrast) mode, to allow for the dashed border
	// to be visible.
	border: none;
}

/* ANIMATIONS */
@keyframes slide-in-left {
	0% {
		transform: translateX(-100%);
	}
	100% {
		transform: translateX(0);
	}
}

@keyframes slide-in-right {
	0% {
		transform: translateX(100%);
	}
	100% {
		transform: translateX(0);
	}
}

@keyframes slide-out-left {
	0% {
		transform: translateX(0);
	}
	100% {
		transform: translateX(-100%);
	}
}

@keyframes slide-out-right {
	0% {
		transform: translateX(0);
	}
	100% {
		transform: translateX(100%);
	}
}

@keyframes fade-in {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}

@keyframes fade-out {
	from {
		opacity: 1;
	}
	to {
		opacity: 0;
	}
}

.components-calendar__weeks-before-enter,
.components-calendar__weeks-before-exit,
.components-calendar__weeks-after-enter,
.components-calendar__weeks-after-exit,
.components-calendar__caption-after-enter,
.components-calendar__caption-after-exit,
.components-calendar__caption-before-enter,
.components-calendar__caption-before-exit {
	animation-duration: 0s;
	animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
	animation-fill-mode: forwards;

	@media not ( prefers-reduced-motion ) {
		animation-duration: 0.3s;
	}
}

.components-calendar__weeks-before-enter,
.components-calendar[dir="rtl"] .components-calendar__weeks-after-enter {
	animation-name: slide-in-left;
}
.components-calendar__weeks-before-exit,
.components-calendar[dir="rtl"] .components-calendar__weeks-after-exit {
	animation-name: slide-out-left;
}
.components-calendar__weeks-after-enter,
.components-calendar[dir="rtl"] .components-calendar__weeks-before-enter {
	animation-name: slide-in-right;
}
.components-calendar__weeks-after-exit,
.components-calendar[dir="rtl"] .components-calendar__weeks-before-exit {
	animation-name: slide-out-right;
}

.components-calendar__caption-after-enter {
	animation-name: fade-in;
}
.components-calendar__caption-after-exit {
	animation-name: fade-out;
}
.components-calendar__caption-before-enter {
	animation-name: fade-in;
}
.components-calendar__caption-before-exit {
	animation-name: fade-out;
}
