اريد ان تتغير القيم بشكل مباشرة عند ادخال قيمة الى الحقل 
ملاحظة القيم المشار اليها هي الرصيد السابق و الرصيد الحالي والرصيد المضاف
الكود
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:telephony/telephony.dart';
import 'package:flutter_contacts/flutter_contacts.dart';

const backgroundColor = Color(0xFFF9F9F9);
const primaryColor = Color(0xFF2C3E50);
const accentColor = Color(0xFFf4721e);
const progressColor = Color(0xFFf4721e);

const tajawalFont = 'Tajawal';

class ThousandsSeparatorInputFormatter extends TextInputFormatter {
  @override
  TextEditingValue formatEditUpdate(
    TextEditingValue oldValue,
    TextEditingValue newValue,
  ) {
    String onlyDigits = newValue.text.replaceAll(RegExp(r'[^0-9]'), '');
    if (onlyDigits.isEmpty) return newValue.copyWith(text: '');
    final buffer = StringBuffer();
    int len = onlyDigits.length;
    for (int i = 0; i < len; i++) {
      buffer.write(onlyDigits[i]);
      int posFromRight = len - i - 1;
      if (posFromRight % 3 == 0 && i != len - 1) buffer.write(',');
    }
    return TextEditingValue(
      text: buffer.toString(),
      selection: TextSelection.collapsed(offset: buffer.length),
    );
  }
}

class SplashScreen extends StatefulWidget {
  const SplashScreen({super.key});

  @override
  State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen>
    with TickerProviderStateMixin {
  bool _isLoading = true;
  bool _hasSavedBalance = false;

  int _previousBalance = 0;
  int _currentBalance = 0;
  int _totalBalance = 0;

  late TextEditingController _balanceController;

  late AnimationController _animationController;
  late Animation<double> _logoScaleAnimation;
  late Animation<Offset> _contentSlideAnimation;
  late Animation<double> _fadeAnimation;

  final Telephony telephony = Telephony.instance;

  List<Contact> _contacts = [];

  @override
  void initState() {
    super.initState();
    _balanceController = TextEditingController();

    _balanceController.addListener(() {
      setState(() {});
    });

    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1000),
    );

    _logoScaleAnimation = Tween<double>(begin: 0.8, end: 1).animate(
      CurvedAnimation(parent: _animationController, curve: Curves.easeOutBack),
    );
    _contentSlideAnimation = Tween<Offset>(
      begin: const Offset(0, 30),
      end: Offset.zero,
    ).animate(
      CurvedAnimation(parent: _animationController, curve: Curves.easeOutQuart),
    );
    _fadeAnimation = Tween<double>(begin: 0, end: 1).animate(
      CurvedAnimation(parent: _animationController, curve: Curves.easeInOut),
    );

