<template lang="pug">
    div
        .input-group
            .input-group-button(v-if='hasPrefix()')
                button(type='button') {{ prefix }}
            input.input-formatted(
                v-model='formattedValue'
                type='text'
                :disabled='!editable'
                :autofocus='focus'
            )
            .input-group-button(v-if='hasSuffix()')
                button(
                    type='button'
                    @click='onShowOptions()'
                    ref='suffixButton'
                ) {{ suffix }}
                    span.caret(:style="{'display': hasOptions() ? 'inline-block' : 'none'}")
                ul.dropdown(
                    :style="{'display': isShowOptions ? 'block' : 'none'}"
                    ref='suffixDropdown'
                )
                    li(
                        v-for='(option, index) in options'
                        :key='index'
                    )
                        a(@click='onClickOption(option)') {{ option }}
</template>

<script>
    export default {
        props: {
            value: {
                type: Number,
                default: 0
            },
            format: {
                type: String,
                default: 'text'
            },
            editable: {
                type: Boolean,
                default: true
            },
            focus: {
                type: Boolean,
                default: false
            },
            prefix: {
                type: String,
                default: ''
            },
            suffix: {
                type: String,
                default: ''
            },
            options: {
                type: Array,
                default: []
            }
        },
        computed: {
            formattedValue: {
                get() {
                    let value = this.value

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

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

                    this.value = value

                    this.onChangeValue(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
            },
            hideOptions() {
                this.isShowOptions = false
            },
            onChangeValue(value) {
                this.$emit('onChangeValue', value)
            },
            hasPrefix() {
                return !!this.prefix && this.prefix.length !== 0
            },
            hasSuffix() {
                return !!this.suffix && this.suffix.length !== 0
            },
            hasOptions() {
                return this.options.length !== 0
            },
            onShowOptions() {
                if (!this.hasOptions()) {
                    return
                }
                
                this.isShowOptions = !this.isShowOptions
            },
            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.hideOptions()
                }
            },
            onClickOption(selectedOption) {
                this.hideOptions()
                this.$emit('onClickOption', selectedOption)
            }
        },
        created() {
            document.addEventListener('click', this.onClickOutside)
        },
        destroyed() {
            document.removeEventListener('click', this.onClickOutside)
        },
        data() {
            return {
                value: '',
                isShowOptions: false
            }
        }
    }
</script>

<style lang="sass">
    @import '../../assets/variables'

    .input-group
        position: relative
        width: 100%
        display: table
        border-collapse: separate
        .input-formatted
            position: relative
            width: 100%
            height: 35px
            float: left
            z-index: 2
            display: table-cell
            margin-bottom: 0
            border-radius: 0
            font-size: 12pt
            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: $app-main-color
                color: #fff
                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: 0
                    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
                font-size: 10pt
                & > 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>