<template>
    <div
        :class="bem()"
        ref="calendar"
        :style="{ height: this.fixedHeight ? this.fixedHeight + 'px' : 'auto' }"
    ></div>
</template>

<script>
/**
 * Usage:
 * <px-calendar v-model:date="mydate" />
 * or
 * <px-calendar date="02/15/2020" @datechanged="onDateChange" />
 *
 * This component always displays as a calendar. If you want to couple with a text input,
 * you can do that pretty easily on your own or else use DateTimePicker which couples this
 * with an input and a popup.
 */

import PxBaseDate from '../bases/PxBaseDate.vue';

const compareDates = function (a, b) {
    if (a && b && a.getTime && b.getTime) {
        return a.getTime() === b.getTime();
    } else {
        return a === b;
    }
};

export default {
    name: 'px-calendar',
    mixins: [PxBaseDate],
    props: {
        minDate: { type: String, default: null },
        maxDate: { type: String, default: null },
    },
    data() {
        return {
            fixedHeight: null,
        };
    },
    async mounted() {
        // has a dependency on window, so needs to be loaded here
        const TinyDatePicker = (await import('tiny-date-picker')).default;

        // create the calendar
        this.calendar = TinyDatePicker(this.$refs.calendar, {
            mode: 'dp-permanent',
            min: this.minDate,
            max: this.maxDate,
        });

        // set the initial date
        if (this.date) {
            this.setCalendarDate(this.date);
        }

        // handle date changes
        this.calendar.on('select', () => {
            this.dateValue = this.getCalendarDate();
        });

        // fix the height when we show the year/month picker
        this.calendar.on('statechange', () => {
            this.fixedHeight =
                this.calendar.state.view === 'month' || this.calendar.state.view === 'year'
                    ? this.$refs.calendar.offsetHeight
                    : null;
        });
    },

    watch: {
        dateValue(nv) {
            this.setCalendarDate(nv);
        },
    },

    methods: {
        getCalendarDate() {
            return this.calendar.state.selectedDate;
        },

        setCalendarDate(d) {
            if (this.calendar) {
                if (!compareDates(this.calendar.state.selectedDate, d)) {
                    this.calendar.setState({
                        selectedDate: d,
                        highlightedDate: d,
                    });
                }
            }
        },
    },
};
</script>

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

