import {toValue, ref, watch, computed} from 'vue'
import _ from "lodash";
import {empty} from "@/uni_modules/uv-ui-tools/libs/function/test";
import {useConditionFactory} from "@/components/mx-condition/useConditionFactory";

export const useConditionDataManager = function (configs, eventManager, queryParams, sharedData, console) {

    const container = ref(new Map())
    const rules = ref({})

    watch(queryParams, async () => {
        console.log('dataManager begin init', new Date().getTime())
        const keys = Object.keys(queryParams.value)
        if (!keys.length) return
        const keysConfig = configs.map(c => c.key)
        const missingKeys = _.difference(keys, keysConfig)
        if (missingKeys.length) console.warn('missing keys: ' + missingKeys.toString())

        // 没有被依赖的属性需要在改变时触发查询
        // 依赖是在config中指定的，但是否没有被依赖需要遍历所有条件才能知道
        const keysNotBeDependent = [...keys]
        keys.forEach(key => {
            const config = configs.find(c => c.key == key)
            if (!config) return _.pull(keysNotBeDependent, key)
            _.pull(keysNotBeDependent, ...config.dependentKeys)

            const condition = useConditionFactory(config, eventManager, queryParams, sharedData, console)
            container.value.set(key, condition)

            // useConditionFactory可能会对规则进行加工
            if (!empty(config.rule)) rules.value[config.key] = config.rule

            // 必须条件立马加入workingList,防止事件过早触发
            if (condition.config.required) eventManager.push('dataManager init of required', key)
        })

        // 一般来说必须得有1个非被依赖项，才能构成一个响应链，否则没有机会触发onSearch
        // TODO：这里只是当1个警告，实际运行效果还待评估
        if (!keysNotBeDependent.length) console.warn('At least one key must not be dependent!')
        keysNotBeDependent.forEach(k => {
            watch(() => toValue(queryParams)[k], () => eventManager.trigger('dataManager watch not be dependent of ' + k))
        })
    }, {immediate: true})

    const conditions = computed(() => [...container.value.values()])
    const filterConditions = computed(() => conditions.value.filter(c => !c.config.hidden))
    const needValidation = computed(() => !empty(rules.value))

    const reset = function () {
        container.value.clear()
        rules.value = {}
    }

    return {
        container,
        conditions: filterConditions,
        rules,
        needValidation,
        reset
    }
}