<!--

    Complete date picker with optional modes for button and textbox input.

-->
<template>
    <PxPopupButton
        :class="bem({ mode: mode, ...variantsMap })"
        :tag="buttonMode ? 'button' : 'div'"
        :trigger="buttonMode ? 'click' : null"
        :modalAttrs="modalAttrs"
        v-bind="popupProps"
        ref="popup"
    >
        <!-- button mode -->
        <span :class="bem('button-outer')" v-if="buttonMode">
            {{ formatDate(dateValue) || placeholder }}
            <px-icon :class="bem('icon')" :src="icon" :size="iconSize" v-if="icon" />
        </span>

        <!-- textbox mode -->
        <div :class="bem('textbox-outer')" v-else>
            <PxTextbox
                ref="textbox"
                variant="none"
                :value="textboxValue"
                @focus="textboxFocus"
                @input="textboxInput"
                @keydown="textboxKeyDown"
                @blur="textboxBlur"
            ></PxTextbox>
            <px-icon-button
                v-if="icon"
                :class="bem('icon-button')"
                ref="textboxButton"
                variant="basic accent-hover"
                :src="icon"
                :size="iconSize"
                @click="textboxButtonClick"
            />
        </div>

        <template #popup>
            <div ref="dialog" :class="bem('dialog')">
                <px-calendar :class="bem('calendar')" v-model:date="dateValue" />
                <div :class="bem('clock')" v-if="clock">
                    <px-clock v-model:date="dateValue" />
                </div>
            </div>
        </template>
    </PxPopupButton>
</template>

<script>
import * as chrono from 'chrono-node';
import dateFormat from 'dateformat';
import PxBaseDate from '../bases/PxBaseDate.vue';
import PxBase from '../bases/PxBase.vue';
import PxCalendar from './PxCalendar.vue';
import PxClock from './PxClock.vue';
import PxIcon from './PxIcon.vue';
import PxIconButton from './PxIconButton.vue';
import PxPopupButton from './PxPopupButton.vue';
import PxTextbox from './PxTextbox.vue';
import iconCalendar from '../assets/feather/calendar.svg?url';

export default {
    name: 'px-date-picker',
    mixins: [PxBaseDate, PxBase],
    components: { PxPopupButton, PxCalendar, PxClock, PxIcon, PxTextbox, PxIconButton },
    props: {
        // button or textbox mode
        mode: { type: String, default: 'button' },

        // whether or not to also show the time picker
        clock: { type: Boolean, default: false },

        // date format options (see https://github.com/felixge/node-dateformat#mask-options)
        format: { type: String, default: null },

        // placeholder text (shown when date is null)
        placeholder: { type: String, default: 'Select a date...' },

        // icon to be displayed in the button / textbox to indiciate this is a picker
        icon: { type: String, default: iconCalendar },

        // the size of the icon
        iconSize: { default: null },

        // properties that get set on the popup object (see PxPopup for details)
        popupProps: {
            type: Object,
            default: () => {
                return {
                    placement: 'bottom-start',
                    setPopupMinWidth: false,
                };
            },
        },
    },
    data() {
        return {
            textboxFocused: false,
            textboxEditValue: '',
        };
    },
    computed: {
        buttonMode() {
            return this.mode == 'button';
        },
        textboxMode() {
            return !this.buttonMode;
        },
        showPlaceholder() {
            return !!this.dateValue;
        },
        textboxValue() {
            return this.textboxFocused ? this.textboxEditValue : this.formatDate(this.dateValue);
        },
        modalAttrs() {
            return {
                autoFocusSelector: '.dp-selected',
                autoFocusEnabled: this.buttonMode,
                restoreFocusEnabled: this.buttonMode,
            };
        },
    },
    methods: {
        formatDate(date) {
            if (date) {
                let format = this.format;

                // TODO: this should be localized
                if (!format || format == 'auto') {
                    format = 'm/d/yy hh:MM tt';
                    if (!this.clock) {
                        format = 'mediumDate';
                    }
                }

                return dateFormat(date, format);
            }
            return null;
        },
        textboxFocus() {
            this.textboxFocused = true;
            this.textboxEditValue = this.formatDate(this.dateValue);
            this.$refs.popup.openPopup();
        },
        textboxInput(e) {
            this.textboxEditValue = e.target.value;
            this.$nextTick(() => {
                let date = chrono.parseDate(this.textboxEditValue);
                if (date) {
                    this.dateValue = date;
                }
            });
        },

        textboxKeyDown(e) {
            if (e.key == 'Enter') {
                if (this.dateValue) {
                    this.textboxEditValue = this.formatDate(this.dateValue);
                    this.$refs.popup.closePopup();
                }
            }
        },
        textboxBlur() {
            this.textboxFocused = false;
            setTimeout(() => {
                let dialogFocus = this.$refs.dialog.contains(document.activeElement);
                if (!dialogFocus) {
                    this.$refs.popup.closePopup();
                }
            }, 100);
        },
        textboxButtonClick() {
            this.$refs.popup.openPopup();
            this.$refs.textbox.$el.focus();
        },
    },
};
</script>

<style lang="scss">
@use '../styles/px.scss' as *;
@use '@thinkpixellab-public/px-styles/src/modules/controls' as *;

.px-date-picker {
    $popup: get(
        'controls.popup',
        (
            background-color: site-var(page-bg),
            border-radius: get('controls.base.border-radius'),
            box-shadow: shadow(15),
            font-size: get('controls.base.font-size'),
            font-family: get('controls.base.font-family'),
        )
    );

    &__dialog {
        @include css-map($popup);
        display: flex;
        overflow: hidden;
    }

    @include bem(calendar) {
        padding: sp(2);
    }

    // "default" variant

    &--default {
        &.px-date-picker--mode-button {
            $dropdown-button: get('controls.dropdown.button', ());
            @include button($dropdown-button);
            justify-content: stretch;

            // placeholder
            @include bem(placeholder) {
                $placeholder: get('controls.dropdown.placeholder', ());
                $placeholder: control-placeholder-style($placeholder);
                @include css-map($placeholder);
            }
        }
    }
    &__button-outer {
        display: inline-flex;
        justify-content: space-between;
        flex: 1;
        align-items: center;
    }

    &__icon {
        margin-left: 1em;
        margin-right: -0.1em;
    }

    &__textbox-outer {
        @include textbox();
        position: relative;
    }

    &__icon-button {
        @include center-y;
        right: 0.5em;
        z-index: 1;
    }
}

.px-date-picker__clock {
    background-color: gray(8);
    padding: sp(1);
}
</style>
