<!--
    #VUE3 Todo
    Must be used in conjuction with PxBaseMobileProvide. See notes in that file for details.
-->

<script>
export default {
    inject: {
        mediaQuery: {
            default: { isMobile: null, currentBreakpoint: null, breakpoints: {} },
        },
    },
    computed: {
        isMobile() {
            return this.mediaQuery.isMobile;
        },
        currentBreakpoint() {
            return this.mediaQuery.currentBreakpoint;
        },
    },
    methods: {
        /**
         * Returns a value from a map that matches the current breakpoint or the nearest breakpoint.
         * Nearest is determined by the searchDirection parameter.
         *
         * Usage:
         *
         * // returns 240 if mobile or smaller, 320 otherwise
         * <Card :width="responsiveValue({mobile: 240}, 320)" />
         *
         * // returns 240 if mobile or smaller, 300 until lg, 320 otherwise
         * <Card :width="responsiveValue({mobile: 240, lg: 300}, 320)" />
         *
         * // returns 200 if smaller than mobile, 240 if smaller than lg and 300 if bigger than lg
         * <Card :width="responsiveValue({mobile: 240, lg: 300}, 200, 'down')" />
         *
         * // could also be used in a computed property....
         * responsiveColor() {
         *     return this.responsiveValue({mobile: 'red', lg: 'blue'}, 'green');
         * }
         */

        responsiveValue(lookup, fallback, searchDirection = 'up') {
            const breakpoints = this.mediaQuery.breakpoints || {};
            const current = this.currentBreakpoint;

            if (!lookup || !Object.keys(lookup).length || current == null) {
                return fallback;
            }

            // if the current breakpoint is in the lookup, just return the value
            if (current in lookup) {
                return lookup[current];
            }

            // convert keys to numbers so we can sort and find the nearest
            lookup = Object.keys(lookup).reduce((acc, key) => {
                if (key in breakpoints) {
                    acc[breakpoints[key]] = lookup[key];
                }
                return acc;
            }, {});

            const currentNum = breakpoints[current];

            const keys = Object.keys(lookup)
                .map(Number)
                .sort((a, b) => (searchDirection == 'up' ? a - b : b - a));

            // find the first key that is smaller than current
            const match = keys.find(key => {
                return searchDirection == 'up' ? key >= currentNum : key <= currentNum;
            });

            if (match) {
                return lookup[match];
            } else {
                return fallback;
            }
        },

        isBreakpointOrSmaller(breakpoint) {
            if (this.currentBreakpoint === null) {
                return false;
            }

            if (this.currentBreakpoint === breakpoint) {
                return true;
            }

            return (
                this.mediaQuery.breakpoints[breakpoint] >=
                this.mediaQuery.breakpoints[this.currentBreakpoint]
            );
        },
    },
};
</script>
