import 'package:flutter/services.dart';
import 'package:string_mask/string_mask.dart';

class PhoneMaskInputFormatter extends TextInputFormatter {
  final String mask;
  final String escapeChar;
  final RegExp regExp = RegExp(r'[^\d]+');

  Map<int, String> _separatorMap;

  PhoneMaskInputFormatter({this.mask, this.escapeChar = r'[\d]+'}) {
    assert(mask != null || mask.isNotEmpty);

    final entries = regExp
        .allMatches(mask)
        .map((match) => MapEntry(match.start, match.group(0)));

    _separatorMap = Map.fromEntries(entries);
  }

  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    int oldValueLength = oldValue.text.length;
    int newValueLength = newValue.text.length;

    final StringBuffer newText = StringBuffer();
    if (newValueLength > 0 && newValueLength > oldValueLength) {
      bool shouldSeparate = mask[newValueLength - 1].contains(regExp);
      if (newValueLength > mask.length) {
        newText.write(oldValue.text);
        return oldValue.copyWith(
          text: newText.toString(),
          selection: TextSelection.collapsed(offset: newText.length),
        );
      }
      if (newValueLength < mask.length && shouldSeparate) {
        String separator = _separatorMap[newValueLength - 1];

        newText.write(oldValue.text +
            separator +
            newValue.text.substring(newValueLength - 1));

        return newValue.copyWith(
          text: newText.toString(),
          selection: TextSelection.collapsed(offset: newText.length),
        );
      }
    }

    return newValue;
  }

  TextEditingValue applyMask(TextEditingValue value) {
    final StringBuffer newText = StringBuffer();
    String newMask = mask.replaceAll(RegExp(r'[\d]'), '#');
    var stringMask = StringMask(newMask);

    String newValue = stringMask.apply(value?.text);

    newText.write(newValue);
    return value.copyWith(
      text: newText.toString(),
      selection: TextSelection.collapsed(offset: newText.length),
    );
  }
}