<template>
    <!-- H5：SortableJS -->
    <!-- #ifdef H5 -->
    <view ref="h5ListRef" class="mt-30 flex flex-col">
        <view
            v-for="(m, i) in innerMajors"
            :key="getKey(m, i)"
            class="bg-back-light rounded-lg p-20 flex justify-between items-center gap-20 mb-20 min-w-0"
            :data-index="i"
        >
            <view class="text-32 text-fore-placeholder font-bold">{{ toFixedLen(i) }}</view>
            <view class="flex-1 w-0 text-28 text-fore-title font-bold truncate">{{ m.majorName }}</view>

            <uv-icon name="trash" size="18" color="error"/>

            <!-- 拖拽手柄：Sortable handle -->
            <view class="drag-handle">
                <uv-icon name="list-dot" size="18" color="primary"/>
            </view>
        </view>
    </view>
    <!-- #endif -->

    <!-- #ifndef H5 -->
    <movable-area
        class="mt-30 w-full"
        :style="{ height: areaHeight + 'px' }"
        :catchtouchmove="dragging"
        @touchmove.stop.prevent="noop"
    >
        <movable-view
            v-for="(m, i) in innerMajors"
            :key="getKey(m, i)"
            class="w-full"
            direction="vertical"
            :y="getY(i)"
            :disabled="activeIndex !== i"
            :inertia="false"
            :damping="80"
            :animation="true"
            @change="(e) => onDragChange(e, i)"
            @touchend="onDragEnd"
        >
            <view class="bg-back-light rounded-lg p-20 flex justify-between items-center gap-20">
                <!-- 主内容：阻断触摸，确保只能手柄拖 -->
                <view class="flex-1 flex items-center gap-20" @touchstart.stop @touchmove.stop>
                    <view class="text-32 text-fore-placeholder font-bold">{{ toFixedLen(i) }}</view>
                    <view class="flex-1 w-0 text-28 text-fore-title font-bold truncate">{{ m.majorName }}</view>
                    <uv-icon name="trash" size="18" color="error" />
                </view>

                <!-- 手柄：不 stop / prevent -->
                <view class="ml-10" @touchstart="onHandleDown(i)" @touchend="onHandleUp">
                    <uv-icon name="list-dot" size="18" color="primary" />
                </view>
            </view>
        </movable-view>
    </movable-area>
    <!-- #endif -->
</template>

<script setup lang="ts">
import {VoluntaryMajorItem} from "@/types/voluntary";
import {VOLUNTARY_SORTING} from "@/types/injectionSymbols";
// #ifdef H5
import Sortable from "sortablejs";
// #endif

const props = defineProps<{
    majors: VoluntaryMajorItem[];
}>();

const emits = defineEmits<{
    (e: "update:majors", majors: VoluntaryMajorItem[]): void;
    (e: "change", majors: VoluntaryMajorItem[]): void;
}>();

const isSorting = inject(VOLUNTARY_SORTING) || ref(false)
const innerMajors = ref<VoluntaryMajorItem[]>([]);
watch(
    () => props.majors,
    (v) => (innerMajors.value = v ? [...v] : []),
    {immediate: true, deep: true}
);

function toFixedLen(i: number, len: number = 2) {
    return String(i + 1).padStart(len, "0");
}

function getKey(m: any, i: number) {
    // 你的示例 majorId 可能重复，所以拼 i
    return m.majorId
}

// ========== H5：SortableJS ==========
const h5ListRef = ref<any>(null);
// #ifdef H5
let sortableIns: Sortable | null = null;

onMounted(async () => {
    await nextTick();
    const el = h5ListRef.value?.$el || h5ListRef.value; // 兼容 view ref
    if (!el) return;

    sortableIns = Sortable.create(el, {
        animation: 150,
        handle: ".drag-handle", // 只允许手柄拖
        forceFallback: true,
        onStart: () => {
            isSorting.value = true
            console.log('sortableIns onStart', true)
        },
        onEnd: (evt) => {
            isSorting.value = false;
            console.log('sortableIns onEnd', false)
            // sort logic
            if (evt.oldIndex == null || evt.newIndex == null) return;
            const arr = [...innerMajors.value];
            const [moved] = arr.splice(evt.oldIndex, 1);
            arr.splice(evt.newIndex, 0, moved);
            innerMajors.value = arr;
            emits("update:majors", arr);
            emits('change', arr)
        },
    });
});

onBeforeUnmount(() => {
    sortableIns?.destroy();
    sortableIns = null;
});
// #endif

// ========== 小程序：movable-view（重写版） ==========
const dragging = ref(false);
const activeIndex = ref(-1);
const activeY = ref(0);

const rowGapPx = uni.upx2px(20);
const rowHeightPx = uni.upx2px(92) + rowGapPx;
const areaHeight = computed(() => innerMajors.value.length * rowHeightPx);

const noop = () => {}; // 关键：给 @touchmove 一个“函数”，不要给 boolean

function getY(i: number) {
    return i === activeIndex.value ? activeY.value : i * rowHeightPx;
}

function clampY(y: number) {
    const maxY = Math.max(0, (innerMajors.value.length - 1) * rowHeightPx);
    return Math.min(Math.max(y, 0), maxY);
}

function swap(arr: any[], a: number, b: number) {
    const t = arr[a];
    arr[a] = arr[b];
    arr[b] = t;
}

function onHandleDown(i: number) {
    console.log("onHandleDown", i);
    dragging.value = true;
    activeIndex.value = i;
    activeY.value = i * rowHeightPx;
}

function onHandleUp() {
    console.log("onHandleUp");
    // 不要在这里结束；结束交给 movable-view 的 touchend
}

function onDragChange(e: any, i: number) {
    // 有了上面的报错修复后，这里应该能打出来
    console.log("onDragChange", e?.detail, i);

    if (!dragging.value) return;
    if (i !== activeIndex.value) return;
    if (e?.detail?.source !== "touch") return;

    const y = clampY(Number(e.detail.y || 0));
    activeY.value = y;

    const target = Math.round(y / rowHeightPx);
    if (target === i) return;

    swap(innerMajors.value as any[], i, target);
    activeIndex.value = target;
}

function onDragEnd() {
    console.log("onDragEnd");
    if (!dragging.value) return;

    dragging.value = false;

    if (activeIndex.value === -1) return;
    activeY.value = activeIndex.value * rowHeightPx;

    const arr = [...innerMajors.value];
    activeIndex.value = -1;
    console.log('emits update:majors', arr)
    emits("update:majors", arr);
    emits('change', arr);
}
</script>

<style scoped>
.drag-handle {
    touch-action: none;
    -webkit-user-select: none;
    user-select: none;
}
</style>