<!--
    #VUE3 Todo

    Creates a horizontally scrolling container with an invisible scrollbar and arrows on either side
    to scroll to the beginning or end of the container.

    <px-arrow-scroller :arrow-start-src="arrowStartImageUrl" :arrow-end-src="arrowEndImageUrl">

        <template #button>
            // this can look like a button but it will ultimately be wrapped by a button
            // element so it should probably be a span
        </template>
        ...
    </px-arrow-scroller>
ar


-->
<template>
    <div :class="bem()">
        <PxIconButton
            v-if="!disabled && !arrowsHidden"
            :class="[bem('button', { start: true, visible: arrowStartVisible }), buttonClass]"
            :iconClass="combineIconClasses(bem('arrow-icon'), iconClass)"
            :icon="arrowStartIcon"
            :disabled="!arrowStartVisible"
            aria-label="Scroll to previous"
            @click="scrollPages(-1)"
        />

        <div
            :class="bem('scroller', { disabled })"
            ref="scroller"
            @scroll="updateScrollArrows"
            data-no-drag
        >
            <slot />
        </div>

        <PxIconButton
            v-if="!disabled && !arrowsHidden"
            :class="[bem('button', { end: true, visible: arrowEndVisible }), buttonClass]"
            :iconClass="combineIconClasses(bem('arrow-icon'), iconClass)"
            :icon="arrowEndIcon"
            :disabled="!arrowEndVisible"
            aria-label="Scroll to next"
            @click="scrollPages(1)"
        />
    </div>
</template>

<script>
import PxBaseResize from '../bases/PxBaseResize.vue';
import PxIconButton from './PxIconButton.vue';
import PxIcon from './PxIcon.vue';
// import arrowStartIconDefault from '../assets/feather/arrow-left.svg?url';
// import arrowEndIconDefault from '../assets/feather/arrow-right.svg?url';
import { svgArrow } from '../utils/svgIcons.js';

import propsFilter from '../utils/propsFilter.js';

/**

Creates a horizontally scrolling container with an invisible scrollbar and arrows on either side.

```html
<px-arrow-scroller :arrow-start-src="yourCustomArrowStartIcon" :arrow-end-src="yourCustomArrowEndIcon">

    <template #button="{location}">
        // this can look like a button but it will ultimately be wrapped by a button
        // element so it should probably be a span
    </template>

    <template #default>
        // scrollable content goes here
    </template>

</px-arrow-scroller>
```

*/

export default {
    name: 'px-arrow-scroller',
    components: { PxIconButton, PxIcon },
    mixins: [PxBaseResize],
    props: {
        /**
         * The icon for the left arrow icon. This gets bound to the icon property of a PxIconButton
         * and can either be a string or an object that defines any valis PxIcon prop. See PxIcon
         * for details.
         */
        arrowStartIcon: {
            type: [String, Object],
            default: { src: svgArrow({ angle: 'left', chevron: true }), size: 1.25 },
        },

        /**
         * The icon for the right arrow icon. This gets bound to the icon property of a PxIconButton
         * and can either be a string or an object that defines any valis PxIcon prop. See PxIcon
         * for details.
         */
        arrowEndIcon: {
            type: [String, Object],
            default: { src: svgArrow({ angle: 'right', chevron: true }), size: 1.25 },
        },

        /**
         * The class to apply to the button element in the default `button` slot.
         */
        buttonClass: { type: String, default: null },

        /**
         * The class to apply to the icon element in the default `button` slot.
         */
        iconClass: { type: String, default: null },

        /**
         * Convenient way to control the size of the icons in the buttons.
         */
        iconSize: { type: [String, Number], default: '1.25rem' },

        /**
         * Disabled if true
         */
        disabled: { type: Boolean, default: false },

        /**
         * Hide arrows (but still allow scrolling)
         */
        arrowsHidden: { type: Boolean, default: false },
    },
    data() {
        return {
            arrowsVisible: false,
            arrowStartVisible: false,
            arrowEndVisible: false,
        };
    },

    methods: {
        combineIconClasses(...classNames) {
            return classNames.filter(c => c).join(' ');
        },
        pxIconProps(attrs) {
            return propsFilter(PxIcon)(attrs);
        },
        resize() {
            this.updateScrollArrows();
        },
        updateScrollArrows() {
            const scroller = this.$refs.scroller;

            if (!scroller) {
                return;
            }

            const fromStart = scroller.scrollLeft;
            const fromEnd = scroller.scrollWidth - scroller.scrollLeft - scroller.clientWidth;

            this.arrowsVisible = scroller.clientWidth > scroller.scrollWidth;
            this.arrowStartVisible = fromStart > 2;
            this.arrowEndVisible = fromEnd > 2;
        },

        scrollPages(pageCount) {
            if (this.$refs.scroller) {
                let pageSize = this.$refs.scroller.offsetWidth;
                let scrollX = Math.max(0, this.$refs.scroller.scrollLeft + pageSize * pageCount);
                this.scrollTo(scrollX);
            }
        },

        scrollTo(x) {
            if (this.$refs.scroller) {
                this.$refs.scroller.scrollTo({
                    left: x,
                    behavior: 'smooth',
                });
            }
        },

        scrollToElement(el) {
            if (this.$refs.scroller) {
                const left = el.offsetLeft - this.$refs.scroller.offsetWidth / 2;
                this.$refs.scroller.scrollTo({
                    left: left,
                    behavior: 'smooth',
                });
            }
        },
    },
};
</script>

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

.px-arrow-scroller {
    // prettier-ignore
    @include grid-art((
        'auto        | 1fr      | auto |',
        'arrow-start | scroller | arrow-end | auto'
    ));

    align-items: center;
    align-content: center;

    &__button {
        position: relative;
        align-self: center;
        padding: 0;
        height: 1.25em;

        &--start {
            grid-area: arrow-start;
        }

        &--end {
            grid-area: arrow-end;
        }

        @include transition(opacity, $dur: 200ms);
        opacity: 0;
        pointer-events: none;

        &--visible {
            opacity: 1;
            pointer-events: visible;
        }

        .px-arrow-scroller__arrow-icon {
            @include button-icon(
                (
                    padding: 0.1em 1em,
                    cursor: pointer,
                    display: flex,
                    align-items: center,
                    justify-content: center,
                )
            );

            @include media-until-mobile {
                min-width: 1em;
                padding-left: 0;
                padding-right: 0;
            }

            min-height: 0.8em;
            height: 100%;
        }
    }

    &__scroller {
        grid-area: scroller;
        overflow-x: auto;
        @include invisible-scrollbar;
        &--disabled {
            overflow-x: hidden;
        }
    }
}
</style>
