<template lang="pug">
    .input-group
        .input-group-button(v-if='withPrefix')
            button(type='button') {{ prefix }}
        input.form-input(type='text' v-model='formattedValue' :style="{'width': withPrefix || withSuffix ? '88%' : '100%'}")
        .input-group-button(v-if='withSuffix')
            button(type='button' @click='onShowSuffixOptions' ref='suffixButton') {{ suffix }}
                span.caret(:style="{'display': withSuffixOptions() ? 'none' : 'inline-block'}")
            ul.dropdown(:style="{'display': isShowSuffixOptions ? 'block' : 'none'}" ref='suffixDropdown')
                li(v-for='option in suffixOptions' :key='option.id')
                    a(@click='onClickSuffixOption(option)') {{ option.name }}
</template>

<script>
    export default {
        props: {
            value: {
                type: String,
                default: ''
            },
            format: {
                type: String,
                default: 'text'
            },
            withPrefix: {
                type: Boolean,
                default: false
            },
            prefix: {
                type: String,
                default: ''
            },
            prefixOptions: {
                type: Array,
                default: []
            },
            withSuffix: {
                type: Boolean,
                default: false
            },
            suffix: {
                type: String,
                default: ''
            },
            suffixOptions: {
                type: Array,
                default: []
            }
        },
        computed: {
            formattedValue: {
                get() {
                    let value = ''

                    if (this.format === 'number') {
                        value = this.formatValue(this.value)
                        value = !!this.value ? value : value.replace(/\d/, '')
                    }

                    return value
                },
                set(value) {
                    if (this.format === 'number') {
                        value = this.unformatValue(value)
                    }

                    this.value = value

                    this.onChange(value)
                }
            }
        },
        methods: {
            formatValue(value, options) {
                value = value.toString()

                if (!(options instanceof Object)) {
                    options = {}
                }

                options.thousandsSeparator = options.thousandsSeparator || '.'
                options.decimalPlaces = options.decimalPlaces >= 0 || options.decimalPlaces <= 2 ? options.decimalPlaces : 2
                options.decimalSeparator = options.decimalSeparator || ','
                options.decimalZeros = !!options.decimalZeros

                if (!!(`${options.thousandsSeparator}${options.decimalSeparator}`).replace(/\.,|,\./g, '')) {
                    throw new Error('Same thousands and decimal separator is not allowed')
                }

                value = value.split('.')

                value[0] = value[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, `$1${options.thousandsSeparator}`)

                if (!!value[1]) {
                    value[1] = Number.parseFloat(`1.${value[1]}e${options.decimalPlaces}`)
                    value[1] = Math.round(value[1]).toString().replace(/^1/, '')
                }

                value = value.join(options.decimalSeparator)

                if (!options.decimalZeros) {
                    value = value.replace(/([\.|,]\d)0$/, '$1')
                }

                return value
            },
            unformatValue(value) {
                value = value.replace(/[\.|,](\d{0,2}$)/, '?$1').split(/\?/)
                value[0] = value[0].replace(/[^0-9]/g, '')
                value = Number.parseFloat(value.join('.')) || 0

                return value
            },
            onChange(data) {
                this.$emit('onChange', data)
            },
            hideSuffixOptions() {
                this.isShowSuffixOptions = false
            },
            withPrefixOptions() {
                return this.prefixOptions.length == 0
            },
            withSuffixOptions() {
                return this.suffixOptions.length == 0
            },
            onShowSuffixOptions() {
                if (this.withSuffixOptions()) {
                    return
                }

                this.isShowSuffixOptions = !this.isShowSuffixOptions
            },
            onClickOutside(e) {
                let suffixButton = this.$refs.suffixButton

                if (!suffixButton) {
                    return
                }

                let target = e.target

                if (target === suffixButton) {
                    return
                }

                let el = this.$refs.suffixDropdown
                
                if (el !== target && !el.contains(target)) {
                    this.hideSuffixOptions()
                }
            },
            onClickSuffixOption(suffixOption) {
                this.hideSuffixOptions()
                this.$emit('onSuffix', suffixOption)
            }
        },
        created() {
            document.addEventListener('click', this.onClickOutside)
        },
        destroyed() {
            document.removeEventListener('click', this.onClickOutside)
        },
        data() {
            return {
                value: '',
                isShowSuffixOptions: false
            }
        }
    }
</script>

<style lang="sass">
    .input-group
        position: relative
        display: table
        border-collapse: separate
        .form-input
            position: relative
            width: 100%
            height: 35px
            float: left
            z-index: 2
            display: table-cell
            margin-bottom: 0
            border-radius: 0
            font-size: 12pt
            line-height: 1.42857143
            padding: 6px 12px
            &:focus
                z-index: 3
        .input-group-button
            position: relative
            font-size: 0
            width: 1%
            white-space: nowrap
            vertical-align: middle
            display: table-cell
            &:first-child
                & > button
                    margin-right: -1px
            &:last-child
                & > button
                    margin-left: -1px
            button
                height: 35px
                display: inline-block
                margin-bottom: 0
                text-align: center
                vertical-align: middle
                white-space: nowrap
                border: 1px solid #ccc
                border-radius: 0
                box-shadow: none
                background: #e0e0e0
                z-index: 2
                position: relative
                user-select: none
                &:focus
                    outline: 0 !important
                    border: 1px solid #ccc
                    box-shadow: none
                &:caret
                    display: inline-block
                    width: 0
                    height: 0
                    margin-left: 2px
                    vertical-align: middle
                    border-top: 4px dashed
                    border-right: 4px solid transparent
                    border-left: 4px solid transparent
            .dropdown
                position: absolute
                top: 100%
                float: left
                left: auto
                right: 0
                list-style: none
                text-align: left
                border: 1px solid #ccc
                background-color: #fff
                background-clip: padding-box
                min-width: 160px
                padding: 5px 0
                margin: 2px 0 0
                z-index: 1000
                & > li > a
                    height: 35px
                    display: block
                    padding: 3px 20px
                    clear: both
                    font-weight: normal
                    line-height: 2.1
                    white-space: nowrap
                    color: #333
                    border-bottom: 1px solid #e5e5e5
                    &:hover, &:focus
                        text-decoration: none
                        border-bottom: 2px solid #7c7bad
</style>