<template>
  <div class="itf-money-field ph-no-capture" :class="{'currency-arrow': !currencyDisabled, 'currency-select': currencySelect}">
    <div class="h-100" :class="{'input-group h-100': noCurrencySign}" :style="`--itf-money-field-padding-left: ${noCurrencySign ? 1 : selectedCurrencySymbol.length * 0.6 + 1}rem`">
      <span class="itf-money-field__prepend" v-if="!noCurrencySign">{{ selectedCurrencySymbol }}</span>
      <i-mask-component
        ref="input"
        v-bind="mask"
        class="form-control"
        :class="{ 'is-invalid': isInvalid(), 'is-valid': isSuccess() }"
        @input="setValue"
        :value="maskedValue"
        :placeholder="placeholder"
        :unmask="false"
        :disabled="disabled"
      />
    </div>
    <slot name="postfix">
      <div v-if="currencySelect" class="itf-money-field__currency">
        <span>{{ selectedCurrencyCode }}<itf-icon v-if="!currencyDisabled && currenciesList.length > 1" name="chevron_down" /></span>
        <select v-if="!disabled && !currencyDisabled" :value="currencyId" @input="onCurrencyChanged">
          <option v-for="currency in currenciesList" :key="currency[itemKey]" :value="currency[itemKey]" :selected="currencyId === currency[itemKey]">
            {{ currency[symbolKey] }}, {{ currency[codeKey] }} - {{ currency[titleKey] }}
          </option>
        </select>
      </div>
    </slot>
  </div>
</template>
<style lang="scss">
.itf-money-field {
  position: relative;

  input {
    padding-left: var(--itf-money-field-padding-left, 1.5rem);

    &.is-invalid, &.is-valid {
      padding-right: 4rem;
    }
  }
  &.currency-select {
    input {
      padding-right: 3rem;
    }
    &.currency-arrow {
      input {
        padding-right: 4.5rem;
      }
    }
  }

  &__prepend {
    position: absolute;
    left: .75rem;
    top: .5rem;
    bottom: .5rem;
    display: flex;
    align-items: center;
  }
  &__currency {
    position: absolute;
    right: .75rem;
    top: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    .is-invalid &, .is-valid & {
      right: 1.75rem;
    }

    select {
      position: absolute;
      height: 100%;
      right: 0;
      opacity: 0;
      left: 0;
    }
  }
}
</style>
<script>
import {Component, Emit, Inject, Model, Prop, Vue} from 'vue-property-decorator';
import { IMask, IMaskComponent } from 'vue-imask';
import itfTextField from './TextField';
import itfSelect from '../select/Select';
import itfLabel from '../form/Label';
import itfIcon from '../icon/Icon';
import {stringToNumber} from '../../helpers/formatters';
import ITFSettings from '../../ITFSettings';

export default @Component({
  name: 'itfMoneyField',
  components: {
    itfIcon,
    itfLabel,
    itfSelect,
    itfTextField,
    IMaskComponent,
  }
})
class itfMoneyField extends Vue {
  @Inject({ default: null }) itemLabel;

  @Model('input', { default: '' }) value;
  @Prop({ default: '' }) placeholder;
  @Prop({ type: Object, default: null }) currency;
  @Prop({ type: Boolean, default: false }) noCurrencySign;
  @Prop({ type: Boolean, default: false }) disabled;
  @Prop({ type: Boolean, default: true }) currencySelect;
  @Prop({ type: Array, default: () => ([]) }) currencies;
  @Prop({ type: Boolean, default: false }) currencyDisabled;
  @Prop({ type: String, default: 'Id' }) itemKey;
  @Prop({ type: String, default: 'Code' }) codeKey;
  @Prop({ type: String, default: 'Symbol' }) symbolKey;
  @Prop({ type: String, default: 'Title' }) titleKey;
  @Prop({ type: String, default: 'Precision' }) precisionKey;
  @Prop({ type: Number, default: -1000000000}) minValue;
  @Prop({ type: Number, default: 1000000000}) maxValue;

  get currenciesList() {
    return this.currencies?.length ? this.currencies : ITFSettings.currencies;
  }

  get mask() {
    return {
      mask: Number,
      scale: this.precition,  // digits after point, 0 for integers
      thousandsSeparator: '',  // any single char
      padFractionalZeros: false,  // if true, then pads zeros at end to the length of scale
      normalizeZeros: true,  // appends or removes zeros at ends
      radix: '.',  // fractional delimiter
      mapToRadix: [','],  // symbols to process as radix
      min: this.minValue,
      max: this.maxValue
    };
  }

  get maskedValue() {
    return (this.value   !== null && typeof this.value !== 'undefined') ? this.value.toString() : '';
  }

  isInvalid() {
    return this.itemLabel && this.itemLabel.isHasError();
  }

  isSuccess() {
    return this.itemLabel && this.itemLabel.isHasSuccess();
  }

  onCurrencyChanged(e) {
    const currency = this.currenciesList.find((c) => `${c[this.itemKey]}` === `${e.target.value}`);
    this.$emit('update:currency', currency)
  }

  get precition() {
    return this.selectedCurrency ? this.selectedCurrency[this.precisionKey] : 2;
  }

  get selectedCurrencySymbol() {
    return this.selectedCurrency ? this.selectedCurrency[this.symbolKey] : '';
  }

  get selectedCurrencyCode() {
    return this.selectedCurrency ? this.selectedCurrency[this.codeKey] : '';
  }

  get currencyId() {
    return this.selectedCurrency && this.selectedCurrency[this.itemKey];
  }

  get selectedCurrency() {
    if (!this.currency || !this.currenciesList) {
      return this.currenciesList.find(({ IsDefault }) => IsDefault) || null;
    }
    return this.currenciesList.find((itm) => this.currency[this.itemKey] === itm[this.itemKey]);
  }

  setValue (val) {
    if (val === '') {
      this.$emit('input', '');
      return;
    }
    if (!isNumeric(val) || (val || '').toString().match(/\..*0$/)) { // що не видаляло останній нуль вкінці
      return;
    }
    this.$emit('input', stringToNumber((val || '').toString().replace(/,/g, '')));

    function isNumeric(value) {
      return /^-?\d+([\,\.]\d+)?$/.test(value);
    }
  }
}
</script>
