@use 'sass:math';
@use '@angular/cdk';
@use '../core/style/button-common';
@use '../core/tokens/token-utils';
@use './m3-datetimepicker';

$fallbacks: m3-datetimepicker.get-tokens();

$calendar-body-label-padding-start: 5% !default;
// We don't want the label to jump around when we switch between month and year views, so we use
// the same amount of padding regardless of the number of columns. We align the header label with
// the one third mark of the first cell, this was chosen somewhat arbitrarily to make it look
// roughly like the mock. Half way is too far since the cell text is center aligned.
$calendar-body-label-side-padding: math.div(33%, 7) !default;
$calendar-body-cell-min-size: 32px !default;
$calendar-body-cell-size: math.div(100%, 7) !default;
$calendar-body-cell-padding: math.div($calendar-body-cell-size, 2) !default;
$calendar-body-cell-content-margin: 5% !default;
$calendar-body-cell-content-border-width: 1px !default;
$calendar-body-cell-radius: 999px !default;

$calendar-body-min-size: 7 * $calendar-body-cell-min-size !default;
$calendar-body-cell-content-size: 100% - $calendar-body-cell-content-margin * 2 !default;

// Styles for a highlighted calendar cell (e.g. hovered or focused).
@mixin _highlighted-cell($token-name) {
  & > .mtx-calendar-body-cell-content {
    @include _unselected-cell {
      background-color: token-utils.slot($token-name, $fallbacks);
    }
  }
}

// Utility mixin to target cells that aren't selected. Used to make selector easier to follow.
@mixin _unselected-cell {
  &:not(.mtx-calendar-body-selected) {
    @content;
  }
}

.mtx-calendar-body {
  min-width: $calendar-body-min-size;
}

.mtx-calendar-body-today {
  @include _unselected-cell {
    border-color: token-utils.slot(datetimepicker-calendar-date-today-outline-color, $fallbacks);
  }
}

.mtx-calendar-body-label {
  height: 0;
  line-height: 0;
  text-align: left;
  padding-left: $calendar-body-label-side-padding;
  padding-right: $calendar-body-label-side-padding;
  font-size: token-utils.slot(datetimepicker-calendar-body-label-text-size, $fallbacks);
  font-weight: token-utils.slot(datetimepicker-calendar-body-label-text-weight, $fallbacks);
  color: token-utils.slot(datetimepicker-calendar-body-label-text-color, $fallbacks);

  [dir='rtl'] & {
    text-align: right;
  }
}

.mtx-calendar-body-week-number {
  height: 0;
  line-height: 0;
  font-weight: 400;
  color: token-utils.slot(datetimepicker-calendar-body-week-number-text-color, $fallbacks);
}

.mtx-calendar-body-cell-container {
  position: relative;
  height: 0;
  line-height: 0;
}

.mtx-calendar-body-cell {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: none;
  text-align: center;
  outline: none;
  margin: 0;
  // Needs to be repeated here in order to override the user agent styles.
  font-family: token-utils.slot(datetimepicker-calendar-text-font, $fallbacks);
  font-size: token-utils.slot(datetimepicker-calendar-text-size, $fallbacks);

  @include button-common.reset();
}

.mtx-calendar-body-disabled {
  cursor: default;
  pointer-events: none;

  > .mtx-calendar-body-cell-content:not(.mtx-calendar-body-selected) {
    color: token-utils.slot(datetimepicker-calendar-date-disabled-state-text-color, $fallbacks);
  }

  > .mtx-calendar-body-today:not(.mtx-calendar-body-selected) {
    border-color: token-utils.slot(datetimepicker-calendar-date-disabled-state-text-color, $fallbacks);
  }

  // Fade out the disabled cells so that they can be distinguished from the enabled ones. Note that
  // ideally we'd use `color: GreyText` here which is what the browser uses for disabled buttons,
  // but we can't because Firefox doesn't recognize it.
  @include cdk.high-contrast {
    opacity: 0.5;
  }
}

.mtx-calendar-body-cell-content {
  top: $calendar-body-cell-content-margin;
  left: $calendar-body-cell-content-margin;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: $calendar-body-cell-content-size;
  height: $calendar-body-cell-content-size;

  // Prevents text being off-center on Android.
  line-height: 1;
  border: $calendar-body-cell-content-border-width;
  border-style: solid;

  // Choosing a value clearly larger than the height ensures we get the correct capsule shape.
  border-radius: $calendar-body-cell-radius;
  color: token-utils.slot(datetimepicker-calendar-date-text-color, $fallbacks);
  border-color: token-utils.slot(datetimepicker-calendar-date-outline-color, $fallbacks);

  // Increase specificity because focus indicator styles are part of the `mat-core` mixin and can
  // potentially overwrite the absolute position of the container.
  &.mat-focus-indicator {
    position: absolute;
  }

  @include cdk.high-contrast {
    border: none;
  }
}

.mtx-calendar-body-active {
  .cdk-keyboard-focused &,
  .cdk-program-focused & {
    @include _highlighted-cell(datetimepicker-calendar-date-focus-state-background-color);
  }
}

@media (hover: hover) {
  .mtx-calendar-body-cell:not(.mtx-calendar-body-disabled):hover {
    @include _highlighted-cell(datetimepicker-calendar-date-hover-state-background-color);
  }
}

.mtx-calendar-body-selected {
  background-color: token-utils.slot(datetimepicker-calendar-date-selected-state-background-color, $fallbacks);
  color: token-utils.slot(datetimepicker-calendar-date-selected-state-text-color, $fallbacks);

  .mtx-calendar-body-disabled > & {
    background-color: token-utils.slot(datetimepicker-calendar-date-selected-disabled-state-background-color, $fallbacks);
  }

  &.mtx-calendar-body-today {
    box-shadow: inset 0 0 0 1px
      token-utils.slot(datetimepicker-calendar-date-today-selected-state-outline-color, $fallbacks);
  }
}
