<script setup>
import { computed, ref, watch } from "vue";
import { useDragAndDrop } from "@formkit/drag-and-drop/vue";
import { animations } from "@formkit/drag-and-drop";
const props = defineProps({
  context: Object
});
const node = props.context.node;
const min = ref(props.context.node.props.min ?? 0);
const max = ref(props.context.node.props.max ?? Infinity);
const sortable = ref(props.context.node.props.sortable ?? true);
const addLabel = ref(props.context.node.props.addLabel ?? "Add");
const dense = ref(props.context.node.props.dense ?? false);
const bordered = ref(props.context.node.props.bordered ?? true);
const separator = ref(props.context.node.props.separator ?? true);
node.on("prop", ({ payload }) => {
  if (payload.prop == "max") {
    max.value = payload.value;
  }
  if (payload.prop == "min") {
    min.value = payload.value;
  }
  if (payload.prop == "sortable") {
    sortable.value = payload.value;
  }
  if (payload.prop == "addLabel") {
    addLabel.value = payload.value;
  }
  if (payload.prop == "dense") {
    dense.value = payload.value;
  }
  if (payload.prop == "bordered") {
    bordered.value = payload.value;
  }
  if (payload.prop == "separator") {
    separator.value = payload.value;
  }
});
if (!props.context.value) {
  await node.input([]);
}
watch(() => max.value, (newVal) => {
  if (localValue.value.length > newVal) {
    localValue.value = localValue.value.slice(0, newVal);
  }
});
watch(() => min.value, (newVal) => {
  if (localValue.value.length < newVal) {
    for (let i = localValue.value.length; i < newVal; i++) {
      localValue.value.push({});
    }
  }
});
const [parent, localValue] = useDragAndDrop(props.context.value, {
  dragHandle: ".l-repeater-handle",
  plugins: [animations()]
});
if (localValue.value.length < min.value) {
  for (let i = localValue.value.length; i < min.value; i++) {
    localValue.value.push({});
  }
}
if (localValue.value.length > max.value) {
  localValue.value = localValue.value.slice(0, max.value);
}
const onAdd = () => {
  if (localValue.value.length >= max.value) return;
  localValue.value.push({});
};
const onRemove = (index) => {
  if (localValue.value.length <= min.value) return;
  localValue.value.splice(index, 1);
};
const onMoveUp = (index) => {
  if (index > 0) {
    let temp = localValue.value[index - 1];
    localValue.value[index - 1] = localValue.value[index];
    localValue.value[index] = temp;
  }
};
const onMoveDown = (index) => {
  if (index < localValue.value.length - 1) {
    let temp = localValue.value[index + 1];
    localValue.value[index + 1] = localValue.value[index];
    localValue.value[index] = temp;
  }
};
const isAllowRemove = computed(() => {
  return localValue.value.length > min.value;
});
const isAllowMoveUp = (index) => {
  return index > 0;
};
const isAllowMoveDown = (index) => {
  return index < localValue.value.length - 1;
};
const cursor = ref("cursor-grab");
</script>

<style>
.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}
</style>

<template>
    <FormKit type="list" v-model="localValue" dynamic #default="{ items, node }" :name="node.name">
        <div class="col col-12">
            <q-list :bordered="bordered" :separator="separator" ref="parent">
                <FormKit type="group" v-for="(item, index) in items" :index="index" :key="item" #default="{ node }">
                    <q-item :class="{ 'q-pa-xs': !dense, 'q-pa-none': dense }">
                        <q-item-section avatar v-if="sortable">
                            <div class="l-repeater-handle"  :class="cursor"
                                @mousedown="cursor = 'cursor-grabbing'" @mouseup="cursor = 'cursor-grab'"
                                @mouseleave="cursor = 'cursor-grab'">
                                <q-icon name="sym_o_drag_indicator" size="sm" />
                            </div>
                        </q-item-section>

                        <q-item-section>
                            <slot v-bind="{ value: localValue[index], index: index, node: node }"></slot>
                        </q-item-section>

                        <q-item-section side>
                            <div class="column q-gutter-xs">
                                <!-- up -->
                                <q-btn type="button" @click="onMoveUp(index)" icon="sym_o_arrow_upward" color="primary"
                                    :dense="dense" flat :disable="!isAllowMoveUp(index)" size="sm" />

                                <q-btn type="button" @click="onRemove(index)" icon="sym_o_delete" color="negative"
                                    :dense="dense" :disable="!isAllowRemove" flat size="sm" />
                                <!-- down -->
                                <q-btn type="button" @click="onMoveDown(index)" icon="sym_o_arrow_downward" color="primary"
                                    :dense="dense" flat :disable="!isAllowMoveDown(index)" size="sm" />
                            </div>
                        </q-item-section>
                    </q-item>
                </FormKit>
            </q-list>
            <q-btn @click="onAdd" :label="addLabel" icon="sym_o_add" color="primary" outline class="q-mt-sm"
                :disable="localValue.length >= max" />
        </div>
    </FormKit>
</template>
