import 'package:core/utils/app_logger.dart'; import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_manager.dart'; import 'package:tmail_ui_user/main/localizations/language_code_constants.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; typedef OnServerLanguageApplied = Function(Locale locale); class LocalizationService extends Translations { static const defaultLocale = Locale(LanguageCodeConstants.english, 'US'); static const fallbackLocale = Locale(LanguageCodeConstants.english, 'US'); static final supportedLanguageCodes = [ LanguageCodeConstants.french, LanguageCodeConstants.english, LanguageCodeConstants.vietnamese, LanguageCodeConstants.russian, LanguageCodeConstants.arabic, LanguageCodeConstants.italian, LanguageCodeConstants.german ]; static const List supportedLocales = [ Locale(LanguageCodeConstants.french, 'FR'), Locale(LanguageCodeConstants.english, 'US'), Locale(LanguageCodeConstants.vietnamese, 'VN'), Locale(LanguageCodeConstants.russian, 'RU'), Locale(LanguageCodeConstants.arabic, 'TN'), Locale(LanguageCodeConstants.italian, 'IT'), Locale(LanguageCodeConstants.german, 'DE') ]; static void changeLocale(Locale newLocale) { log('LocalizationService::changeLocale(): New locale is $newLocale'); Get.updateLocale(newLocale); } static Locale getInitialLocale() { try { final cachedLocale = _getCachedLocale(); if (cachedLocale != null) return cachedLocale; final deviceLocale = _getDeviceLocale(); if (_isSupportedLocale(deviceLocale)) return deviceLocale; return defaultLocale; } catch (e) { logWarning('LocalizationService::getInitialLocale:Exception is $e'); return defaultLocale; } } static Locale? _getCachedLocale() { try { final languageCacheManager = getBinding(); return languageCacheManager?.getStoredLanguage(); } catch (e) { logWarning('LocalizationService::getCachedLocale: Exception: $e'); return null; } } static Locale _getDeviceLocale() => WidgetsBinding.instance.platformDispatcher.locale; static String supportedLocalesToLanguageTags() { final listLanguageTags = supportedLocales.map((locale) => locale.toLanguageTag()).join(', '); log('LocalizationService::supportedLocalesToLanguageTags:listLanguageTags: $listLanguageTags'); return listLanguageTags; } static void initializeAppLanguage({ String? serverLanguage, OnServerLanguageApplied? onServerLanguageApplied, }) { log('LocalizationService::initializeAppLanguage:Server language: $serverLanguage'); try { // From server if (serverLanguage != null && _useServerLocale( languageCode: serverLanguage, onServerLanguageApplied: onServerLanguageApplied, )) { return; } if (_useCachedLocale()) return; if (_useDeviceLocale()) return; _useDefaultLocale(); } catch (e) { logWarning('LocalizationService::initializeAppLanguage: Exception: $e'); _useDefaultLocale(); } } static void _useDefaultLocale() { final currentLocale = Get.locale; if (currentLocale == null || !_isSupportedLocale(currentLocale)) { changeLocale(defaultLocale); } } static bool _useDeviceLocale() { final deviceLocale = _getDeviceLocale(); log('LocalizationService::_useDeviceLocale: Device locale is $deviceLocale'); if (_isSupportedLocale(deviceLocale)) { changeLocale(deviceLocale); return true; } return false; } static bool _useCachedLocale() { final cachedLocale = _getCachedLocale(); log('LocalizationService::_useCachedLocale: Cached locale is $cachedLocale'); if (cachedLocale != null && _isSupportedLocale(cachedLocale)) { changeLocale(cachedLocale); return true; } return false; } static bool _useServerLocale({ required String languageCode, required OnServerLanguageApplied? onServerLanguageApplied, }) { final serverLocale = _findSupportedLocale(languageCode); log('LocalizationService::_useServerLocale: Server locale is $serverLocale'); if (serverLocale != null && _isSupportedLocale(serverLocale)) { changeLocale(serverLocale); onServerLanguageApplied?.call(serverLocale); return true; } return false; } static bool _isSupportedLocale(Locale locale) { return supportedLocales .any((supported) => supported.languageCode == locale.languageCode); } static Locale? _findSupportedLocale(String languageCode) { return supportedLocales.firstWhereOrNull( (supported) => supported.languageCode == languageCode); } @override Map> get keys => {}; }