getAccountInfo static method

AccountInfo getAccountInfo(
  1. dynamic message
)

Extracts account information from processed message

Implementation

static AccountInfo getAccountInfo(dynamic message) {
  final processedMessage = MessageProcessor.getProcessedMessage(message);
  // Get original message for card detection
  final String originalMessage = message is String
      ? message
      : message.join(' ');
  int accountIndex = -1;
  AccountInfo account = const AccountInfo(
    type: null,
    name: null,
    number: null,
    walletType: null,
    cardType: null,
    cardScheme: null,
    bankName: null,
  );

  // First, check for UPI IDs
  final upiAccount = _getUpiAccount(message);
  if (upiAccount.type != null) {
    return upiAccount;
  }

  // Then, check for "card" keyword before checking for "ac"
  // This prevents false positives like "c_card" matching "ac"
  final hasCard = processedMessage.any(
    (word) =>
        word == 'card' ||
        combinedWords.any(
          (w) => w.type == AccountType.card && w.word == word,
        ),
  );

  if (hasCard) {
    account = _getCard(processedMessage, originalMessage);
    if (account.type != null) {
      // Extract last 4 digits if card number exists
      if (account.number != null && account.number!.length > 4) {
        account = AccountInfo(
          type: account.type,
          name: account.name,
          number: account.number!.substring(account.number!.length - 4),
          walletType: null,
          cardType: account.cardType,
          cardScheme: account.cardScheme,
          bankName: account.bankName,
        );
      }
      return account;
    }
  }

  // Now check for account number
  for (int index = 0; index < processedMessage.length; index++) {
    final word = processedMessage[index];

    if (word == 'ac') {
      if (index + 1 < processedMessage.length) {
        final accountNo = MessageProcessor.trimLeadingAndTrailingChars(
          processedMessage[index + 1],
        );

        if (!MessageProcessor.isNumber(accountNo)) {
          continue;
        } else {
          accountIndex = index;

          // Detect bank name for account
          String? bankName;
          final lowerMessage = originalMessage.toLowerCase();
          for (final entry in bankNameMap.entries) {
            if (lowerMessage.contains(entry.key)) {
              bankName = entry.value;
              break;
            }
          }

          account = AccountInfo(
            type: AccountType.account,
            name: null,
            number: accountNo,
            walletType: null,
            cardType: null,
            cardScheme: null,
            bankName: bankName,
          );
          break;
        }
      } else {
        continue;
      }
    } else if (word.contains('ac')) {
      final extractedAccountNo = MessageProcessor.extractBondedAccountNo(
        word,
      );

      if (extractedAccountNo.isEmpty) {
        continue;
      } else {
        accountIndex = index;

        // Detect bank name for account
        String? bankName;
        final lowerMessage = originalMessage.toLowerCase();
        for (final entry in bankNameMap.entries) {
          if (lowerMessage.contains(entry.key)) {
            bankName = entry.value;
            break;
          }
        }

        account = AccountInfo(
          type: AccountType.account,
          name: null,
          number: extractedAccountNo,
          walletType: null,
          cardType: null,
          cardScheme: null,
          bankName: bankName,
        );
        break;
      }
    }
  }

  // No occurrence of the word "ac". (Card check was done earlier)
  // Check for wallets
  if (accountIndex == -1 && account.type == null) {
    final wallet = processedMessage.firstWhere(
      (word) => wallets.contains(word),
      orElse: () => '',
    );
    if (wallet.isNotEmpty) {
      // Get the corresponding WalletType
      WalletType? walletType;
      if (walletTypeMap.containsKey(wallet)) {
        final walletTypeName = walletTypeMap[wallet]!;
        walletType = WalletType.values.firstWhere(
          (e) => e.name == walletTypeName,
          orElse: () => WalletType.paytm,
        );
      }

      account = AccountInfo(
        type: AccountType.wallet,
        name: wallet,
        number: null,
        walletType: walletType,
        cardType: null,
        cardScheme: null,
        bankName: null,
      );
    }
  }

  // Check for special accounts
  if (account.type == null) {
    final specialAccount = combinedWords
        .where((word) => word.type == AccountType.account)
        .firstWhere(
          (w) => processedMessage.contains(w.word),
          orElse: () => CombinedWord(
            regex: RegExp(''),
            word: '',
            type: AccountType.account,
          ),
        );
    if (specialAccount.word.isNotEmpty) {
      // Detect bank name for special account
      String? bankName;
      final lowerMessage = originalMessage.toLowerCase();
      for (final entry in bankNameMap.entries) {
        if (lowerMessage.contains(entry.key)) {
          bankName = entry.value;
          break;
        }
      }

      account = AccountInfo(
        type: specialAccount.type,
        name: specialAccount.word,
        number: null,
        walletType: null,
        cardType: null,
        cardScheme: null,
        bankName: bankName,
      );
    }
  }

  // Extract last 4 digits of account number
  if (account.number != null && account.number!.length > 4) {
    account = AccountInfo(
      type: account.type,
      name: account.name,
      number: account.number!.substring(account.number!.length - 4),
      walletType: account.walletType,
      cardType: account.cardType,
      cardScheme: account.cardScheme,
      bankName: account.bankName,
    );
  }

  return account;
}