<script setup lang="ts">
import type { Timestamp } from '@quasar/quasar-ui-qcalendar';
import {
  addToDate,
  createDayList,
  createNativeLocaleFormatter,
  getEndOfWeek,
  getStartOfWeek,
  parseTimestamp,
  today,
} from '@quasar/quasar-ui-qcalendar';
import { ref, reactive, computed } from 'vue';

const selectedDate = defineModel<string>();

const weekdays = reactive([1, 2, 3, 4, 5, 6, 0]);
const locale = ref('en-CA');
const monthFormatter = monthFormatterFunc();
const dayFormatter = dayFormatterFunc();
const weekdayFormatter = weekdayFormatterFunc();

const today2 = computed(() => parseTimestamp(today()));

const parsedStart = computed(() =>
  getStartOfWeek(
    parseTimestamp(selectedDate.value || today()) as Timestamp,
    weekdays,
    today2.value as Timestamp
  )
);

const parsedEnd = computed(() =>
  getEndOfWeek(
    parseTimestamp(selectedDate.value || today()) as Timestamp,
    weekdays,
    today2.value as Timestamp
  )
);

const days = computed(() => {
  if (parsedStart.value && parsedEnd.value) {
    return createDayList(parsedStart.value, parsedEnd.value, today2.value as Timestamp, weekdays);
  }
  return [];
});

const dayStyle = computed(() => ({ width: 100 / weekdays.length + '%' }));

function onPrev() {
  selectedDate.value = addToDate(parsedStart.value, { day: -7 }).date;
}

function onNext() {
  selectedDate.value = addToDate(parsedStart.value, { day: 7 }).date;
}

function dayClass(day: Timestamp) {
  return { 'date-button': true, 'selected-date-button': selectedDate.value === day.date };
}

function monthFormatterFunc() {
  const longOptions: Intl.DateTimeFormatOptions = { timeZone: 'UTC', month: 'long' };
  const shortOptions: Intl.DateTimeFormatOptions = { timeZone: 'UTC', month: 'short' };
  return createNativeLocaleFormatter(locale.value, (_tms, short) => short ? shortOptions : longOptions);
}

function weekdayFormatterFunc() {
  const longOptions: Intl.DateTimeFormatOptions = { timeZone: 'UTC', weekday: 'long' };
  const shortOptions: Intl.DateTimeFormatOptions = { timeZone: 'UTC', weekday: 'short' };
  return createNativeLocaleFormatter(locale.value, (_tms, short) => short ? shortOptions : longOptions);
}

function dayFormatterFunc() {
  const longOptions: Intl.DateTimeFormatOptions = { timeZone: 'UTC', day: '2-digit' };
  const shortOptions: Intl.DateTimeFormatOptions = { timeZone: 'UTC', day: 'numeric' };
  return createNativeLocaleFormatter(locale.value, (_tms, short) => short ? shortOptions : longOptions);
}
</script>

<template>
  <div class="title-bar" style="display: flex">
    <button tabindex="0" class="date-button direction-button direction-button__left" @click="onPrev">
      <span class="q-calendar__focus-helper" tabindex="-1" />
    </button>
    <div class="dates-holder">
      <div :key="parsedStart?.date" class="internal-dates-holder">
        <div v-for="day in days" :key="day.date" :style="dayStyle">
          <button tabindex="0" style="width: 100%" :class="dayClass(day)" @click="selectedDate = day.date">
            <span class="q-calendar__focus-helper" tabindex="-1" />
            <div style="width: 100%; font-size: 0.9em">{{ monthFormatter(day, true) }}</div>
            <div style="width: 100%; font-size: 1.2em; font-weight: 700">{{ dayFormatter(day, false) }}</div>
            <div style="width: 100%; font-size: 1em">{{ weekdayFormatter(day, true) }}</div>
          </button>
        </div>
      </div>
    </div>
    <button tabindex="0" class="date-button direction-button direction-button__right" @click="onNext">
      <span class="q-calendar__focus-helper" tabindex="-1" />
    </button>
  </div>
</template>

<style lang="sass">
.title-bar
  position: relative
  width: 100%
  height: 70px
  background: white
  display: flex
  flex-direction: row
  flex: 1 0 100%
  justify-content: space-between
  align-items: center
  overflow: hidden
  border-radius: 3px
  user-select: none
  margin: 2px 0px 2px

.dates-holder
  position: relative
  width: 100%
  align-items: center
  display: flex
  justify-content: space-between
  color: #fff
  overflow: hidden
  user-select: none

.internal-dates-holder
  position: relative
  width: 100%
  display: inline-flex
  flex: 1 1 100%
  flex-direction: row
  justify-content: space-between
  overflow: hidden
  user-select: none

.direction-button
  background: white
  color: $primary
  width: 40px
  max-width: 50px !important

.direction-button__left
  &:before
    content: '<'
    display: inline-flex
    flex-direction: column
    justify-content: center
    height: 100%
    font-weight: 900
    font-size: 3em

.direction-button__right
  &:before
    content: '>'
    display: inline-flex
    flex-direction: column
    justify-content: center
    height: 100%
    font-weight: 900
    font-size: 3em

.date-button
  color: $primary
  background: white
  z-index: 2
  height: 100%
  outline: 0
  cursor: pointer
  border-radius: 3px
  display: inline-flex
  flex: 1 0 auto
  flex-direction: column
  align-items: stretch
  position: relative
  border: 0
  vertical-align: middle
  padding: 0
  font-size: 14px
  line-height: 1.715em
  text-decoration: none
  font-weight: 500
  text-transform: uppercase
  text-align: center
  user-select: none

.selected-date-button
  color: white !important
  background: $primary !important
</style>
