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

export const useConditionEventManager = function (queryParams, validator, console) {
    // 工作列表，工作列表清空时，表示条件已经准备好了
    const workingList = ref([])
    // 初次完成标识
    const initialized = ref(false)
    // 外抛事件，一般事件
    const searchEvent = createEventHook()
    // 初始化成功时的外抛事件，会优先于searchEvent外抛
    const initEvent = createEventHook()

    const push = function (reason, ...keys) {
        workingList.value.push(...keys)
        console.log('eventManager push reason:', reason, ', key:', keys + '', ', result:', workingList.value + '')
    }

    const pop = async (reason, key) => {
        if (workingList.value.includes(key)) {
            _.pull(workingList.value, key)
            console.log('eventManager pop reason:', reason, ', key:', key, ', result:', workingList.value + '')

            await trigger('working list check')
        }
    }

    // loadData 引发的pop 与 dataManager 非被依赖项watch 有时会并发触发trigger
    // 用triggerLock来控制并发只执行一次，TODO：待观察看有没有更好的方式
    let triggerLock = false
    const trigger = async (reason) => {
        if (triggerLock) {
            console.log('eventManager trigger ignore by lock，reason', reason)
            return
        }
        triggerLock = true
        console.log('eventManager trigger reason:', reason)

        try {
            // check trigger event
            if (empty(workingList.value) && !empty(queryParams.value)) {
                // 看当前是否数据有效
                await validator.value()

                if (!initialized.value) {
                    console.log('eventManager init trigger')
                    await initEvent.trigger()
                    initialized.value = true
                }
                console.log('eventManager search trigger', new Date().getTime())
                await searchEvent.trigger()
            }
        } finally {
            triggerLock = false
        }
    }

    const reset = function () {
        workingList.value.length = 0
    }

    return {
        push,
        pop,
        trigger,
        reset,
        onSearch: searchEvent.on,
        onInit: initEvent.on
    }
}