<template>
    <div class="text-item focus-input" :class="[inputSize ? 'focus-input-' + inputSize : '',
    {
      'disabled': disabled,
      'focus-input-group': $slots.prepend || $slots.append,
      'focus-append-input': $slots.append,
      'focus-prepend-input': $slots.prepend,
      'focus-prefix-input': $slots.prefix || prefixIcon,
      'focus-suffix-input': $slots.suffix || suffixIcon
    }]" tabindex="-1">
        <!-- 前置元素 -->
        <div class="focus-input-prepend" v-if="$slots.prepend" tabindex="0">
            <slot name="prepend"></slot>
        </div>

        <input class="input-text" v-bind="$props" :autocomplete="autoComplete" :value="currentValue" ref="input"
               @input="handleInput"
               @focus="handleFocus"
               @blur="handleBlur"
               @change="handleChange"
               :aria-label="label">
        <span class="input-ctnr" v-if="isGroup"></span>

        <!-- 前置内容 -->
        <span class="focus-input-prefix" v-if="$slots.prefix || prefixIcon" :style="prefixOffset">
            <slot name="prefix"></slot>
            <focus-icon class="focus-input-icon" v-if="prefixIcon" :name="prefixIcon"></focus-icon>
        </span>

        <!-- 后置内容 -->
        <span class="focus-input-suffix" v-if="$slots.suffix || suffixIcon || validateState && needStatusIcon" :style="suffixOffset">
            <span class="focus-input-suffix-inner">
                <slot name="suffix"></slot>
                <focus-icon class="focus-input-icon" v-if="suffixIcon" :name="suffixIcon"></focus-icon>
            </span>

            <focus-icon class="focus-input-icon focus-input-validate-icon" v-if="validateState && validateState!=='validating'" :name="validateIcon"></focus-icon>
        </span>
        <!-- 后置元素 -->
        <div class="focus-input-append" v-if="$slots.append">
            <slot name="append"></slot>
        </div>
    </div>
</template>
<script>
    import emitter from 'focus-view/src/mixins/emitter';
    import Focus from 'focus-view/src/mixins/focus';
    import Migrating from 'focus-view/src/mixins/migrating';
    import FocusIcon from 'focus-view/packages/icon';

    export default {
        components: {FocusIcon},
        name: 'focusInput',

        componentName: 'focusInput',

        mixins: [emitter, Focus('input'), Migrating],

        inject: {
            focusForm: {
                default: ''
            },
            focusFormItem: {
                default: ''
            }
        },

        data() {
            return {
                currentValue: this.value,
                prefixOffset: null,
                suffixOffset: null
            };
        },

        props: {
            value: [String, Number],
            placeholder: String,
            size: String,
            resize: String,
            name: String,
            form: String,
            id: String,
            maxlength: Number,
            minlength: Number,
            readonly: Boolean,
            autofocus: Boolean,
            disabled: Boolean,
            type: {
                type: String,
                default: 'text'
            },
            autoComplete: {
                type: String,
                default: 'off'
            },
            max: {},
            min: {},
            step: {},
            validateEvent: {
                type: Boolean,
                default: true
            },
            suffixIcon: String,
            prefixIcon: String,
            label: String
        },

        computed: {
            _elFormItemSize() {
                return (this.focusFormItem || {}).elFormItemSize;
            },
            validateState() {
                return this.focusFormItem ? this.focusFormItem.validateState : '';
            },
            needStatusIcon() {
                return this.focusForm ? this.focusForm.statusIcon : false;
            },
            validateIcon() {
                return {
                    success: 'yes',
                    error: 'error'
                }[this.validateState];
            },
            inputSize() {
                return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
            },
            isGroup() {
                return this.$slots.prepend || this.$slots.append;
            },

            isPlainInput(){
                const $slots = this.$slots;
                return !this.isGroup && !$slots.prefix && !$slots.suffix && !this.prefixIcon && !this.suffixIcon;
            }
        },

        watch: {
            'value'(val, oldValue) {
                this.setCurrentValue(val);
            }
        },

        methods: {
            getMigratingConfig() {
                return {
                    props: {
                        'icon': 'icon is removed, use suffix-icon / prefix-icon instead.',
                        'on-icon-click': 'on-icon-click is removed.'
                    },
                    events: {
                        'click': 'click is removed.'
                    }
                };
            },
            handleBlur(event) {
                this.$emit('blur', event);
                if (this.validateEvent) {
                    this.dispatch('focusFormItem', 'el.form.blur', [this.currentValue]);
                }
            },
            inputSelect() {
                this.$refs.input.select();
            },
            handleFocus(event) {
                this.$emit('focus', event);
            },
            handleInput(event) {
                const value = event.target.value;
                this.$emit('input', value);
                this.setCurrentValue(value);
            },
            handleChange(event) {
                this.$emit('change', event.target.value);
            },
            setCurrentValue(value) {
                if (value === this.currentValue) return;
                this.currentValue = value;
                if (this.validateEvent) {
                    this.dispatch('focusFormItem', 'el.form.change', [value]);
                }
            },
            calcIconOffset(place) {
                const pendantMap = {
                    'suf': 'append',
                    'pre': 'prepend'
                };

                const pendant = pendantMap[place];

                if (this.$slots[pendant]) {
                    return {transform: `translateX(${place === 'suf' ? '-' : ''}${this.$el.querySelector(`.focus-input-${pendant}`).offsetWidth}px)`};
                }
            }
        },

        created() {
            this.$on('inputSelect', this.inputSelect);
        },

        mounted() {
            if (this.isGroup) {
                this.prefixOffset = this.calcIconOffset('pre');
                this.suffixOffset = this.calcIconOffset('suf');
            }
        }
    };
</script>
