<template>
    <uv-popup ref="popup" mode="bottom" round="16" closeable>
        <view class="h-[50px] px-40 fx-row fx-bet-cen text-main text-lg font-bold">
            <template v-if="!id">
                志愿表预览
            </template>
            <view v-else class="fx-row flex-1 pr-30">
                <text v-if="!nameEditing">{{ name }}</text>
                <uv-input v-else v-model="name" placeholder="志愿表名称"/>
                <uv-icon name="edit-pen" size="18" class="ml-10" @click="nameEditing=!nameEditing"/>
            </view>
            <uv-tags icon="list-dot" text="快速排序" plain class="mr-50" @click="openSortList"/>
        </view>
        <scroll-view :scroll-y="!anyDragging" class="bg-bg" style="height: 50vh" lower-threshold="100"
                     @scrolltolower="handleGroupScroll">
            <uv-sticky v-if="firedSorts.length" :offsetTop="-44">
                <view class="px-20 pb-20 fx-row bg-white">
                    <uv-tags v-for="s in firedSorts" :key="s.name" :text="s.short" :icon="s.icon" size="mini"
                             type="success" closable plain-fill @close="handleSortRemove(s)"/>
                </view>
            </uv-sticky>
            <view class="p-20 fx-col gap-20">
                <view v-for="(college,index) in pagedSelectedList" class="fx-row fx-bet-sta bg-white mx-card">
                    <view class="ml-10 mb-10 text-sm">
                        <text class="fx-row rounded-b-full px-15 pt-5 pb-10 text-white bg-primary">
                            {{ generateSeq(index) }}
                        </text>
                    </view>
                    <view class="flex-1 p-20 fx-col">
                        <view class="font-bold">
                            {{ college.university.name }}
                            <!-- TODO:志愿表还未保存group信息，所以这里显示会在编辑时表现不一致 -->
                            <template v-if="false">({{ college.recruitPlan.group }})</template>
                            ({{ college.recruitPlan.collegeCode }})
                        </view>
                        <view class="fx-row fx-bet-cen mt-10 text-content text-2xs gap-20">
                            <view>录取概率：
                                <view class="font-bold text-main">
                                    {{ college.enrollRatio || '-' }}%
                                </view>
                            </view>
                            <view>最低位次：
                                <view class="font-bold text-main">
                                    {{ college.history && college.history.seat || '-' }}
                                </view>
                            </view>
                            <view>院校排名：
                                <view class="font-bold text-main">
                                    {{ college.university.ranking || '-' }}
                                </view>
                            </view>
                        </view>
                        <view class="fx-row gap-20 my-20">
                            <uv-button :disabled="selectedList.length<2" type="primary" size="mini" plain
                                       shape="circle" icon="arrow-down-fill" :text="generateSeq(index)"
                                       icon-color="primary" @click="openSeqSelect(index)"/>
                            <uv-button :disabled="index==0" type="primary" size="mini" plain shape="circle"
                                       icon="arrow-up" icon-color="primary" @click="handleMoveUp(college)"/>
                            <uv-button :disabled="index==selectedList.length-1" type="primary" size="mini" plain
                                       shape="circle" icon="arrow-down" icon-color="primary"
                                       @click="handleMoveDown(college)"/>
                            <uv-button type="primary" size="mini" plain shape="circle" icon="trash"
                                       icon-color="primary" @click="handleRemoveAll(college)"/>
                        </view>
                        <m-drag ref="drag" :list="getSelectedSortedMajors(college)" :item-height="44"
                                @change="handleDragComplete">
                            <template #default="{item:major,index:majorIndex}">
                                <view class="fx-row items-center text-xs text-content h-[44px] box-border mx-border-b">
                                    <view class="flex-1 truncate">
                                        <text v-if="majorIndex>-1" class="mr-20">{{ majorIndex + 1 }}</text>
                                        <text :class="{'highlight-major': isFormedMajorFired(major)}">
                                            {{ major.marjorName }}[{{ major.marjorBelongs }}]
                                        </text>
                                    </view>
                                    <!-- 因为手机上区域比较小，只保留了拖拽排序 -->
                                    <uv-icon v-if="false" name="arrow-up" size="20px" class="mr10"
                                             @click="handleMajorUp(major, college)"></uv-icon>
                                    <uv-icon v-if="false" name="arrow-down" size="20px" class="mr10"
                                             @click="handleMajorDown(major, college)"></uv-icon>
                                    <uv-icon name="trash" size="20px" class="mr10"
                                             @click="handleMajorDelete(major, college)"></uv-icon>
                                </view>
                            </template>
                        </m-drag>
                    </view>
                </view>
            </view>
        </scroll-view>
        <view class="h-[50px] px-40 fx-row items-center mx-border-t">
            <uv-button type="primary" text="保存志愿表" shape="circle" :loading="locking"
                       @click="handleSave"></uv-button>
        </view>
        <uv-action-sheet ref="actionSheet" :actions="sortList" :cancel-text="cancelSortText" @select="handleSort"
                         @cancel="handleSortReset"/>
        <!--  We don't use `u-action-sheet` because there maybe a great number of seq options  -->
        <uv-picker ref="picker" title="指定志愿顺序" :columns="[sequenceOptions]" :default-index="[seqIndex]"
                   @confirm="handleSeq"/>
    </uv-popup>
