import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../theme/app_theme.dart'; /// Manages dynamic branding and app theme settings fetched from the Odoo backend. /// Automatically handles offline caching via SharedPreferences. class ThemeManager extends ChangeNotifier { static final ThemeManager instance = ThemeManager._internal(); ThemeManager._internal(); Color _primaryColor = AppTheme.primary; Color _secondaryColor = AppTheme.secondary; Color _tertiaryColor = AppTheme.tertiary; Color _backgroundColor = AppTheme.surface; Color _backgroundGradientColor = const Color(0xFFF3EAD3); String _brandLogo = ''; Color get primaryColor => _primaryColor; Color get secondaryColor => _secondaryColor; Color get tertiaryColor => _tertiaryColor; Color get backgroundColor => _backgroundColor; Color get backgroundGradientColor => _backgroundGradientColor; String get brandLogo => _brandLogo; ThemeData get themeData => AppTheme.getTheme( primaryColor: _primaryColor, secondaryColor: _secondaryColor, tertiaryColor: _tertiaryColor, backgroundColor: _backgroundColor, ); /// Initialize cached settings on app launch Future initialize() async { final prefs = await SharedPreferences.getInstance(); final primHex = prefs.getString('theme_primary_color'); final secHex = prefs.getString('theme_secondary_color'); final terHex = prefs.getString('theme_tertiary_color'); final bgHex = prefs.getString('theme_background_color'); final bgGradHex = prefs.getString('theme_background_gradient_color'); _brandLogo = prefs.getString('theme_brand_logo') ?? ''; if (primHex != null) { _primaryColor = _parseHexColor(primHex) ?? AppTheme.primary; } if (secHex != null) { _secondaryColor = _parseHexColor(secHex) ?? AppTheme.secondary; } if (terHex != null) { _tertiaryColor = _parseHexColor(terHex) ?? AppTheme.tertiary; } if (bgHex != null) { _backgroundColor = _parseHexColor(bgHex) ?? AppTheme.surface; } if (bgGradHex != null) { _backgroundGradientColor = _parseHexColor(bgGradHex) ?? const Color(0xFFF3EAD3); } } /// Update theme options and persist them to SharedPreferences Future updateConfig({ required String primaryHex, required String secondaryHex, required String tertiaryHex, required String backgroundHex, required String backgroundGradientHex, required String brandLogoB64, }) async { final prefs = await SharedPreferences.getInstance(); await prefs.setString('theme_primary_color', primaryHex); await prefs.setString('theme_secondary_color', secondaryHex); await prefs.setString('theme_tertiary_color', tertiaryHex); await prefs.setString('theme_background_color', backgroundHex); await prefs.setString('theme_background_gradient_color', backgroundGradientHex); await prefs.setString('theme_brand_logo', brandLogoB64); _primaryColor = _parseHexColor(primaryHex) ?? AppTheme.primary; _secondaryColor = _parseHexColor(secondaryHex) ?? AppTheme.secondary; _tertiaryColor = _parseHexColor(tertiaryHex) ?? AppTheme.tertiary; _backgroundColor = _parseHexColor(backgroundHex) ?? AppTheme.surface; _backgroundGradientColor = _parseHexColor(backgroundGradientHex) ?? const Color(0xFFF3EAD3); _brandLogo = brandLogoB64; notifyListeners(); } Color? _parseHexColor(String hexString) { try { final buffer = StringBuffer(); if (hexString.length == 6 || hexString.length == 7) buffer.write('ff'); buffer.write(hexString.replaceFirst('#', '')); return Color(int.parse(buffer.toString(), radix: 16)); } catch (_) { return null; } } }