    _animationController.forward();
    _loadBalance();
    _loadContacts();
  }

  Future<void> _loadContacts() async {
    bool permissionGranted = await FlutterContacts.requestPermission();
    if (!permissionGranted) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('يرجى السماح بالوصول إلى جهات الاتصال')),
        );
      }
      return;
    }
    final contacts = await FlutterContacts.getContacts(withProperties: true);
    if (mounted) {
      setState(() {
        _contacts = contacts;
      });
    }
  }

  Future<String?> _askUserForPhoneNumber() async {
    String? phoneNumber;
    await showDialog(
      context: context,
      builder: (context) {
        final controller = TextEditingController();
        String localSearchQuery = '';

        return StatefulBuilder(
          builder: (context, setStateDialog) {
            List<Contact> filteredContacts =
                _contacts.where((contact) {
                  final name = contact.displayName.toLowerCase();
                  final query = localSearchQuery.toLowerCase();

                  final matchesName = name.contains(query);
                  final matchesNumber = contact.phones.any(
                    (phone) => phone.number.toLowerCase().contains(query),
                  );

                  return matchesName || matchesNumber;
                }).toList();

            return AlertDialog(
              title: const Text('أدخل رقم جهة الاتصال أو اختر من القائمة'),
              content: SizedBox(
                width: double.maxFinite,
                height: 350,
                child: Column(
                  children: [
                    TextField(
                      controller: controller,
                      keyboardType: TextInputType.text,
                      decoration: const InputDecoration(
                        hintText: 'قم بكتابة اسم الشخص او رقم هاتفة',
                        suffixIcon: Icon(Icons.search),
                      ),
                      onChanged: (val) {
                        setStateDialog(() {
                          localSearchQuery = val;
                        });
                      },
                    ),
                    const SizedBox(height: 10),
                    Expanded(
                      child:
                          filteredContacts.isEmpty
                              ? const Center(child: Text('لا توجد جهات اتصال'))
                              : ListView.builder(
                                shrinkWrap: true,
                                itemCount: filteredContacts.length,
                                itemBuilder: (_, index) {
                                  final contact = filteredContacts[index];
                                  final phones = contact.phones;
                                  return ListTile(
                                    title: Text(contact.displayName),
                                    subtitle:
                                        phones.isNotEmpty
                                            ? Text(phones.first.number)
                                            : null,
                                    onTap: () {
                                      if (phones.isNotEmpty) {
                                        controller.text = phones.first.number;
                                      }
                                    },
                                  );
                                },
                              ),
                    ),
                  ],
                ),
              ),
              actions: [
                TextButton(
                  onPressed: () => Navigator.of(context).pop(),
                  child: const Text('إلغاء'),
                ),
                TextButton(
                  onPressed: () {
                    phoneNumber = controller.text.trim();
                    Navigator.of(context).pop();
                  },
                  child: const Text('موافق'),
                ),
              ],
            );
          },
        );
      },
    );
    return phoneNumber;
  }

  Future<bool> _requestPermissions() async {
    PermissionStatus smsStatus = await Permission.sms.status;
    if (!smsStatus.isGranted) {
      smsStatus = await Permission.sms.request();
    }
    return smsStatus.isGranted;
  }

  Future<String?> _getLatestSmsFromNumber(String senderNumber) async {
    bool? permissionsGranted = await telephony.requestSmsPermissions;
    if (permissionsGranted != true) return null;

    String formatNumber(String number) {
      return number.replaceAll(RegExp(r'[^0-9]'), ''); // أبقي الأرقام فقط
    }

    String formattedSenderNumber = formatNumber(senderNumber);

    final List<SmsMessage> messages = await telephony.getInboxSms(
      columns: [SmsColumn.ADDRESS, SmsColumn.BODY],
      filter: SmsFilter.where(
        SmsColumn.ADDRESS,
      ).like('%$formattedSenderNumber%'),
      sortOrder: [OrderBy(SmsColumn.DATE_SENT, sort: Sort.DESC)],
    );

    if (messages.isNotEmpty) {
      return messages.first.body;
    }
    return null;
  }

  double? extractBalanceFromMessage(String message) {
    RegExp regex = RegExp(r'(\d{1,3}(,\d{3})*(\.\d+)?|\d+(\.\d+)?)');

    final matches = regex.allMatches(message);
    double? maxValue;

    for (var match in matches) {
      final valueStr = match.group(0)?.replaceAll(',', '');
      if (valueStr != null) {
        final val = double.tryParse(valueStr);
        if (val != null) {
          if (maxValue == null || val > maxValue) {
            maxValue = val;
          }
        }
      }
    }
    return maxValue;
  }

  String _formatDoubleWithThousandsSeparator(double value) {
    String fixed = value.toStringAsFixed(2);

    final parts = fixed.split('.');
    String integerPart = parts[0];
    String decimalPart = parts[1];

    final buffer = StringBuffer();
    int len = integerPart.length;
    for (int i = 0; i < len; i++) {
      buffer.write(integerPart[i]);
      int posFromRight = len - i - 1;
      if (posFromRight % 3 == 0 && i != len - 1) {
        buffer.write(',');
      }
    }

    if (decimalPart == '00') {
      return buffer.toString();
    }

    return '${buffer.toString()}.$decimalPart';
  }

  Future<void> _fetchBalanceFromSms() async {
    bool havePermissions = await _requestPermissions();
    if (!havePermissions) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('يرجى السماح بصلاحيات قراءة الرسائل')),
      );
      return;
    }

    final senderNumber = await _askUserForPhoneNumber();
    if (senderNumber == null || senderNumber.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('لم يتم إدخال رقم جهة اتصال')),
      );
      return;
    }

    String? smsText = await _getLatestSmsFromNumber(senderNumber);
    if (smsText == null) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('لم يتم العثور على رسائل من جهة الاتصال')),
      );
      return;
    }

    double? balance = extractBalanceFromMessage(smsText);
    if (balance != null) {
      String formattedBalance = _formatDoubleWithThousandsSeparator(balance);

      setState(() {
        _balanceController.text = formattedBalance.split('.').first;
      });

      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('تم جلب الرصيد من رسالة جهة الاتصال')),
      );
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('لم يتم العثور على رصيد صالح في الرسالة')),
      );
    }
  }

  Future<void> _loadBalance() async {
    final prefs = await SharedPreferences.getInstance();
    final savedData = prefs.getString('balance_data');

    if (savedData != null) {
      final Map<String, dynamic> jsonData = jsonDecode(savedData);

      setState(() {
        _previousBalance = jsonData['previous_balance'] ?? 0;
        _currentBalance = jsonData['current_balance'] ?? 0;
        _totalBalance = jsonData['total_balance'] ?? _currentBalance;
        _hasSavedBalance = true;

        _balanceController.text = _formatWithThousandsSeparator(
          _currentBalance,
        );
      });
    } else {
      setState(() {
        _hasSavedBalance = false;
      });
    }

    setState(() {
      _isLoading = false;
    });
  }

  String _formatWithThousandsSeparator(int value) {
    final s = value.toString();
    final buffer = StringBuffer();
    final len = s.length;
    for (int i = 0; i < len; i++) {
      buffer.write(s[i]);
      final posFromRight = len - i - 1;
      if (posFromRight % 3 == 0 && i != len - 1) buffer.write(',');
    }
    return buffer.toString();
  }

  Future<void> _saveBalances({
    required int previousBalance,
    required int currentBalance,
    required int totalBalance,
  }) async {
    final prefs = await SharedPreferences.getInstance();

    Map<String, dynamic> balanceData = {
      'previous_balance': previousBalance,
      'current_balance': currentBalance,
      'total_balance': totalBalance,
    };

    await prefs.setString('balance_data', jsonEncode(balanceData));
  }

  void _onContinue() async {
    final currentInput = _balanceController.text.replaceAll(',', '').trim();

    final currentBalanceInput = int.tryParse(currentInput);

    if (currentBalanceInput == null || currentBalanceInput < 0) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: const Text(
            'يرجى إدخال مبلغ رصيد صالح (صفر أو أكثر)',
            style: TextStyle(fontFamily: tajawalFont),
          ),
          behavior: SnackBarBehavior.floating,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(10),
          ),
          backgroundColor: Colors.red,
        ),
      );
      return;
    }

    int totalBalance = currentBalanceInput;

    setState(() {
      _previousBalance = _currentBalance;
      _currentBalance = currentBalanceInput;
      _totalBalance = totalBalance;

      _balanceController.clear();

      _hasSavedBalance = true;
    });

    await _saveBalances(
      previousBalance: _previousBalance,
      currentBalance: _currentBalance,
      totalBalance: _totalBalance,
    );

    Navigator.pushReplacementNamed(context, '/home');
  }

  Widget _smallBalanceInfo(String label, int value) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Text(
          label,
          style: TextStyle(
            fontFamily: tajawalFont,
            color: Colors.grey[600],
            fontSize: 12,
          ),
        ),
        const SizedBox(height: 2),
        Text(
          _formatWithThousandsSeparator(value),
          style: TextStyle(
            fontFamily: tajawalFont,
            fontWeight: FontWeight.bold,
            color: primaryColor,
            fontSize: 14,
          ),
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: backgroundColor,
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
          child:
              _isLoading
                  ? Center(
                    child: CircularProgressIndicator(
                      color: progressColor,
                      strokeWidth: 2,
                    ),
                  )
                  : Column(
                    children: [
                      Expanded(
                        child: SingleChildScrollView(
                          physics: const BouncingScrollPhysics(),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: [
                              const SizedBox(height: 40),
                              ScaleTransition(
                                scale: _logoScaleAnimation,
                                child: Container(
                                  width: 120,
                                  height: 120,
                                  decoration: BoxDecoration(
                                    color: const Color(
                                      0xFF69541D,
                                    ).withOpacity(0.05),
                                    shape: BoxShape.circle,
                                  ),
                                  child: Icon(
                                    Icons.currency_exchange_rounded,
                                    size: 60,
                                    color: const Color(
                                      0xFFf4721e,
                                    ).withOpacity(1),
                                  ),
                                ),
                              ),
                              const SizedBox(height: 40),
                              SlideTransition(
                                position: _contentSlideAnimation,
                                child: FadeTransition(
                                  opacity: _fadeAnimation,
                                  child: Column(
                                    children: [
                                      Text(
                                        ' مرحبًا بك في تطبيق حوّلها فايـبـرافـون',
                                        style: TextStyle(
                                          fontSize: 18,
                                          color: primaryColor,
                                          fontWeight: FontWeight.bold,
                                          height: 1.4,
                                          fontFamily: tajawalFont,
                                        ),
                                        textAlign: TextAlign.center,
                                      ),
                                      const SizedBox(height: 16),
                                      Text(
                                        'أدخل رصيدك الحالي لبدء إدارة وتحويل رصيدك بسهولة',
                                        style: TextStyle(
                                          color: Colors.grey[700],
                                          height: 1.6,
                                          fontFamily: tajawalFont,
                                          fontSize: 14,
                                        ),
                                        textAlign: TextAlign.center,
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                              const SizedBox(height: 40),
                              SlideTransition(
                                position: _contentSlideAnimation,
                                child: FadeTransition(
                                  opacity: _fadeAnimation,
                                  child: TextField(
                                    controller: _balanceController,
                                    keyboardType: TextInputType.number,
                                    inputFormatters: [
                                      ThousandsSeparatorInputFormatter(),
                                    ],
                                    textAlign: TextAlign.right,
                                    style: TextStyle(
                                      fontWeight: FontWeight.w600,
                                      fontFamily: tajawalFont,
                                      color: primaryColor,
                                    ),
                                    decoration: InputDecoration(
                                      filled: true,
                                      fillColor: Colors.white,
                                      hintText: 'مثال: 1,000',
                                      hintStyle: TextStyle(
                                        fontSize: 13,
                                        fontFamily: tajawalFont,
                                        color: Colors.grey[500],
                                      ),
                                      labelText: 'الرصيد الحالي',
                                      labelStyle: TextStyle(
                                        fontFamily: tajawalFont,
                                        color: primaryColor,
                                      ),
                                      prefixIcon: Icon(
                                        Icons.account_balance_wallet,
                                        color: accentColor,
                                      ),
                                      suffixIcon:
                                          _balanceController.text.trim().isEmpty
                                              ? IconButton(
                                                onPressed: _fetchBalanceFromSms,
                                                icon: Icon(
                                                  Icons.message,
                                                  color: accentColor,
                                                ),
                                                tooltip:
                                                    'جلب الرصيد من الرسائل',
                                              )
                                              : null,
                                      border: OutlineInputBorder(
                                        borderRadius: BorderRadius.circular(12),
                                        borderSide: BorderSide(
                                          color: Colors.grey[300]!,
                                        ),
                                      ),
                                      enabledBorder: OutlineInputBorder(
                                        borderRadius: BorderRadius.circular(12),
                                        borderSide: BorderSide(
                                          color: Colors.grey[300]!,
                                        ),
                                      ),
                                      focusedBorder: OutlineInputBorder(
                                        borderRadius: BorderRadius.circular(12),
                                        borderSide: BorderSide(
                                          color: primaryColor,
                                          width: 2,
                                        ),
                                      ),
                                      floatingLabelBehavior:
                                          FloatingLabelBehavior.always,
                                      contentPadding:
                                          const EdgeInsets.symmetric(
                                            horizontal: 20,
                                            vertical: 16,
                                          ),
                                    ),
                                  ),
                                ),
                              ),
                              if (_hasSavedBalance)
                                Padding(
                                  padding: const EdgeInsets.only(top: 24),
                                  child: Row(
                                    mainAxisAlignment:
                                        MainAxisAlignment.spaceEvenly,
                                    children: [
                                      _smallBalanceInfo(
                                        'الرصيد السابق',
                                        _previousBalance,
                                      ),
                                      _smallBalanceInfo(
                                        'الرصيد الحالي',
                                        _currentBalance,
                                      ),
                                      _smallBalanceInfo(
                                        'الرصيد المضاف',
                                        _totalBalance - _previousBalance,
                                      ),
                                    ],
                                  ),
                                ),
                            ],
                          ),
                        ),
                      ),
                      const SizedBox(height: 24),
                      SlideTransition(
                        position: _contentSlideAnimation,
                        child: FadeTransition(
                          opacity: _fadeAnimation,
                          child: SizedBox(
                            width: double.infinity,
                            child: ElevatedButton(
                              onPressed: _onContinue,
                              style: ElevatedButton.styleFrom(
                                backgroundColor: accentColor,
                                foregroundColor: Colors.white,
                                padding: const EdgeInsets.symmetric(
                                  vertical: 16,
                                ),
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(12),
                                ),
                                elevation: 0,
                                shadowColor: Colors.transparent,
                              ),
                              child: Text(
                                'ابدأ الآن',
                                style: TextStyle(
                                  fontWeight: FontWeight.bold,
                                  color: Colors.white,
                                  fontFamily: tajawalFont,
                                  fontSize: 16,
                                ),
                              ),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
        ),
      ),
    );
  }
}