</template>

<script setup>
import {ref, computed, watch} from 'vue';
import {useInjectVoluntaryCart} from "@/pages/voluntary/hooks/useVoluntaryCartInjection";
import {toValue} from "@vueuse/core";
import {useVoluntarySortService} from "@/pages/voluntary/hooks/useVoluntarySortService";
import {useInjectVoluntaryMajorHighlight} from "@/pages/voluntary/hooks/useVoluntaryMajorHighlightInjection";
import {confirmAsync} from "@/utils/uni-helper";
import {useInjectVoluntaryAssistant} from "@/pages/voluntary/hooks/useVoluntaryAssistantInjection";
import {useInjectVoluntaryHeader} from "@/pages/voluntary/hooks/useVoluntaryHeaderInjection";

const popup = ref(null)
const drag = ref(null)
const picker = ref(null)
const actionSheet = ref(null)
const seqIndex = ref(0)
const nameEditing = ref(false) // 暂时不允许修改名称
const {id, name, locking, selectedList, defaultSort, recalculatePureSelectedList} = useInjectVoluntaryCart()
const {isFormedMajorFired, snapshotSearchingMajorWhenApply} = useInjectVoluntaryMajorHighlight()
const {
    firedSorts, sortList, cancelSortText, generateSeq, sequenceOptions,
    handleSort, handleSortReset, handleSortRemove,
    getSelectedSortedMajors, sortInterrupt,
    handleMoveDown, handleMoveUp
} = useVoluntarySortService(popup, defaultSort)
const {isMock} = useInjectVoluntaryHeader()
const {save} = useInjectVoluntaryAssistant()
const anyDragging = computed(() => drag.value?.some(d => d.dragging))

// optimization for faster rendering
const localPageNum = ref(1)
const localPageSize = ref(4)
const pagedSelectedList = computed(() => {
    return selectedList.value.slice(0, toValue(localPageNum) * toValue(localPageSize))
})
const handleGroupScroll = () => {
    if (toValue(pagedSelectedList).length >= toValue(selectedList).length) return
    localPageNum.value += 1
}

const openSortList = () => {
    actionSheet.value.open()
}

const handleDragComplete = (newList, oldList) => {
    // make localPriority exchange when drag complete.
    const copyPriorities = oldList.map(i => i.localPriority)
    copyPriorities.forEach((p, i) => newList[i].localPriority = p)
}

const handleRemoveAll = async (college) => {
    await confirmAsync('确认删除该专业组下的全部专业？')
    college.majors.forEach(m => {
        m.selected = false
        snapshotSearchingMajorWhenApply(m)
    })
    recalculatePureSelectedList()
    sortInterrupt()
}

// sort for major item
const handleMajorUp = (major, majorGroup) => {
    // TODO: HM-DragSorts 已经没有再使用了，所以不存在深拷贝的问题，但这个方法目前没有使用，先不优化
    const source = getSelectedSortedMajors(majorGroup)
    // HM-DragSorts clone element will cause index error
    const index = source.findIndex(s => s.marjorBelongs == major.marjorBelongs)
    const targetIndex = index - 1
    // exchange two majors' localPriority
    if (targetIndex >= 0) {
        major = source[index] // this is the original major
        const targetMajor = source[targetIndex]
        const temp = major.localPriority
        major.localPriority = targetMajor.localPriority
        targetMajor.localPriority = temp
    }
}
const handleMajorDown = (major, majorGroup) => {
    // TODO: HM-DragSorts 已经没有再使用了，所以不存在深拷贝的问题，但这个方法目前没有使用，先不优化
    const source = getSelectedSortedMajors(majorGroup)
    // HM-DragSorts clone element will cause index error
    const index = source.findIndex(s => s.marjorBelongs == major.marjorBelongs)
    const targetIndex = index + 1
    // exchange two majors' localPriority
    if (targetIndex < source.length) {
        major = source[index] // this is the original major
        const targetMajor = source[targetIndex]
        const temp = major.localPriority
        major.localPriority = targetMajor.localPriority
        targetMajor.localPriority = temp
    }
}
const handleMajorDelete = (major) => {
    major.selected = false
    snapshotSearchingMajorWhenApply(major)
    if (recalculatePureSelectedList()) sortInterrupt()
}

const openSeqSelect = (groupIndex) => {
    seqIndex.value = groupIndex
    picker.value.open()
}
const handleSeq = ({indexs}) => {
    const oldIndex = seqIndex.value
    const newIndex = indexs[0]
    if (oldIndex != newIndex) {
        const seqGroup = selectedList.value[oldIndex]
        selectedList.value.splice(oldIndex, 1)
        selectedList.value.splice(newIndex, 0, seqGroup)
        sortInterrupt()
    }
}

