<template>
    <draggable
        v-model="iVal"
        tag="ul"
        handle=".handle"
        ghost-class="ghost"
        class="list-unstyled"
        :group="group"
        @end="$emit('input', iVal)"
        @add="$emit('input', iVal)"
    >
        <li v-for="(v, i) in iVal" ref="items">
            <div>
                <div class="input-group input-group-sm mb-1">
                    <button v-if="!disableSorting" :class="['btn', 'btn-light border', readonly ? '' : 'handle']" type="button" :aria-label="$t('table.sort')" :disabled="readonly">
                        <Icon v="bars" />
                    </button>
                    <slot :val="iVal[i]" :update="curry(update)(i)" :i="i">
                        <input
                            v-model="iVal[i]"
                            type="text"
                            class="form-control"
                            required
                            :readonly="readonly"
                            :maxlength="maxlength"
                        >
                    </slot>
                    <button :class="['btn', readonly ? 'btn-light border' : 'btn-outline-danger']" type="button" :aria-label="$t('crud.remove')" :disabled="readonly" @click.prevent="remove(i)">
                        <Icon v="times" />
                    </button>
                </div>
                <slot name="validation" :val="iVal[i]" :i="i"></slot>
            </div>
        </li>

        <li slot="footer">
            <button
                v-if="!readonly && (maxitems === null || iVal.length < maxitems)"
                class="btn btn-outline-success w-100 btn-sm"
                type="button"
                :aria-label="$t('crud.add')"
                @click.prevent="add"
            >
                <Icon v="plus" />
            </button>
        </li>
        <li v-if="maxitems && iVal.length > maxitems" class="alert alert-danger">
            <Icon v="exclamation-triangle" />
            <T :params="{ maxlength: maxitems }" class="ml-1">crud.validation.listMaxLength</T>
        </li>
    </draggable>
</template>

<script>
import { curry } from '../src/helpers.js';
import draggable from 'vuedraggable';

export default {
    components: {
        draggable,
    },
    props: {
        value: {},
        prototype: { default: '' },
        group: {},
        readonly: { type: Boolean },
        maxlength: { default: 32 },
        maxitems: { default: null },
        disableSorting: { type: Boolean },
    },
    data() {
        return {
            iVal: this.value,
            curry,
        };
    },
    watch: {
        value() {
            this.iVal = this.value;
        },
    },
    methods: {
        remove(i) {
            const v = [...this.value];
            v.splice(i, 1);
            this.$emit('input', v);
        },
        add() {
            // create a deep copy of the prototype
            const addedItem = JSON.parse(JSON.stringify(this.prototype));
            this.$emit('input', [...this.value, addedItem]);
            this.$nextTick((_) => {
                this.$refs.items[this.value.length - 1].querySelector('input,textarea,select').focus();
            });
        },
        update(i, val) {
            const v = [...this.value];
            v[i] = val;
            this.$emit('input', v);
        },
    },
};
</script>

<style lang="scss" scoped>
    .ghost {
        opacity: 0.5;
        background: #c8ebfb;
    }
</style>
