<template>
    <div class="money-input-container">
      <input
        ref="input"
        :value="displayValue"
        @input="handleInput"
        @keydown="handleKeydown"
        @blur="handleBlur"
        v-bind="$attrs"
        v-on="inputListeners"
      />
    </div>
  </template>
  
  <script>
  export default {
    name: 'MoneyInput',
    inheritAttrs: false,
    props: {
      value: {
        type: [String, Number],
        default: ''
      }
    },
    data() {
      return {
        localValue: '',
        hasComma: false,
        rawDisplayValue: ''
      }
    },
    computed: {
      // Format untuk tampilan
      displayValue() {
        // Jika pengguna baru mengetik, gunakan rawDisplayValue
        if (this.rawDisplayValue) {
          return this.rawDisplayValue;
        }
        
        // Format dari nilai model
        return this.formatValue(this.localValue);
      },
      
      // Event listeners yang diteruskan
      inputListeners() {
        const listeners = { ...this.$listeners };
        
        // Hapus event handlers yang dikelola sendiri
        delete listeners.input;
        delete listeners.keydown;
        delete listeners.blur;
        
        return listeners;
      }
    },
    watch: {
      // Sinkronkan props dengan data lokal
      value: {
        immediate: true,
        handler(newValue) {
          // Hindari loop jika nilai sama
          if (newValue !== this.localValue) {
            this.localValue = newValue;
            this.rawDisplayValue = '';
          }
        }
      }
    },
    methods: {
      // Format nilai untuk tampilan (1234.56 -> 1.234,56)
      formatValue(value) {
        if (!value && value !== 0) return '';
        
        // Convert ke string
        const strValue = value.toString();
        
        // Pisahkan bagian integer dan desimal
        const parts = strValue.split('.');
        const integerPart = parts[0];
        const decimalPart = parts.length > 1 ? parts[1] : '';
        
        // Format bagian integer dengan titik ribuan
        const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, '.');
        
        // Gabungkan dengan format display
        return decimalPart ? `${formattedInteger},${decimalPart}` : formattedInteger;
      },
      
      // Parse dari format display ke nilai model (1.234,56 -> 1234.56)
      parseValue(displayValue) {
        if (!displayValue) return '';
        
        // Pisahkan bagian integer dan desimal
        const parts = displayValue.split(',');
        const integerPart = parts[0].replace(/\./g, ''); // Hapus titik ribuan
        const decimalPart = parts.length > 1 ? parts[1] : '';
        
        // Gabungkan dengan format model (titik untuk desimal)
        return decimalPart ? `${integerPart}.${decimalPart}` : integerPart;
      },
      
      // Tangani event input
      handleInput(event) {
        const input = event.target;
        const cursorPos = input.selectionStart;
        const rawValue = input.value;
        
        // Cek apakah ada koma
        this.hasComma = rawValue.includes(',');
        
        // Pisahkan bagian integer dan desimal
        let integerPart, decimalPart;
        
        if (this.hasComma) {
          const parts = rawValue.split(',');
          integerPart = parts[0];
          decimalPart = parts.length > 1 ? parts[1] : '';
        } else {
          integerPart = rawValue;
          decimalPart = '';
        }
        
        // Format bagian integer (hapus titik lama, tambahkan titik baru)
        const cleanInteger = integerPart.replace(/\./g, '');
        const formattedInteger = cleanInteger.replace(/\B(?=(\d{3})+(?!\d))/g, '.');
        
        // Buat nilai tampilan baru
        this.rawDisplayValue = this.hasComma ? `${formattedInteger},${decimalPart}` : formattedInteger;
        
        // Update model value (tanpa formatter)
        const modelValue = this.hasComma ? `${cleanInteger}.${decimalPart}` : cleanInteger;
        this.localValue = modelValue;
        
        // Emit event
        this.$emit('input', modelValue);
        
        // Set cursor position setelah DOM diupdate
        this.$nextTick(() => {
          // Posisi kursor relatif
          if (this.hasComma) {
            const commaPos = rawValue.indexOf(',');
            
            if (cursorPos <= commaPos) {
              // Hitung pergeseran karena dot formatting
              const oldDotsBeforeCursor = (integerPart.substring(0, cursorPos).match(/\./g) || []).length;
              const newDotsBeforeCursor = (formattedInteger.substring(0, cursorPos).match(/\./g) || []).length;
              const offset = newDotsBeforeCursor - oldDotsBeforeCursor;
              input.setSelectionRange(cursorPos + offset, cursorPos + offset);
            } else {
              // Setelah koma, sesuaikan dengan posisi koma baru
              const newCommaPos = formattedInteger.length;
              const offsetAfterComma = cursorPos - commaPos;
              input.setSelectionRange(newCommaPos + offsetAfterComma, newCommaPos + offsetAfterComma);
            }
          } else {
            // Format tanpa koma
            const oldDots = (rawValue.substring(0, cursorPos).match(/\./g) || []).length;
            const newDots = (this.rawDisplayValue.substring(0, cursorPos).match(/\./g) || []).length;
            input.setSelectionRange(cursorPos + (newDots - oldDots), cursorPos + (newDots - oldDots));
          }
        });
      },
      
      // Tangani tombol koma dan titik
      handleKeydown(event) {
        // Khusus untuk tombol koma dan titik
        if (event.key === ',' || event.key === '.') {
          // Jika sudah ada koma, cegah input
          if (this.rawDisplayValue.includes(',')) {
            event.preventDefault();
            return;
          }
          
          event.preventDefault();
          
          // Ambil nilai dan posisi kursor saat ini
          const input = event.target;
          const cursorPos = input.selectionStart;
          const currentValue = this.rawDisplayValue || this.displayValue;
          
          // Sisipkan koma
          const beforeComma = currentValue.substring(0, cursorPos);
          const afterComma = currentValue.substring(cursorPos);
          const newDisplayValue = beforeComma + ',' + afterComma;
          
          // Set nilai display
          this.rawDisplayValue = newDisplayValue;
          
          // Update model value
          const parts = newDisplayValue.split(',');
          const integerPart = parts[0].replace(/\./g, '');
          const decimalPart = parts.length > 1 ? parts[1] : '';
          const modelValue = integerPart + (decimalPart ? '.' + decimalPart : '');
          
          this.localValue = modelValue;
          this.hasComma = true;
          
          // Emit event
          this.$emit('input', modelValue);
          
          // Set kursor setelah koma
          this.$nextTick(() => {
            input.setSelectionRange(cursorPos + 1, cursorPos + 1);
          });
        }
      },
      
      // Format ulang pada blur
      handleBlur() {
        // Reset raw display value
        this.rawDisplayValue = '';
        
        // Emit event
        this.$emit('blur');
      }
    }
  };
  </script>