import {ref} from 'vue';
import _ from 'lodash';
import {createEventHook, injectLocal, provideLocal} from "@vueuse/core";
import {toast} from "@/uni_modules/uv-ui-tools/libs/function";

const key = Symbol('VOLUNTARY_CART')

export const useProvideVoluntaryCart = function (initId, n = '') {
    const id = ref(initId)
    const name = ref(n)
    const locking = ref(false)
    const total = ref(0)
    const list = ref([])
    const selectedList = ref([])
    const defaultSort = ref([])
    const majorCounter = ref(0) // 本地排序使用

    const resetCart = () => {
        total.value = 0
        list.value = []
        selectedList.value = []
        majorCounter.value = 0
    }

    const syncMajorGroupToSelected = (rows) => {
        if (selectedList.value.length) {
            rows.forEach(group => {
                const matcher = s => s.uniqueCode == group.uniqueCode
                const matchIdx = selectedList.value.findIndex(matcher)
                if (matchIdx > -1) {
                    const match = selectedList.value[matchIdx]
                    group.majors = match.majors
                    group.isExpand = match.isExpand
                    // replace in selectedList
                    selectedList.value.splice(matchIdx, 1, group)
                }
            })
        }
    }

    const syncMajorsToSelectedGroup = (majors, majorGroup) => {
        if (majorGroup.majors.length) {
            majors.forEach(m => {
                const match = majorGroup.majors.find(cache => m.id == cache.id && cache.selected)
                m.selected = !!match
                m.localPriority = match?.localPriority || 0 // 用于本地排序，待提交时，按此字段排序
            })
        } else {
            majors.forEach(m => {
                m.selected = false
                m.localPriority = 0
            })
        }
    }

    const recalculatePureSelectedList = async () => {
        // 过滤掉selectedList中，其majors元素全部selected=false的项
        // 使用splice操作，防止更改selectedList引用
        const abandonGroups = selectedList.value.filter(g => g.majors.every(m => !m.selected))
        _.pull(selectedList.value, ...abandonGroups)
        return !!abandonGroups.length
    }

    const toggleMajorSelected = async (major, majorGroup, options) => {
        // validation
        if (!major.selected) {
            // major is unselected
            if (majorGroup.majors.filter(major => major.selected).length >= options.firedLimit.profession) {
                toast(`每个专业组最多选择${options.firedLimit.profession}个专业`)
                return Promise.reject('profession over limitation.')
            }
            if (!selectedList.value.includes(majorGroup)) {
                // major & majorGroup are both unselected
                if (selectedList.value.length >= options.firedLimit.groups) {
                    toast(`最多选择${options.firedLimit.groups}个专业组`)
                    return Promise.reject('group over limitation')
                }
            }
        }
        // toggle major selected state
        major.selected = !major.selected
        if (major.selected) {
            // set majorCounter with max value of major.localPriority in majorGroup // this logic is for edit mode
            majorCounter.value = Math.max(majorCounter.value, ...majorGroup.majors.filter(m => m.selected).map(m => m.localPriority))
            // make current major localPriority to max value
            major.localPriority = ++majorCounter.value
            // if major is a new select element, add its parent to selectedList
            if (!selectedList.value.includes(majorGroup)) {
                selectedList.value.push(majorGroup)
            }
            return
        }
        // if major is unselect, recalculate selectedList
        await recalculatePureSelectedList()
    }

    const options = {
        id, name, locking,
        total, list, selectedList, majorCounter,
        defaultSort, resetCart,
        syncMajorsToSelectedGroup,
        syncMajorGroupToSelected,
        recalculatePureSelectedList,
        toggleMajorSelected
    }
    provideLocal(key, options)
    return options
}

export const useInjectVoluntaryCart = function () {
    return injectLocal(key)
}