@use "sass:math";
@use "sass:map";
@use "sass:color";
@use "../variables" as *;
@use "../maps" as *;
@use "../../util/scss/besm.scss" as *;
@use "../../util/scss/add-rules.scss" as *;
@use "../../util/scss/clockwise.scss" as *;
@use "../../util/scss/include.scss" as *;

@mixin cx-calendar(
   $name: "calendar",
   $state-style-map: $cx-calendar-state-style-map,
   $width: $cx-default-input-width,
   $icon-size: $cx-default-icon-size,
   $besm: $cx-besm
) {
   $block: map.get($besm, block);
   $element: map.get($besm, element);
   $state: map.get($besm, state);
   $mod: map.get($besm, mod);

   .#{$block}calendar {
      display: inline-block;
      vertical-align: middle;
      overflow-y: auto;
      box-sizing: border-box;

      @include cx-add-state-rules($state-style-map, "default");

      &:hover {
         @include cx-add-state-rules($state-style-map, "hover");
      }

      &:focus {
         @include cx-add-state-rules($state-style-map, "focus");
      }

      &.#{$state}error {
         @include cx-add-state-rules($state-style-map, "error");

         &:focus {
            @include cx-add-state-rules($state-style-map, "error-focus");
         }
      }

      table {
         border-spacing: 0;
         width: 100%;
         border-collapse: separate;
         font-size: inherit;
      }

      td,
      th {
         text-align: center;
         width: 2em;
         line-height: 2em;
         -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
      }

      th {
         font-weight: cx-get-state-rule($state-style-map, header, font-weight);
         font-size: inherit;
      }

      tbody td {
         user-select: none;
         @include cx-add-state-rules($cx-calendar-day-state-style-map, default);
      }

      .#{$element}#{$name}-header {
         @include cx-add-state-rules($state-style-map, header);
      }

      td.#{$state}today {
         @include cx-add-state-rules($cx-calendar-day-state-style-map, today);

         &:hover {
            @include cx-add-state-rules(
               $cx-calendar-day-state-style-map,
               hover
            );
         }
      }

      td.#{$state}outside {
         @include cx-add-state-rules($cx-calendar-day-state-style-map, outside);
      }

      td.#{$state}unselectable {
         @include cx-add-state-rules(
            $cx-calendar-day-state-style-map,
            disabled
         );
      }

      td.#{$state}cursor,
      .#{$element}#{$name}-header td:hover {
         @include cx-add-state-rules($cx-calendar-day-state-style-map, hover);
      }

      td.#{$state}selected {
         @include cx-add-state-rules(
            $cx-calendar-day-state-style-map,
            selected
         );
      }

      &:not(.#{$state}disabled) {
         td {
            cursor: pointer;
         }
      }

      td:not(.cxe-calendar-year-option):first-child,
      td:not(.cxe-calendar-year-option):last-child {
         display: none;
         pointer-events: none;
      }

      &:focus {
         td.#{$state}cursor,
         .#{$element}#{$name}-header td:hover {
            @include cx-add-state-rules(
               $cx-calendar-day-state-style-map,
               hover-focus
            );

            &:active {
               @include cx-add-state-rules(
                  $cx-calendar-day-state-style-map,
                  active
               );
            }
         }

         td.#{$state}selected {
            @include cx-add-state-rules(
               $cx-calendar-day-state-style-map,
               selected-focus
            );
         }
      }

      &.#{$state}disabled {
         background-color: transparent;
         border-color: transparent;
         color: color.adjust(#fff, $lightness: -18%);
         pointer-events: none;
         opacity: 0.9;
      }
   }

   .#{$element}#{$name}-header td {
      line-height: 0;
   }

   .#{$element}#{$name}-icon-next-year,
   .#{$element}#{$name}-icon-prev-year,
   .#{$element}#{$name}-icon-prev-month,
   .#{$element}#{$name}-icon-next-month {
      width: $icon-size;
      height: $icon-size;
      display: inline-block;
      font-size: $icon-size;
      line-height: $icon-size;
      user-select: none;
   }

   .#{$element}#{$name}-year {
      &-name {
         cursor: pointer;
      }

      &-picker {
         user-select: none;
         overflow-y: scroll;
         width: 100%;
         max-height: 24em;
         height: auto;
      }

      &-option {
         cursor: pointer;
         @include cx-add-state-rules($cx-calendar-day-state-style-map, default);

         &.#{$state}active {
            @include cx-add-state-rules(
               $cx-calendar-day-state-style-map,
               today
            );
         }

         &:hover {
            @include cx-add-state-rules(
               $cx-calendar-day-state-style-map,
               hover
            );
         }

         &.#{$state}selected {
            @include cx-add-state-rules(
               $cx-calendar-day-state-style-map,
               selected
            );
         }
      }
   }

   .#{$element}#{$name}-icon-prev-year {
      transform: rotate(180deg);
   }
   .#{$element}#{$name}-icon-prev-month {
      transform: rotate(90deg);
   }
   .#{$element}#{$name}-icon-next-month {
      transform: rotate(-90deg);
   }

   th.#{$element}#{$name}-display {
      line-height: 1.5;
      padding: 0.5em;
   }

   .#{$element}#{$name}-toolbar {
      display: flex;
      justify-content: center;
      margin-top: cx-top(
         cx-get-state-rule($state-style-map, default, "padding", 0)
      );
   }
}

@if (cx-should-include("cx/widgets/Calendar")) {
   @include cx-calendar();
}
