<template>
  <span>
    <select v-model="optionDate">
      <option :value="null">任意の日付</option>
      <option
        v-for="date in courseDates" :key="date.isoFormat()" :value="date"
        :class="{
          'dateoption-weekday': date.weekday() < 5,
          'dateoption-saturday': date.weekday() === 5,
          'dateoption-sunday': date.weekday() === 6,
        }"
      >{{ dateToString(date) }}</option>
    </select>
    <input-date v-if="!optionDate" v-model="arbitaryDate" />
  </span>
</template>

<script>
import { shallowRef, computed, watch } from 'vue';
import { Date, cmp, timedelta } from '@silane/datetime';

import { inject, keys as injectionKeys } from '../injection';
import { datetimeRange } from '../common/utils';


export default {
  name: 'InputCourseDate',
  props: {
    modelValue: {
      type: /** @type {import('vue').PropType<Date | null>} */ (Object),
      required: true,
    },
  },
  emits: { 'update:modelValue': /** @type{(value: Date | null) => boolean} */(
    value => true
  ) },
  setup(props, { emit }) {
      const dateRange = inject(injectionKeys.generalTimetableScope).dateRange;

      const courseDates = computed(() => [...datetimeRange(
        dateRange.value[0], dateRange.value[1], timedelta({ days: 1 })
      )]);

      const optionDate = shallowRef(/** @type {Date | null} */(null));
      const arbitaryDate = shallowRef(/** @type {Date | null} */(null));

      let lastEmittedModelValue = null;
      watch([optionDate, arbitaryDate], () => {
        lastEmittedModelValue = optionDate.value ?? arbitaryDate.value;
        emit('update:modelValue', lastEmittedModelValue);
      });


      watch(() => props.modelValue, () => {
        const newVal = props.modelValue, oldVal = lastEmittedModelValue;
        if(newVal == oldVal || (
          newVal != null && oldVal != null && cmp(newVal, oldVal) === 0
        )) return;
        if(props.modelValue == null) {
          optionDate.value = null;
          arbitaryDate.value = null;
          return;
        }
        const newInternalValue = courseDates.value.find(
          x => x === props.modelValue || cmp(x, props.modelValue) === 0
        );
        if(newInternalValue) {
          optionDate.value = newInternalValue;
        } else {
          optionDate.value = null;
          arbitaryDate.value = props.modelValue;
        }
      }, { immediate: true });

      const today = Date.today();
      /** @param {Date} date */
      function dateToString(date) {
          const format = date.year == today.year ? '%m / %d' : '%Y / %m / %d';
          return `${date.strftime(format)}(${
              ['月', '火', '水', '木', '金', '土', '日'][date.weekday()]
          })`;
      }

      return { courseDates, optionDate, arbitaryDate, dateToString };
  },
}
</script>

<style scoped>
.dateoption-saturday {
    background-color: darkblue;
    color: white;
}
.dateoption-sunday {
    background-color: brown;
    color: white;
}
</style>
