<template>
    <!-- 全局下拉框控件 -->
    <view class="picker" :class="{ 'u-border': ps.border }" :style="style">
        <global-popup v-model="show" :height="592" :customStyle="{ padding: '28rpx 32rpx' }" v-if="filter || multiple" :distance="distance">
            <template #top>
                <view>
                    <up-search :placeholder="placeholder" :showAction="false" v-model="searchKey"></up-search>
                </view>
            </template>
            <view class="popup-content-list" v-if="getFilterColumns.length">
                <view
                    class="popup-content-item u-line-1"
                    :class="{
                        'mocp-color-primary-6': multipleValue.includes(item[valueField])
                    }"
                    v-for="(item, index) in getFilterColumns"
                    :key="index"
                    @tap="handleChoose(item[valueField])"
                >
                    {{ item[labelField] }}
                </view>
            </view>
            <view style="width: 100%; height: 100%" v-else>
                <global-empty></global-empty>
            </view>
            <template #bottom>
                <view style="margin-top: 20rpx" v-if="multiple">
                    <global-button type="primary" :radius="5" @tap="confirmMultiple">确定</global-button>
                </view>
                <view class="customize" style="margin-top: 20rpx" v-if="customize && !getFilterColumns.length">
                    <text>没有找到筛选内容</text>
                    <global-button type="text" :radius="5" @tap="confirmCustomize">添加已输入内容</global-button>
                </view>
            </template>
        </global-popup>
        <up-picker
            v-else
            :show="show"
            :columns="[getColumns]"
            :keyName="labelField"
            @confirm="confirm"
            closeOnClickOverlay
            @close="show = false"
            @cancel="show = false"
            :defaultIndex="[defaultIndex]"
            :cancelText="cancelText"
            :confirmText="confirmText"
            :cancelColor="cancelColor"
            :confirmColor="confirmColor"
        ></up-picker>
        <view class="picker-content" :class="getPickerClass" @tap="open" :style="getContentStyle">
            <text class="picker-value">{{ getLabelValue }}</text>
            <view class="picker-icon">
                <view class="picker-icon-close" v-if="clearable && !showPlaceholder && !disabled" @tap.stop="clear">
                    <up-icon name="close-circle-fill" color="#c0c4cc" size="36rpx"></up-icon>
                </view>
                <up-icon name="arrow-right" color="#86909C" size="36rpx"></up-icon>
            </view>
        </view>
    </view>
</template>

<script setup>
import { computed, nextTick, ref, watch } from 'vue'
import * as dictData from 'mocp/hooks/use-dict/dict-data'
import { cloneDeep, min } from 'lodash'
import { getParamsByType } from 'mocp/hooks/use-params/useParams'

