<script setup>
import { computed, onMounted, onUnmounted, ref } from "vue";
import { useFreeformContext } from "../composables/useFreeform";
const props = defineProps({
  item: { type: Object, required: true },
  disabled: { type: Boolean, required: false },
  asDropZone: { type: Boolean, required: false },
  accept: { type: Function, required: false }
});
const context = useFreeformContext();
const elementRef = ref(null);
onMounted(() => {
  if (elementRef.value) {
    context.registerItem(props.item.id, elementRef.value);
    if (isContainer.value) {
      context.registerDropZone(props.item.id, elementRef.value, props.item, props.accept);
    }
  }
});
onUnmounted(() => {
  context.unregisterItem(props.item.id);
  if (isContainer.value) {
    context.unregisterDropZone(props.item.id);
  }
});
const isSelected = computed(
  () => context.selectionState.value.items.some((i) => i.id === props.item.id)
);
const isDragging = computed(
  () => context.dragState.value.thresholdPassed && context.dragState.value.items.some((i) => i.id === props.item.id)
);
const actualIndex = computed(
  () => context.items.value.findIndex((i) => i.id === props.item.id)
);
const visualIndex = computed(
  () => context.getVisualIndex(props.item.id)
);
const isContainer = computed(
  () => props.asDropZone || props.item.type === "container"
);
const isDropTarget = computed(
  () => context.currentDropTarget.value?.item?.id === props.item.id
);
const isDropAccepted = computed(
  () => isDropTarget.value && context.currentDropTarget.value?.accepted
);
function hasHandle() {
  return !!elementRef.value?.querySelector("[data-freeform-handle]");
}
function isFromHandle(event) {
  const target = event.target;
  return !!target?.closest("[data-freeform-handle]");
}
function onPointerDown(event) {
  if (props.disabled) return;
  event.stopPropagation();
  if (hasHandle() && !isFromHandle(event)) return;
  if (event.ctrlKey || event.metaKey) {
    context.select(props.item, { ctrl: true });
    return;
  }
  context.startDrag(props.item, event);
}
function onClick(event) {
  if (props.disabled) return;
  if (context.dragState.value.thresholdPassed) return;
  if (event.ctrlKey || event.metaKey) return;
  context.select(props.item);
}
</script>

<template>
  <div
    ref="elementRef"
    class="freeform-item"
    :class="{
  'freeform-item--selected': isSelected,
  'freeform-item--dragging': isDragging,
  'freeform-item--disabled': disabled,
  'freeform-item--container': isContainer,
  'freeform-item--drop-target': isDropTarget,
  'freeform-item--drop-accepted': isDropAccepted,
  'freeform-item--drop-rejected': isDropTarget && !isDropAccepted
}"
    :style="{ order: visualIndex, display: isDragging ? 'none' : void 0 }"
    data-freeform-item
    :data-index="actualIndex"
    :data-visual-index="visualIndex"
    @pointerdown="onPointerDown"
    @click="onClick"
  >
    <slot
      :item="item"
      :selected="isSelected"
      :dragging="isDragging"
      :index="actualIndex"
      :visual-index="visualIndex"
      :is-container="isContainer"
      :drop-target="isDropTarget"
      :drop-accepted="isDropAccepted"
    >
      <!-- Default item rendering -->
      <div class="freeform-item-default">
        {{ item.id }}
      </div>
    </slot>
  </div>
</template>

<style>
.freeform-item{align-self:flex-start;touch-action:none}.freeform-item-default{background:var(--freeform-color-neutral);border-radius:8px;color:var(--freeform-color-text);font-weight:500;padding:16px 24px;transition:all .15s ease}.freeform-item--selected .freeform-item-default{background:var(--freeform-color-primary-light);box-shadow:0 0 0 2px var(--freeform-color-primary)}.freeform-item--drop-target.freeform-item--drop-accepted .freeform-item-default{background:var(--freeform-color-success-light);box-shadow:0 0 0 2px var(--freeform-color-success);transform:scale(1.02)}.freeform-item--drop-target.freeform-item--drop-rejected .freeform-item-default{background:var(--freeform-color-danger-light);box-shadow:0 0 0 2px var(--freeform-color-danger)}
</style>
