import 'package:flutter/services.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:marco/helpers/widgets/my_snackbar.dart'; import 'package:marco/helpers/services/app_logger.dart'; class LauncherUtils { /// Launches the phone dialer with the provided phone number static Future launchPhone(String phoneNumber) async { logSafe('Attempting to launch phone: $phoneNumber', ); final Uri url = Uri(scheme: 'tel', path: phoneNumber); await _tryLaunch(url, 'Could not launch phone'); } /// Launches the email app with the provided email address static Future launchEmail(String email) async { logSafe('Attempting to launch email: $email', ); final Uri url = Uri(scheme: 'mailto', path: email); await _tryLaunch(url, 'Could not launch email'); } /// Launches WhatsApp with the provided phone number static Future launchWhatsApp(String phoneNumber) async { logSafe('Attempting to launch WhatsApp with: $phoneNumber', ); String normalized = phoneNumber.replaceAll(RegExp(r'\D'), ''); if (!normalized.startsWith('91')) { normalized = '91$normalized'; } logSafe('Normalized WhatsApp number: $normalized', ); if (normalized.length < 12) { logSafe('Invalid WhatsApp number: $normalized', ); showAppSnackbar( title: 'Error', message: 'Invalid phone number for WhatsApp', type: SnackbarType.error, ); return; } final Uri url = Uri.parse('https://wa.me/$normalized'); await _tryLaunch(url, 'Could not open WhatsApp'); } /// Copies text to clipboard with feedback static Future copyToClipboard(String text, {required String typeLabel}) async { try { logSafe('Copying "$typeLabel" to clipboard'); HapticFeedback.lightImpact(); await Clipboard.setData(ClipboardData(text: text)); showAppSnackbar( title: 'Copied', message: '$typeLabel copied to clipboard', type: SnackbarType.success, ); } catch (e, st) { logSafe( 'Failed to copy $typeLabel to clipboard: $e', stackTrace: st, level: LogLevel.error, ); showAppSnackbar( title: 'Error', message: 'Failed to copy $typeLabel', type: SnackbarType.error, ); } } /// Internal function to launch a URL and show error if failed static Future _tryLaunch(Uri url, String errorMsg) async { try { logSafe('Trying to launch URL: ${url.toString()}'); final bool launched = await launchUrl( url, mode: LaunchMode.externalApplication, ); if (launched) { logSafe('URL launched successfully: ${url.toString()}'); } else { logSafe( 'launchUrl returned false: ${url.toString()}', level: LogLevel.warning, ); showAppSnackbar( title: 'Error', message: errorMsg, type: SnackbarType.error, ); } } catch (e, st) { logSafe( 'Exception during launch of ${url.toString()}: $e', stackTrace: st, level: LogLevel.error, ); showAppSnackbar( title: 'Error', message: '$errorMsg: $e', type: SnackbarType.error, ); } } }