<script>
import { getWeekNumber } from "reka-ui/date";
import theme from "#build/b24ui/calendar";
</script>

<script setup>
import { computed } from "vue";
import { Calendar as SingleCalendar, RangeCalendar } from "reka-ui/namespaced";
import { reactiveOmit } from "@vueuse/core";
import { useAppConfig } from "#imports";
import { useComponentProps } from "../composables/useComponentProps";
import { useForwardProps } from "../composables/useForwardProps";
import { useLocale } from "../composables/useLocale";
import { tv } from "../utils/tv";
import icons from "../dictionary/icons";
import B24Button from "./Button.vue";
const _props = defineProps({
  as: { type: null, required: false },
  nextYearIcon: { type: [Function, Object], required: false },
  nextYear: { type: Object, required: false },
  nextMonthIcon: { type: [Function, Object], required: false },
  nextMonth: { type: Object, required: false },
  prevYearIcon: { type: [Function, Object], required: false },
  prevYear: { type: Object, required: false },
  prevMonthIcon: { type: [Function, Object], required: false },
  prevMonth: { type: Object, required: false },
  color: { type: null, required: false },
  size: { type: null, required: false },
  range: { type: Boolean, required: false },
  multiple: { type: Boolean, required: false },
  monthControls: { type: Boolean, required: false, default: true },
  yearControls: { type: Boolean, required: false, default: false },
  defaultValue: { type: null, required: false },
  modelValue: { type: null, required: false },
  weekNumbers: { type: Boolean, required: false },
  class: { type: null, required: false },
  b24ui: { type: Object, required: false },
  defaultPlaceholder: { type: Object, required: false },
  placeholder: { type: Object, required: false },
  allowNonContiguousRanges: { type: Boolean, required: false },
  pagedNavigation: { type: Boolean, required: false },
  preventDeselect: { type: Boolean, required: false },
  maximumDays: { type: Number, required: false },
  weekStartsOn: { type: Number, required: false },
  weekdayFormat: { type: String, required: false },
  fixedWeeks: { type: Boolean, required: false, default: true },
  maxValue: { type: Object, required: false },
  minValue: { type: Object, required: false },
  locale: { type: String, required: false },
  numberOfMonths: { type: Number, required: false },
  disabled: { type: Boolean, required: false },
  readonly: { type: Boolean, required: false },
  initialFocus: { type: Boolean, required: false },
  isDateDisabled: { type: Function, required: false },
  isDateUnavailable: { type: Function, required: false },
  isDateHighlightable: { type: Function, required: false },
  nextPage: { type: Function, required: false },
  prevPage: { type: Function, required: false },
  disableDaysOutsideCurrentView: { type: Boolean, required: false },
  fixedDate: { type: String, required: false }
});
const emits = defineEmits(["update:modelValue", "update:placeholder", "update:validModelValue", "update:startValue"]);
defineSlots();
const props = useComponentProps("calendar", _props);
const { dir, t, locale } = useLocale();
const appConfig = useAppConfig();
const rootProps = useForwardProps(reactiveOmit(props, "range", "modelValue", "defaultValue", "color", "size", "monthControls", "yearControls", "class", "b24ui"), emits);
const nextYearIcon = computed(() => props.nextYearIcon || (dir.value === "rtl" ? icons.chevronDoubleLeft : icons.chevronDoubleRight));
const nextMonthIcon = computed(() => props.nextMonthIcon || (dir.value === "rtl" ? icons.chevronLeft : icons.chevronRight));
const prevYearIcon = computed(() => props.prevYearIcon || (dir.value === "rtl" ? icons.chevronDoubleRight : icons.chevronDoubleLeft));
const prevMonthIcon = computed(() => props.prevMonthIcon || (dir.value === "rtl" ? icons.chevronRight : icons.chevronLeft));
const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.calendar || {} })({
  color: props.color,
  size: props.size,
  weekNumbers: props.weekNumbers
}));
function paginateYear(date, sign) {
  if (sign === -1) {
    return date.subtract({ years: 1 });
  }
  return date.add({ years: 1 });
}
const Calendar = computed(() => props.range ? RangeCalendar : SingleCalendar);
const btnSize = computed(() => {
  switch (props.size) {
    case "xs":
      return "xs";
    default:
      return "sm";
  }
});
</script>

