import { reactive, toRefs, onUnmounted } from 'vue'
import { enumType } from '@/services/api/common'

export function useEnum(code: string) {
    const state = reactive({
        loading: true,
        enums: <Model.EnumTypeRsp[]>[]
    })

    const controller = new AbortController()
    const readyCallbackMap = new Map<symbol, () => void>()

    // 获取枚举名称
    const getEnumTypeName = (value: number) => {
        const item = state.enums.find((e) => e.enumitemname === value)
        const { enumdicname = value?.toString() } = item ?? {}
        return enumdicname
    }

    // 获取枚举列表
    const getEnumOptions = (filtered: number | number[] = [], reverse = false) => {
        const valuesSet = new Set(Array.isArray(filtered) ? filtered : [filtered])
        if (valuesSet.size === 0) {
            return state.enums.map((e) => ({
                label: e.enumdicname,
                value: e.enumitemname
            }))
        }
        const result = state.enums.filter((e) => {
            if (reverse) {
                // 排除枚举
                return !valuesSet.has(e.enumitemname)
            } else {
                // 匹配枚举
                return valuesSet.has(e.enumitemname)
            }
        })
        return result.map((e) => ({
            label: e.enumdicname,
            value: e.enumitemname
        }))
    }

    // 注册成功回调
    const registerEnumReadyCallback = (callback: () => void) => {
        if (state.loading) {
            const key = Symbol()
            readyCallbackMap.set(key, callback)
        } else {
            callback()
        }
    }

    // 获取枚举列表
    enumType({
        controller,
        data: {
            typeCode: code
        }
    }).then((res) => {
        state.enums = res.data
        readyCallbackMap.forEach((callback) => callback())
        readyCallbackMap.clear()
    })

    onUnmounted(() => {
        controller.abort()
        readyCallbackMap.clear()
    })

    return {
        ...toRefs(state),
        getEnumOptions,
        getEnumTypeName,
        registerEnumReadyCallback
    }
}