
<template>
    <div class="as-picker">
        <span @click="handlePicker">
            <slot :value="computedValue">
                <as-cell-picker
                    :label="label"
                    :placeholder="placeholder"
                    :required="required"
                    :disabled="disabled"
                    :clearable="clearable"
                    :value="computedValue"
                    :formatter="formatter"
                    :is-arrow="isArrow"
                    :is-vertical="isVertical"
                    @input="handleClear"
                ></as-cell-picker>
            </slot>
        </span>
        <van-popup
            round
            position="bottom"
            v-model="isShow">
            <van-picker
                show-toolbar
                :default-index="computedIndex"
                @cancel="isShow = false"
                @confirm="handleConfirm"
                :columns="computedColumns"
                :value-key="labelKey"
            ></van-picker>
            <input
                v-if="filterable"
                placeholder="输入关键词进行筛选"
                class="as-picker-filter"
                type="text"
                v-model="keyword"
            />
        </van-popup>
    </div>
</template>

<script>
    import { Picker, Popup } from 'vant'
    import AsCellPicker from '../as-cell-picker'
    import { isNotEmpty, isObject } from '../../../plugins/utils/validator'
    export default {
        name: 'AsPicker',
        data () {
            return {
                keyword: '',
                isShow: false,
                columns: [],
            }
        },
        props: {
            clearable: { type: Boolean, default: false },
            filterable: { type: Boolean, default: false },
            disabled: { type: Boolean, default: false },
            required: { type: Boolean, default: false },
            isArrow: { type: Boolean, default: true },
            isVertical: { type: Boolean, default: false },
            value: { default: '' },
            label: { default: '' },
            valueKey: { type: String, default: '' },
            labelKey: { type: String, default: '' },
            placeholder: { default: '' },
            options: { default: () => [] },
            optionsTrigger: { type: [String, Array], default: 'lazy' }, // 拉取数据时机 always 每次点击的时候都去拉取  lazy 第一次点击没数据就去加载  init初始化加载
            formatter: { type: Function, default: v => v },
            defaultValue: { default: '' },
        },
        computed: {
            computedIndex () {
                const index = this.columns.findIndex(item => {
                    const v = this.valueKey ? item[this.valueKey] : item
                    const value = this.getValue() || this.defaultValue
                    return value === v
                })
                return index > -1 ? index : 0
            },
            computedValue () {
                if (!isNotEmpty(this.getValue())) {
                    return ''
                }
                const item = this.columns.find(item => {
                    const v = this.valueKey ? item[this.valueKey] : item
                    return this.getValue() === v
                })
                if (item) {
                    return this.labelKey ? item[this.labelKey] : item
                }
                const { value } = this
                if (isObject(value)) {
                    const label = this.labelKey ? value[this.labelKey] : value
                    return isNotEmpty(label) ? label : this.getValue()
                }
                return value
            },
            computedColumns () {
                let columns = this.columns
                if (this.filterable && this.keyword) {
                    columns = this.columns.filter(item => {
                        const l = this.labelKey ? item[this.labelKey] : item
                        return l && l.includes(this.keyword)
                    })
                }
                return columns.length ? columns : ['没有数据']
            },
            computedShowClear() {
                return isNotEmpty(this.getValue()) && !this.disabled && this.clearable
            },
        },
        watch: {
            options: {
                immediate: true,
                handler (v) {
                    if (Array.isArray(v)) {
                        this.columns = v
                    }
                }
            }
        },
        created() {
            this.assignmentData()
        },
        methods: {
            getValue() {
                const { value } = this
                if (isObject(value)) {
                    return this.valueKey ? value[this.valueKey] : value
                }
                return value
            },
            assignmentData () {
                if (this.optionsTrigger.includes('init')
                    && typeof this.options === 'function') {
                    this.options().then((data) => this.columns = data).toast()
                }
            },
            handleClear () {
                let value = ''
                const { labelKey, valueKey } = this
                if (isObject(this.value) && labelKey && valueKey) {
                    value = {}
                    value[labelKey] = ''
                    value[valueKey] = ''
                }
                this.$emit('input', value)
                this.$emit('change', value)
            },
            handlePicker () {
                if (this.disabled) return
                this.keyword = ''
                if (this.optionsTrigger.includes('lazy')
                    && this.columns.length) {
                    return this.isShow = true
                }
                if (typeof this.options === 'function') {
                    return this.options().then(data => {
                        this.columns = data
                        this.isShow = true
                    }).toast()
                }
                this.columns = this.options
                this.isShow = true
            },
            handleConfirm (item, ids) {
                if (item && item !== '没有数据') {
                    let value = item
                    if (Array.isArray(item)) {
                        // 级联或者是多个返回的都是数组值
                        if (
                            !Array.isArray(this.columns[0].values)
                            && item[0]
                            && typeof item[0] !== 'object'
                        ) {
                            // 级联需要单独处理下返回结果
                            value = []
                            let a = this.columns
                            let i = ids.shift()
                            while (i !== undefined) {
                                let it = a[i]
                                value.push(it)
                                a = it.children
                                i = ids.shift()
                            }
                        }
                    } else {
                        value = isObject(this.value) || !this.valueKey ? item : item[this.valueKey]
                    }
                    this.$emit('input', isNotEmpty(value) ? value : '')
                    this.$emit('change', item)
                }
                this.isShow = false
            },
        },
        components: {
            AsCellPicker,
            VanPopup: Popup,
            VanPicker: Picker,
        },
    }
</script>

<style lang="scss" scoped>
    @import "../../assets/scss/define";
    .as-picker{
        &-filter{
            @extend %bsb;
            @extend %w100;
            border: none;
            padding: 0 j(16);
            height: j(40);
            font-size: j(14);
            background-color: transparent;
        }
    }
</style>
