<template>
    <uv-popup ref="popup" mode="top" :safe-area-inset-bottom="false" :offset-top="relTop" @change="handleChange">
        <scroll-view scroll-y style="max-height: 35vh;">
            <view class="w-screen px-30 py-10 box-border" @touchmove.stop>
                <component :is="comp" v-model="model[config.key]" placement="column" icon-placement="right">
                    <component :is="itemComp" v-for="i in list" :name="getValue(i)" :label="getLabel(i)"/>
                </component>
            </view>
        </scroll-view>
        <mx-bottom-buttons left-type="primary" left="重置" :right="right" class="p-30"
                           @left="handleReset" @right="handleConfirm"/>
    </uv-popup>
</template>

<script setup>
import {ref, computed} from 'vue';
import {useElementBounding} from "@vueuse/core";
import {useInjectConditionDropdownPopup} from "@/components/mx-condition-dropdown/useConditionDropdownPopupInjection";
import {deepClone, sleep} from "@/uni_modules/uv-ui-tools/libs/function";
import {useInjectSearchModel} from "@/components/mx-condition/useSearchModelInjection";
import UvCheckboxGroup from "@/uni_modules/uv-checkbox/components/uv-checkbox-group/uv-checkbox-group.vue";
import UvRadioGroup from "@/uni_modules/uv-radio/components/uv-radio-group/uv-radio-group.vue";
import UvCheckbox from "@/uni_modules/uv-checkbox/components/uv-checkbox/uv-checkbox.vue";
import UvRadio from "@/uni_modules/uv-radio/components/uv-radio/uv-radio.vue";
import {func} from "@/uni_modules/uv-ui-tools/libs/function/test";

const popup = ref(null)
const {bottom, container} = useInjectConditionDropdownPopup()
const {queryParams} = useInjectSearchModel()
const model = ref({}) // 存放queryParams副本
const show = ref(false)

const condition = ref(null)
const list = computed(() => condition.value?.list || [])
const config = computed(() => condition.value?.config || {})
const multiple = computed(() => config.value?.multiple)
const comp = computed(() => multiple.value ? UvCheckboxGroup : UvRadioGroup)
const itemComp = computed(() => multiple.value ? UvCheckbox : UvRadio)

const right = computed(() => {
    if (!multiple.value) return '确定'
    const cur = model.value[config.value.key]
    if (cur.length < 1) return '确定'
    return `确定(${cur.length})`
})

// TODO: 相对位置不精准
// baseTop 理论上应该找当前容器的值，但目前筛选器是紧贴swiper容器的，所以取的是筛选器的顶部
// 如果以后有定位不对的情况，请修正该值
const {top: baseTop} = useElementBounding(container)
const {bottom: baseBottom} = useElementBounding(bottom)
const relTop = computed(() => baseBottom.value - baseTop.value - 1)

const handleReset = () => {
    // 重置本地model状态
    if (multiple.value) model.value[config.value.key] = []
    else model.value[config.value.key] = ''
    if (config.value.defaultValue) {
        let val = config.value.defaultValue
        if (func(val)) val = val(condition.value)
        model.value[config.value.key] = val
    }
}

const handleConfirm = () => {
    // 将本地model状态赋值回queryParams
    const key = config.value.key
    queryParams.value[key] = model.value[key]
    close()
}

const open = function (cond) {
    // console.log('open begin', new Date().getTime())
    if (cond == condition.value && show.value) {
        popup.value.close()
        // console.log('open end', new Date().getTime())
    } else {
        condition.value = cond
        // 每次打开都创建一个副本，用户确认后才将结果反向从model赋回queryParams
        model.value = deepClone(queryParams.value)
        popup.value.open()
        // console.log('open end', new Date().getTime())
    }
}

const close = function () {
    // console.log('close begin', new Date().getTime())
    popup.value.close()
    // console.log('close end', new Date().getTime())
}

const handleChange = async function (e) {
    // console.log('change begin', new Date().getTime())
    show.value = e.show
    await sleep()
    if (!show.value) {
        // always clean current condition&model while hidden.
        condition.value = null
        model.value = {}
    }
    // console.log('change end', new Date().getTime())
}

const getLabel = (item) => config.value.keyName ? item[config.value.keyName] : item
const getValue = (item) => config.value.keyValue ? item[config.value.keyValue] : item

defineExpose({open, close, show, condition})
</script>

<style scoped lang="scss">
::v-deep(.uv-checkbox-group),
::v-deep(.uv-radio-group) {
    .uv-checkbox-label--right,
    .uv-radio-label--right {
        padding-top: 20rpx;
        padding-bottom: 20rpx;
        border-bottom: 0.5px solid var(--border-color);
    }
}
</style>