const es = defineEmits(['update:modelValue', 'change', 'getScrollTop'])
const ps = defineProps({
    //是否筛选
    filter: {
        type: Boolean,
        default: false
    },
    //是否有边框
    border: {
        type: Boolean,
        default: false
    },
    //是否多选(只对filter有效)
    multiple: {
        type: Boolean,
        default: false
    },
    //是否筛选不到的时候可以自定义内容(只对filter有效)
    customize: {
        type: Boolean,
        default: false
    },
    style: {
        type: Object,
        default: () => {
            return {}
        }
    },
    //显示为空的value值
    emptyValue: {
        type: [String, Number],
        default: ''
    },
    dictkey: {
        type: String,
        default: ''
    },
    paramsType: {
        type: String,
        default: ''
    },
    modelValue: {
        type: [String, Number],
        default: ''
    },
    options: {
        type: [Array, Object],
        default: () => {
            return []
        }
    },
    clearable: {
        type: Boolean,
        default: false
    },
    labelField: {
        type: String,
        default: 'label'
    },
    valueField: {
        type: String,
        default: 'value'
    },
    valueSplit: {
        type: String,
        default: ','
    },
    pickAlign: {
        type: String,
        default: 'left'
    },
    placeholder: {
        type: String,
        default: '请选择'
    },
    disabled: {
        type: Boolean,
        default: false
    },
    cancelText: {
        type: String,
        default: '取消'
    },
    confirmText: {
        type: String,
        default: '确认'
    },
    cancelColor: {
        type: String,
        default: '#909193'
    },
    confirmColor: {
        type: String,
        default: '#165dff'
    },
    //打开前判断
    onBeforeOpen: {
        type: Function,
        default: null
    }
})
//获取下拉框样式
const getContentStyle = computed(() => {
    let pickAlign = 'space-between'
    if (ps.pickAlign == 'center') {
        pickAlign = 'center'
    } else if (ps.pickAlign == 'right') {
        pickAlign = 'flex-end'
    }
    return {
        justifyContent: pickAlign
    }
})
//下拉框显示的内容
const labelValue = ref('')
const getLabelValue = computed(() => {
    if (labelValue.value == ps.emptyValue) {
        return ps.placeholder
    }
    return labelValue.value || ps.placeholder
})
//获取下拉框class
const showPlaceholder = computed(() => {
    return !labelValue.value || labelValue.value == ps.emptyValue
})
const getPickerClass = computed(() => {
    return {
        disabled: ps.disabled,
        placeholder: showPlaceholder.value
    }
})
const show = ref(false)
//打开
const open = async () => {
    if (ps.onBeforeOpen) {
        const flag = await ps.onBeforeOpen()
        if (!flag) return
    }
    searchKey.value = ''
    show.value = true
    if (ps.modelValue) {
        multipleValue.value = ps.modelValue.split(ps.valueSplit)
    } else {
        multipleValue.value = []
    }
}
//设置下拉框打开的默认值
const defaultIndex = ref(0)
//获取下拉框的内容Columns
const getColumns = computed(() => {
    if (ps.dictkey) {
        if (dictData[ps.dictkey]) {
            return cloneDeep(dictData[ps.dictkey])
        } else {
            throw new Error('请输入存在的dictkey值')
        }
    } else if (ps.paramsType) {
        return getParamsByType(ps.paramsType) || []
    } else {
        if (ps.options) {
            if (Array.isArray(ps.options)) {
                if (Object.prototype.toString.call(ps.options[0]) == '[object Object]') {
                    return ps.options
                } else {
                    return ps.options.map((item) => {
                        return {
                            [ps.labelField]: item,
                            [ps.valueField]: item
                        }
                    })
                }
            } else {
                return Object.values(ps.options).map((v, i) => {
                    return {
                        [ps.labelField]: v,
                        [ps.valueField]: i
                    }
                })
            }
        }
    }
    return []
})
//监听设置labelValue的值
const multipleValue = ref([])
watch(
    [() => ps.modelValue, () => ps.options],
    () => {
        if (ps.multiple) {
            if (ps.modelValue) {
                labelValue.value = ps.modelValue
                    .split(ps.valueSplit)
                    .map((item) => {
                        return getColumns.value.find((option) => String(option[ps.valueField]) === String(item))[ps.labelField]
                    })
                    .join(ps.valueSplit)
                const indexs = ps.modelValue.split(ps.valueSplit).map((item) => {
                    return getColumns.value.findIndex((option) => String(option[ps.valueField]) === String(item))
                })
                nextTick(() => {
                    defaultIndex.value = min(indexs)
                })
            } else {
                defaultIndex.value = 0
            }
        } else {
            const option = getColumns.value?.find((option) => String(option[ps.valueField]) === String(ps.modelValue))
            const index = getColumns.value?.findIndex((option) => String(option[ps.valueField]) === String(ps.modelValue))
            if (option) {
                labelValue.value = option[ps.labelField]
                nextTick(() => {
                    defaultIndex.value = index
                })
            } else {
                labelValue.value = ps.modelValue
                defaultIndex.value = 0
            }
        }
    },
    { immediate: true }
)
watch(show, (value) => {
    uni.$emit('changeShowBottom', value)
})
//点击确定按钮
const confirm = (e) => {
    show.value = false
    const index = e.indexs[0]
    labelValue.value = getColumns.value[index][ps.labelField]
    es('update:modelValue', getColumns.value[index][ps.valueField])
    es('change', getColumns.value[index][ps.valueField], getColumns.value[index])
}
const confirmMultiple = () => {
    show.value = false
    es('update:modelValue', multipleValue.value.join(ps.valueSplit))
    es('change', multipleValue.value.join(ps.valueSplit))
}
//确定自定义内容
const confirmCustomize = () => {
    show.value = false
    es('update:modelValue', searchKey.value)
    es('change', searchKey.value)
}
//点击清空按钮
const clear = () => {
    labelValue.value = ''
    defaultIndex.value = 0
    es('update:modelValue', ps.emptyValue)
    es('change', ps.emptyValue)
}
//弹出层输入框搜索
const searchKey = ref('')
const getFilterColumns = computed(() => {
    return getColumns.value.filter((item) => item[ps.labelField].toLowerCase().includes(searchKey.value.toLowerCase()))
})
//弹出层列表点击
const distance = ref(0)
const handleChoose = (value) => {
    if (ps.multiple) {
        if (multipleValue.value.includes(value)) {
            multipleValue.value = multipleValue.value.filter((item) => item != value)
        } else {
            multipleValue.value.push(value)
        }
    } else {
        es('update:modelValue', value)
        es(
            'change',
            value,
            getColumns.value.find((item) => item[ps.valueField] == value)
        )
        show.value = false
    }
}
//打开默认滑动到选中的位置
watch(
    defaultIndex,
    (value) => {
        distance.value = value * 39
    },
    { immediate: true }
)
</script>
<style lang="scss" scoped>
.picker {
    flex: auto;
    height: 100%;
    border-radius: 4px;
    padding-left: 18rpx;
    box-sizing: border-box;
    &-content {
        height: 100%;
        display: flex;
        align-items: center;
        line-height: 48rpx;
        &.placeholder {
            .picker-value {
                color: $mocp-text-3;
            }
        }
        &.disabled {
            background: #f5f7fa;
        }
    }
    &-value {
        color: $mocp-text-4;
        margin-right: 8rpx;
        word-break: break-all;
    }
    &-icon {
        display: flex;
        align-items: center;
        &-close {
            margin-left: 4rpx;
        }
    }
    .popup-content {
        &-list {
            padding-top: 20rpx;
            color: $mocp-text-4;
        }
        &-item {
            margin-bottom: 40rpx;
            &:last-child {
                margin-bottom: 0;
            }
        }
    }
    .customize {
        display: flex;
        justify-content: space-between;
        align-items: center;
        background: $mocp-fill-1;
        padding: 10rpx 20rpx;
    }
}
</style>
