<!--
    #VUE3 Done (has breaking changes)

    Provides basic items services for controls that maintain lists of items.

-->

<script>
function getFromItem(item, propOrFunc) {
    if (!item) {
        return undefined;
    }

    if (typeof propOrFunc == 'string' && propOrFunc in item) {
        return item[propOrFunc];
    }

    if (typeof propOrFunc == 'function') {
        return propOrFunc(item);
    }

    return undefined;
}

export default {
    props: {
        items: { type: Array },

        /**
         * Value needed to get a unique id from a given item. Can either be a string representing
         * the property name or a function that takes the item and returns the id.
         */
        itemsKey: { type: [String, Function], default: 'id' },

        /**
         * Value needed to get a string representation (label) for a given item. Can either be a
         * string representing the property name or a function that takes the item and returns the id.
         */
        itemsLabel: { type: [String, Function], default: 'label' },

        /**
         * Value needed to determine whether an item has been disabled. Can either be a string
         * representing the property name or a function that takes the item and returns the id.
         */
        itemsDisabled: { type: [String, Function], default: 'disabled' },
    },
    computed: {
        itemKeys() {
            if (this.items && Array.isArray(this.items)) {
                return this.items.map(item => this.getItemKey(item));
            }
            return [];
        },
    },
    methods: {
        getItem(key) {
            if (typeof key !== 'undefined') {
                return this.items.find(item => this.getItemKey(item) === key);
            }
            return undefined;
        },

        getItemKey(item) {
            if (!this.isValidItem(item)) {
                return undefined;
            }
            return getFromItem(item, this.itemsKey);
        },

        getItemLabel(item) {
            if (!this.isValidItem(item)) {
                return undefined;
            }
            return getFromItem(item, this.itemsLabel);
        },

        getItemDisabled(item) {
            if (!this.isValidItem(item)) {
                return undefined;
            }
            return getFromItem(item, this.itemsDisabled);
        },

        getItemKeyLabel(key) {
            const item = this.getItem(key);
            if (item) {
                return this.getItemLabel(item);
            }
            return undefined;
        },

        getItemKeyIndex(key) {
            return (this.items || []).indexOf(this.getItem(key));
        },

        isValidItem(item) {
            return !!this.items?.includes(item);
        },

        isValidItemKey(key) {
            return !!this.itemKeys?.includes(key);
        },
    },
};
</script>