<template>
  <Calendar.Root
    v-slot="{ weekDays, grid }"
    v-bind="rootProps"
    :model-value="props.modelValue"
    :default-value="props.defaultValue"
    data-slot="root"
    :class="b24ui.root({ class: [props.b24ui?.root, props.class] })"
  >
    <Calendar.Header data-slot="header" :class="b24ui.header({ class: props.b24ui?.header })">
      <Calendar.Prev v-if="props.yearControls" :prev-page="(date) => paginateYear(date, -1)" :aria-label="t('calendar.prevYear')" as-child>
        <B24Button :icon="prevYearIcon" :size="btnSize" color="air-tertiary" v-bind="props.prevYear" />
      </Calendar.Prev>
      <Calendar.Prev v-if="props.monthControls" :aria-label="t('calendar.prevMonth')" as-child>
        <B24Button :icon="prevMonthIcon" :size="btnSize" color="air-tertiary" v-bind="props.prevMonth" />
      </Calendar.Prev>
      <Calendar.Heading v-slot="{ headingValue }" data-slot="heading" :class="b24ui.heading({ class: props.b24ui?.heading })">
        <slot name="heading" :value="headingValue">
          {{ headingValue }}
        </slot>
      </Calendar.Heading>
      <Calendar.Next v-if="props.monthControls" :aria-label="t('calendar.nextMonth')" as-child>
        <B24Button :icon="nextMonthIcon" :size="btnSize" color="air-tertiary" v-bind="props.nextMonth" />
      </Calendar.Next>
      <Calendar.Next v-if="props.yearControls" :next-page="(date) => paginateYear(date, 1)" :aria-label="t('calendar.nextYear')" as-child>
        <B24Button :icon="nextYearIcon" :size="btnSize" color="air-tertiary" v-bind="props.nextYear" />
      </Calendar.Next>
    </Calendar.Header>
    <div data-slot="body" :class="b24ui.body({ class: props.b24ui?.body })">
      <Calendar.Grid
        v-for="month in grid"
        :key="month.value.toString()"
        data-slot="grid"
        :class="b24ui.grid({ class: props.b24ui?.grid })"
      >
        <Calendar.GridHead>
          <Calendar.GridRow data-slot="gridWeekDaysRow" :class="b24ui.gridWeekDaysRow({ class: props.b24ui?.gridWeekDaysRow })">
            <Calendar.HeadCell
              v-for="day in weekDays"
              :key="day"
              data-slot="headCell"
              :class="b24ui.headCell({ class: props.b24ui?.headCell })"
            >
              <slot name="week-day" :day="day">
                {{ day }}
              </slot>
            </Calendar.HeadCell>
          </Calendar.GridRow>
        </Calendar.GridHead>
        <Calendar.GridBody data-slot="gridBody" :class="b24ui.gridBody({ class: props.b24ui?.gridBody })">
          <Calendar.GridRow
            v-for="(weekDates, index) in month.rows"
            :key="`weekDate-${index}`"
            data-slot="gridRow"
            :class="b24ui.gridRow({ class: props.b24ui?.gridRow })"
          >
            <td
              v-if="props.weekNumbers && weekDates[0]"
              role="gridcell"
              data-slot="cellWeek"
              :class="b24ui.cellWeek({ class: props.b24ui?.cellWeek })"
            >
              {{ getWeekNumber(weekDates[0], locale.code) }}
            </td>
            <Calendar.Cell
              v-for="weekDate in weekDates"
              :key="weekDate.toString()"
              :date="weekDate"
              data-slot="cell"
              :class="b24ui.cell({ class: props.b24ui?.cell })"
            >
              <Calendar.CellTrigger
                :day="weekDate"
                :month="month.value"
                data-slot="cellTrigger"
                :class="b24ui.cellTrigger({ class: props.b24ui?.cellTrigger })"
              >
                <slot name="day" :day="weekDate">
                  {{ weekDate.day }}
                </slot>
              </Calendar.CellTrigger>
            </Calendar.Cell>
          </Calendar.GridRow>
        </Calendar.GridBody>
      </Calendar.Grid>
    </div>
  </Calendar.Root>
</template>