const handleSave = async () => {
    await save(isMock.value)
}

const open = () => {
    localPageNum.value = 1
    popup.value.open()
}

const close = () => {
    popup.value.close()
}

defineExpose({open, close})
// export default {
//     props: {
//         id: {
//             type: String | Number,
//             default: 0
//         },
//         name: {
//             type: String,
//             default: ''
//         },
//         show: {
//             type: Boolean,
//             default: false
//         },
//         selectedList: {
//             type: Array,
//             default: () => []
//         },
//         defaultSort: {
//             type: Array,
//             default: () => []
//         },
//         locking: {
//             type: Boolean,
//             default: false
//         }
//     },
//     data() {
//         return {
//             nameEditing: false,
//             confirmGroup: null,
//             showConfirm: false,
//             showSort: false,
//             showSeq: false,
//             seqIndex: 0,
//         }
//     },
//     watch: {
//         show: function (val) {
//             // u-popup will release dom elements when not showing
//             // so reset the current page number here
//             if (val) this.localPageNum = 1
//         }
//     },
//     methods: {
//         getSelectedSortedMajors(group) {
//             return group.majors.filter(m => m.selected).sort(MxConst.recommendMajorSortFn)
//         },
//         getGroupHeight(group) {
//             const majors = this.getSelectedSortedMajors(group)
//             return majors.length * 45
//         },
//         openSeqSelect(groupIndex) {
//             this.seqIndex = groupIndex
//             this.showSeq = true
//         },
//         handleSeq({indexs}) {
//             const oldIndex = this.seqIndex
//             const newIndex = indexs[0]
//             if (oldIndex != newIndex) {
//                 const seqGroup = this.selectedList[oldIndex]
//                 this.selectedList.splice(oldIndex, 1)
//                 this.selectedList.splice(newIndex, 0, seqGroup)
//                 this.sortInterrupt()
//             }
//             this.showSeq = false
//         },
//         close() {
//             this.$emit('closeVolunteer')
//         },
//         open() {
//
//         },
//         save() {
//             this.$emit('save')
//         },
//         handleRemoveAll() {
//             this.confirmGroup.majors.forEach(m => {
//                 m.selected = false
//                 this.snapshotSearchingMajorWhenApply(m)
//             })
//             this.$emit('change')
//             this.showConfirm = false
//         },
//         // sort for major item
//         handleMajorUp(major, majorGroup) {
//             const source = this.getSelectedSortedMajors(majorGroup)
//             // HM-DragSorts clone element will cause index error
//             const index = source.findIndex(s => s.marjorBelongs == major.marjorBelongs)
//             const targetIndex = index - 1
//             // exchange two majors' localPriority
//             if (targetIndex >= 0) {
//                 major = source[index] // this is the original major
//                 const targetMajor = source[targetIndex]
//                 const temp = major.localPriority
//                 major.localPriority = targetMajor.localPriority
//                 targetMajor.localPriority = temp
//             }
//         },
//         handleMajorDown(major, majorGroup) {
//             const source = this.getSelectedSortedMajors(majorGroup)
//             // HM-DragSorts clone element will cause index error
//             const index = source.findIndex(s => s.marjorBelongs == major.marjorBelongs)
//             const targetIndex = index + 1
//             // exchange two majors' localPriority
//             if (targetIndex < source.length) {
//                 major = source[index] // this is the original major
//                 const targetMajor = source[targetIndex]
//                 const temp = major.localPriority
//                 major.localPriority = targetMajor.localPriority
//                 targetMajor.localPriority = temp
//             }
//         },
//         deleteMajor(major, majorGroup) {
//             const source = this.getSelectedSortedMajors(majorGroup)
//             // HM-DragSorts clone element will cause index error
//             const index = source.findIndex(s => s.marjorBelongs == major.marjorBelongs)
//             major = source[index] // this is the original major
//             major.selected = false
//             this.snapshotSearchingMajorWhenApply(major)
//             this.$emit('change')
//         },
//         handleMajorDrag(group, event) {
//             const source = this.getSelectedSortedMajors(group)
//             const oldIndex = event.index * 1
//             const newIndex = event.moveTo * 1
//             if (oldIndex == newIndex) return
//             // get localPriority one by one
//             const oldSeq = source.map(m => m.localPriority)
//             const oldMajor = source[oldIndex]
//             const newMajor = source[newIndex]
//             const newSource = [...source]
//             newSource.splice(oldIndex, 1)
//             newSource.splice(newIndex, 0, oldMajor)
//             // assign oldSeq to newSource one by one
//             newSource.forEach((m, idx) => {
//                 m.localPriority = oldSeq[idx]
//             })
//         }
//     }
// }
</script>

<style scoped lang="scss">
.uv-button-wrapper {
    flex: 1 !important;
}
</style>