.px-calendar {
    /// Configuration defautls for px-calendar
    $-defaults: (
        'px-calendar.font-size': fs(base),
        'px-calendar.day-size': 2.5em,
        'px-calendar.day-radius': 0.25em,
        'px-calendar.button-radius': 0.25em,
        'px-calendar.fg': clr(page-fg),
        'px-calendar.fg-subtle': clr(page-fg, $alpha: 0.4),
        'px-calendar.bg': white,
        'px-calendar.selection-bg': accent(),
        'px-calendar.hover-bg': rgba(accent(), 0.1),
        'px-calendar.hover-fg': accent(),
        'px-calendar.today-bg': rgba(accent(), 0.33),
        'px-calendar.today-fg': clr(page-fg),
        'px-calendar.link-fg': accent(),
        'px-calendar.link-hover-fg': accent(),
    );

    @include defaults($-defaults);

    $dp-day-size: get('px-calendar.day-size');
    $dp-day-radius: get('px-calendar.day-radius');
    $dp-button-radius: get('px-calendar.button-radius');
    $dp-fg: get('px-calendar.fg');
    $dp-fg-subtle: get('px-calendar.fg-subtle');
    $dp-bg: get('px-calendar.bg');
    $dp-selection-bg: get('px-calendar.selection-bg');
    $dp-hover-bg: get('px-calendar.hover-bg');
    $dp-hover-fg: get('px-calendar.hover-fg');
    $dp-today-bg: get('px-calendar.today-bg');
    $dp-today-fg: get('px-calendar.today-fg');
    $dp-link-fg: get('px-calendar.link-fg');
    $dp-link-hover-fg: get('px-calendar.link-hover-fg');

    font-family: inherit;
    font-size: get('px-calendar.font-size');
    width: calc(#{$dp-day-size * 7} + 2em);

    .dp {
        width: 100%;
        height: 100%;
        font-size: inherit;
        position: relative;
        background: $dp-bg;
        padding: 1em;
        box-sizing: border-box;

        button {
            font-family: inherit;
        }
    }

    .dp-permanent {
        position: relative;
        height: 100%;
    }

    .dp-cal-month,
    .dp-cal-year,
    .dp-day,
    .dp-month,
    .dp-year {
        box-sizing: border-box;
        text-align: center;
        text-decoration: none;
        position: relative;
        border-radius: $dp-button-radius;
        border: 0;
        padding: 0;
        background: transparent;
        cursor: pointer;
    }

    .dp-cal-header {
        position: relative;
        display: flex;
        //height: $dp-day-size * 1.25;
        align-items: center;
        margin-bottom: 1em;
    }

    .dp-cal-month,
    .dp-cal-year {
        display: block;
        font-size: 1.1em;
        height: 2.25em;

        padding-inline: 0.25em;

        // padding: 16px 8px 8px;
        // outline: none;
    }

    .dp-cal-month {
        font-weight: 700;
    }

    .dp-next,
    .dp-prev {
        @include control-reset();
        background-color: transparent;
        background-repeat: no-repeat;
        background-position: center;
        top: 0;
        position: absolute;
        width: $dp-day-size;
        height: $dp-day-size;
        left: auto;
        text-indent: -9999px;
        border-radius: $dp-button-radius;
        cursor: pointer;
        &:hover {
            background-color: transparent;
        }
    }

    .dp-next {
        right: 0;
        background-image: inline-svg(
            '<svg width="8px" height="14px" viewBox="0 0 8 14" version="1.1" xmlns="http://www.w3.org/2000/svg" ><polyline stroke="stroke-value" fill="none" fill-rule="evenodd" stroke-width="2" points="1 1 7 7 1 13" stroke-linecap="round" stroke-linejoin="round"></polyline></svg>',
            (
                stroke-value: $dp-fg,
            )
        );
    }

    .dp-prev {
        right: $dp-day-size;
        background-image: inline-svg(
            '<svg width="8px" height="14px" viewBox="0 0 8 14" version="1.1" xmlns="http://www.w3.org/2000/svg" ><polyline stroke="stroke-value" fill="none" fill-rule="evenodd" stroke-width="2" points="7 1 1 7 7 13" stroke-linecap="round" stroke-linejoin="round"></polyline></svg>',
            (
                stroke-value: $dp-fg,
            )
        );
    }

    .dp-day-today {
        border-radius: $dp-day-radius;
        background-image: linear-gradient(
            135deg,
            transparent 37.5%,
            $dp-today-bg 37.5%,
            $dp-today-bg 50%,
            transparent 50%,
            transparent 87.5%,
            $dp-today-bg 87.5%,
            $dp-today-bg 100%
        );
        background-size: 5.66px 5.66px;
    }

    .dp-cal-footer {
        display: flex;
        justify-content: center;
        margin-top: 0.5em;
        button {
            font-size: 0.66em;
            text-transform: uppercase;
            font-weight: 700;
            height: 2em;
            line-height: 2em;
            border-radius: $dp-button-radius;
            padding: 0 0.5em;
            cursor: pointer;

            &:hover {
                color: $dp-hover-fg;
                background-color: $dp-hover-bg;
            }
        }
    }

    .dp-permanent .dp-today,
    .dp-permanent .dp-clear,
    .dp-permanent .dp-close {
        display: none;
    }

    @media screen and (min-device-width: 1200px) {
        .dp-close:hover,
        .dp-close:focus,
        .dp-clear:hover,
        .dp-clear:focus,
        .dp-today:hover,
        .dp-today:focus,
        .dp-next:hover,
        .dp-next:focus,
        .dp-prev:hover,
        .dp-prev:focus,
        .dp-cal-month:focus,
        .dp-cal-month:hover,
        .dp-cal-year:hover,
        .dp-cal-year:focus {
            background-color: $dp-hover-bg;
            color: $dp-hover-fg;
        }
    }

    .dp-col-header,
    .dp-day {
        //width: 14.28571429%;
        width: divide(1, 7) * 100%;
        border-radius: $dp-day-radius;
        display: inline-block;
        text-align: center;
    }

    .dp-day {
        font-size: 1em;
        //height: $dp-day-size * divide(1, 0.8);
        height: $dp-day-size;
        cursor: pointer;
    }

    .dp-col-header {
        color: $dp-fg-subtle;
        text-transform: uppercase;
        font-size: 0.66em;
        font-weight: 700;
        font-family: inherit;
        margin-bottom: 0.5em;
    }

    .dp-years,
    .dp-months {
        box-sizing: border-box;
        overflow: auto !important; /* HACK for Chrome on Android */
        @include abs;
        padding: 1em;
        @include scrollbar(8px, accent(), $background: rgba(accent(), 0.1));
    }

    .dp-month {
        width: 50%;
        display: inline-block;
        padding: 1em 0.5em;
    }

    .dp-year {
        display: block;
        padding: 1em 0.5em;
        width: 100%;
    }

    .dp-edge-day {
        color: $dp-fg-subtle;
    }

    .dp-day:hover,
    .dp-day:focus,
    .dp-month:hover,
    .dp-year:hover {
        outline: none;
        background: $dp-hover-bg;
        color: $dp-hover-fg;
    }

    .dp-day.dp-selected:hover,
    .dp-day.dp-selected:focus,
    .dp-day.dp-selected {
        background: accent();
        color: #fff;
        box-shadow: shadow(5);
    }

    // TODO
    .dp-day-disabled {
        background: transparent !important;
        color: $dp-fg-subtle !important;
        &::before {
            content: '';
            position: absolute;
            width: 100%;
            height: 1px;
            background-color: $dp-fg-subtle;
            opacity: 0.5;
            display: block;
            left: 0%;
            top: 50%;
            transform: rotate(-45deg);
        }
        //color: $dp-
    }

    // // TODO
    // .dp-day-disabled:focus,
    // .dp-day-disabled:hover {
    //     background: #ddd;
    // }

    // // TODO?
    // .dp-focuser {
    //     position: absolute;
    //     z-index: 0;
    //     top: 50%;
    //     left: 50%;
    // }

    /* Responsive overrides */
    @media (max-width: 480px), (max-height: 480px) {
        .dp-modal .dp {
            font-size: 0.9em;
            width: auto;
            width: 100%;
        }

        .dp-day-of-week,
        .dp-day {
            padding: 8px;
        }
    }
}
</style>
