<template>
  <q-input
    filled
    :readonly="readonly"
    :label="label"
    :value="getDateTime()"
    :placeholder="placeholder"
    @input="dateTimeChanged"
    :rules="customRules"
  >
    <template #append>
      <q-icon name="event" class="cursor-pointer" v-if="type == 'date' || type == 'datetime'">
        <q-popup-proxy ref="qDateProxy" transition-show="scale" transition-hide="scale">
          <q-date :value="getDate()" mask="YYYY-MM-DD" @input="dateChanged">
            <div class="row items-center justify-end">
              <q-btn v-close-popup label="Schließen" color="primary" flat />
            </div>
          </q-date>
        </q-popup-proxy>
      </q-icon>
      <q-icon
        name="mdi-clock-outline"
        class="cursor-pointer"
        v-if="type == 'time' || type == 'datetime'"
      >
        <q-popup-proxy ref="qTimeProxy" transition-show="scale" transition-hide="scale">
          <q-time :value="getTime()" mask="HH:mm" @input="timeChanged">
            <div class="row items-center justify-end">
              <q-btn v-close-popup label="Schließen" color="primary" flat />
            </div>
          </q-time>
        </q-popup-proxy>
      </q-icon>
    </template>
  </q-input>
</template>

<script lang="ts">
import { computed, defineComponent, ref } from 'vue';
import { date } from 'quasar';

export default defineComponent({
  name: 'IsoDateInput',
  props: {
    value: { type: String, required: true },
    type: {
      type: String,
      default: 'date',
      validator: (value: string) => ['date', 'time', 'datetime'].indexOf(value) !== -1,
    },
    label: String,
    readonly: {
      type: Boolean,
      default: false,
    },

    rules: {
      default: () => {
        return [];
      },
    },
  },
  setup(props, { emit }) {
    function getDateTime() {
      if (typeof props.value == 'object') {
        switch (props.type) {
          case 'date':
            return getDate();
          case 'time':
            return getTime();
          case 'datetime':
            return `${getDate()} ${getTime()}`;
        }
      }
      return props.value;
    }

    function getDate() {
      if (typeof props.value == 'object') {
        return date.formatDate(props.value, 'YYYY-MM-DD');
      }
      return '';
    }
    function getTime() {
      if (typeof props.value == 'object') {
        return date.formatDate(props.value, 'HH:mm');
      }
      return '';
    }

    const _date = ref('');
    const _time = ref('');
    const placeholder = computed(() => {
      switch (props.type) {
        case 'date':
          return 'YYYY-MM-DD';
        case 'time':
          return 'HH:mm';
        case 'datetime':
          return 'YYYY-MM-DD HH:mm';
      }
      throw 'Invalid type given';
    });

    function dateChanged(dateString: string) {
      _date.value = dateString;
      console.log(dateString);

      if (/^\d{4}-\d\d-\d\d$/.test(dateString)) {
        // eslint-disable-next-line @typescript-eslint/no-unsafe-call
        emit('input', new Date(`${_date.value} ${_time.value}`));
      } else {
        // eslint-disable-next-line @typescript-eslint/no-unsafe-call
        emit('input', dateString);
      }
    }

    function timeChanged(timeString: string) {
      _time.value = timeString;
      if (_date.value == '') {
        _date.value = date.formatDate(new Date(), 'YYYY-MM-DD');
      }
      if (/^\d\d:\d\d$/.test(timeString)) {
        // eslint-disable-next-line @typescript-eslint/no-unsafe-call
        emit('input', new Date(`${_date.value} ${_time.value}`));
      } else {
        // eslint-disable-next-line @typescript-eslint/no-unsafe-call
        emit('input', timeString);
      }
    }

    function dateTimeChanged(dateTimeString: string) {
      switch (props.type) {
        case 'date':
          dateChanged(dateTimeString);
          break;
        case 'time':
          timeChanged(dateTimeString);
          break;
        case 'datetime':
          const _dateTime = dateTimeString.split(' ');
          _date.value = _dateTime[0];
          _time.value = _dateTime[1];
          console.log(dateTimeString, _dateTime);
          if (/^\d{4}-\d\d-\d\d \d\d:\d\d$/.test(dateTimeString)) {
            console.log('dateTimeChanged');
            // eslint-disable-next-line @typescript-eslint/no-unsafe-call
            emit('input', new Date(`${_date.value} ${_time.value}`));
          } else {
            // eslint-disable-next-line @typescript-eslint/no-unsafe-call
            emit('input', dateTimeString);
          }
      }
    }

    function isDate(val: string) {
      return !val || /^\d{4}-\d\d-\d\d$/.test(val) || 'Datum ist nicht gültig.';
    }

    function isTime(val: string) {
      return !val || /^\d\d:\d\d$/.test(val) || 'Zeit ist nicht gültig.';
    }

    function isDateTime(val: string) {
      return !val || /^\d{4}-\d\d-\d\d \d\d:\d\d$/.test(val) || 'Datum und Zeit ist nicht gültig.';
    }

    // const customRules = computed(() => {
    //   const _rules = props.rules;
    //   switch (props.type) {
    //     case 'date':
    //       _rules.push(isDate);
    //     case 'time':
    //       _rules.push(isTime);
    //     case 'datetime':
    //       _rules.push(isDateTime);
    //   }
    // });

    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
    const customRules = [
      props.type == 'date' ? isDate : props.type == 'time' ? isTime : isDateTime,
      ...props.rules,
    ];

    return {
      getDate,
      getTime,
      getDateTime,
      dateChanged,
      customRules,
      timeChanged,
      placeholder,
      dateTimeChanged,
    };
  },
});
</script>
