<template>
    <Popper
        :trigger="trigger"
        transitionName="gd-fade"
        :visible="visible && !disabled"
        @update:visible="v => {disabled ? null: visible = v}"
        tag="span"
        :lazy="lazy"
        :appendToBody="appendToBody"
        :arrow="false"
        :placement="placement"
        ref="select"
        :class="bem({ border, disabled })"
        :modifiers="{ offset: { offset  }}"
    >
        <em v-if="currentLabel" :class="bem('label')">{{currentLabel}}</em>
        <em v-else :class="bem('placeholder')">{{placeholder}}</em>
        <i v-if="!disabled" :class="bem('arrow')"/>

        <ul
            :class="[bem('popover'), popoverClass]"
            slot="content"
            ref='popup'
            :style="getPopperStyle()"
        >
            <li
                v-for="item in options"
                :key="item.key || item.value || item.name"
            >
                <Option
                    :label="item.label"
                    :value="item.value"
                >
                    <!-- 可以自定义选项项渲染 默认渲染label -->
                    <slot :data="item" :setOption="setOption" />
                </Option>
            </li>
        </ul>
    </Popper>
</template>
<script>
import Popper from '../Popover';
import Option from './Option';
import { createComponentName, componentMixin } from '../_utils/component.js';

export default {
    name: createComponentName('select'),
    components: {
        Popper,
        Option
    },
    mixins: [componentMixin],
    model: {
        prop: 'value',
        event: 'change'
    },
    provide() {
        return {
            select: this
        };
    },
    props: {
        // 下拉菜单触发方式
        trigger: {
            //  'click' / 'hover' / null
            type: String,
            default: 'click',
            validator: value => ['click', 'hover', null].indexOf(value) > -1,
        },
        disabled: {
            type: Boolean,
            default: false,
        },
        lazy: {
            type: Boolean,
            default: true,
        },
        appendToBody: {
            type: Boolean,
            default: true,
        },
        /**
         * 浮层位置
         */
        placement: {
            // 'top-start' 'top' 'top-end' 'left-start' 'left' 'left-end' 'bottom-start' 'bottom' 'bottom-end'
            type: String,
            default: 'bottom-start',
        },
        // 选项
        options: {
            // {value: string; label: string, key?: string}[]
            type: Array,
            default: () => []
        },
        // 占位符, value 没有值时展示
        placeholder: {
            type: String,
        },
        // 当前值 可用配合 v-model 使用
        value: {
            type: [String, Number, Array],
            default: ''
        },
        // 偏移位置
        offset: {
            type: String,
            default: '0,6,0,0'
        },
        // 默认值
        defaultValue: {
            type: String,
            default: ''
        },
        // 下拉菜单浮层样式
        popoverStyle: {
            type: Object,
            default() {
                return {};
            }
        },
        // 下拉菜单浮层class
        popoverClass: {
            type: String,
        },
        // 显示边框
        border: {
            type: Boolean,
            default: false,
        }
    },
    data() {
        let value = '';
        if (this.$hasProp('value')) {
            value = this.value;
        }
        else if (this.$hasProp('defaultValue')) {
            value = this.defaultValue;
        }

        return {
            innerValue: value,
            visible: false,
            label: '',
        };
    },
    computed: {
        currentValue() {
            if (this.$hasProp('value')) {
                return this.value;
            }
            return this.value || this.innerValue;
        },
        currentLabel() {
            if (!this.currentValue) return '';
            const option = this.options.find(opt => opt.value === this.currentValue);
            return option ? option.label : '';
        },
    },
    methods: {
        setOption(value, label) {
            this.innerValue = value;
            this.label = label;
            this.visible = false;
            // 修改选项值触发
            this.$emit('change', value);
        },
        getPopperStyle() {
            if (this.$refs.select && this.visible) {
                this.lastWidth = `${this.$refs.select.$el.clientWidth}px`;
            }

            return Object.assign({ width: this.lastWidth }, this.popoverStyle);
        }
    }
};
</script>

<style lang="less">
@import '../_styles/base.less';

.@{select} {
    display: inline-flex;
    align-items: center;
    color: @color-font;
    cursor: pointer;
    font-size: 14px;
    height: 30px;
    width: 200px;
    position: relative;
    vertical-align: top;
    text-align: left;

    box-sizing: content-box;

    &--disabled {
        cursor: default;
    }

    &--border {
        border: 1px solid @border-color-default;

        .@{select}__placeholder {
            color: @color-stroke;
        }
    }

    &--small {
        width: 115px;
    }

    &__placeholder,
    &__label {
        display: block;
        background: #fff;
        padding: 0 28px 0 12px;
        width: 100%;
        overflow: hidden;
        white-space: nowrap;
        word-wrap: normal;
        font-style: normal;
        text-overflow: ellipsis;
    }

    &__arrow {
        position: absolute;
        right: 10px;
        width: 0;
        height: 0;
        border-left: 5px solid transparent;
        border-right: 5px solid transparent;
        border-top: 5px solid #000;
    }

    &__popover {
        background: #fff;
        margin: 0;
        max-height: 276px;
        box-shadow: 0px 10px 14px rgba(53, 100, 175, .15);
        border: none;
        overflow: auto;
        overflow-x: hidden;
        padding: 8px 0;


        li {
            margin: 0;
            list-style: none;
        }
    }
}

</style>

