<script setup>
import { onMounted, watch, computed, ref } from 'vue';
import { date } from 'quasar';
import { useI18n } from 'vue-i18n';

const model = defineModel({ type: String });
const $props = defineProps({
    isOutlined: {
        type: Boolean,
        default: false,
    },
});

const { t } = useI18n();
const requiredFieldRule = (val) => !!val || t('globals.fieldRequired');

const dateFormat = 'DD/MM/YYYY';
const isPopupOpen = ref();
const hover = ref();
const mask = ref();

onMounted(() => {
    // fix quasar bug
    mask.value = '##/##/####';
});

const styleAttrs = computed(() => {
    return $props.isOutlined
        ? {
              dense: true,
              outlined: true,
              rounded: true,
          }
        : {};
});

const formattedDate = computed({
    get() {
        if (!model.value) return model.value;
        return date.formatDate(new Date(model.value), dateFormat);
    },
    set(value) {
        if (value == model.value) return;
        let newDate;
        if (value) {
            // parse input
            if (value.includes('/') && value.length >= 10) {
                if (value.at(2) == '/') value = value.split('/').reverse().join('/');
                value = date.formatDate(
                    new Date(value).toISOString(),
                    'YYYY-MM-DDTHH:mm:ss.SSSZ'
                );
            }
            let ymd = value.split('-').map((e) => parseInt(e));
            newDate = new Date(ymd[0], ymd[1] - 1, ymd[2]);
            if (model.value) {
                const orgDate =
                    model.value instanceof Date ? model.value : new Date(model.value);

                newDate.setHours(
                    orgDate.getHours(),
                    orgDate.getMinutes(),
                    orgDate.getSeconds(),
                    orgDate.getMilliseconds()
                );
            }
        }
        if (!isNaN(newDate)) model.value = newDate.toISOString();
    },
});

const popupDate = computed(() =>
    model.value ? date.formatDate(new Date(model.value), 'YYYY/MM/DD') : model.value
);

watch(
    () => model.value,
    (val) => (formattedDate.value = val),
    { immediate: true }
);
</script>

<template>
    <div @mouseover="hover = true" @mouseleave="hover = false">
        <QInput
            v-model="formattedDate"
            class="vn-input-date"
            :mask="mask"
            placeholder="dd/mm/aaaa"
            v-bind="{ ...$attrs, ...styleAttrs }"
            :class="{ required: $attrs.required }"
            :rules="$attrs.required ? [requiredFieldRule] : null"
            :clearable="false"
        >
            <template #append>
                <QIcon
                    name="close"
                    size="xs"
                    v-if="
                        ($attrs.clearable == undefined || $attrs.clearable) &&
                        hover &&
                        model &&
                        !$attrs.disable
                    "
                    @click="
                        model = null;
                        isPopupOpen = false;
                    "
                />
                <QIcon name="event" class="cursor-pointer" />
            </template>
            <QMenu
                transition-show="scale"
                transition-hide="scale"
                v-model="isPopupOpen"
                anchor="bottom left"
                self="top start"
                :no-focus="true"
            >
                <QDate
                    v-model="popupDate"
                    :today-btn="true"
                    @update:model-value="
                        (date) => {
                            formattedDate = date;
                            isPopupOpen = false;
                        }
                    "
                />
            </QMenu>
        </QInput>
    </div>
</template>

<style lang="scss">
.vn-input-date.q-field--standard.q-field--readonly .q-field__control:before {
    border-bottom-style: solid;
}

.vn-input-date.q-field--outlined.q-field--readonly .q-field__control:before {
    border-style: solid;
}
</style>
