// lib/screens/settings/submission_preferences_settings.dart import 'package:flutter/material.dart'; import 'package:environment_monitoring_app/services/user_preferences_service.dart'; class _ModuleSettings { bool isApiEnabled; bool isFtpEnabled; List> apiConfigs; List> ftpConfigs; _ModuleSettings({ this.isApiEnabled = true, this.isFtpEnabled = true, required this.apiConfigs, required this.ftpConfigs, }); } class SubmissionPreferencesSettingsScreen extends StatefulWidget { const SubmissionPreferencesSettingsScreen({super.key}); @override State createState() => _SubmissionPreferencesSettingsScreenState(); } class _SubmissionPreferencesSettingsScreenState extends State { final UserPreferencesService _preferencesService = UserPreferencesService(); bool _isLoadingSettings = true; bool _isSaving = false; final Map _moduleSettings = {}; final List> _configurableModules = [ {'key': 'marine_tarball', 'name': 'Marine Tarball'}, {'key': 'marine_in_situ', 'name': 'Marine In-Situ'}, {'key': 'marine_investigative', 'name': 'Marine Investigative'}, {'key': 'river_in_situ', 'name': 'River In-Situ'}, {'key': 'river_triennial', 'name': 'River Triennial'}, {'key': 'river_investigative', 'name': 'River Investigative'}, {'key': 'air_installation', 'name': 'Air Installation'}, {'key': 'air_collection', 'name': 'Air Collection'}, ]; @override void initState() { super.initState(); _loadAllModuleSettings(); } Future _loadAllModuleSettings() async { setState(() => _isLoadingSettings = true); for (var module in _configurableModules) { final moduleKey = module['key']!; final prefs = await _preferencesService.getModulePreference(moduleKey); final apiConfigsWithPrefs = await _preferencesService.getAllApiConfigsWithModulePreferences(moduleKey); final ftpConfigsWithPrefs = await _preferencesService.getAllFtpConfigsWithModulePreferences(moduleKey); _moduleSettings[moduleKey] = _ModuleSettings( isApiEnabled: prefs?['is_api_enabled'] ?? true, // Fallback to true if null isFtpEnabled: prefs?['is_ftp_enabled'] ?? true, // Fallback to true if null apiConfigs: apiConfigsWithPrefs, ftpConfigs: ftpConfigsWithPrefs, ); } if (mounted) { setState(() => _isLoadingSettings = false); } } Future _saveAllModuleSettings() async { setState(() => _isSaving = true); try { for (var module in _configurableModules) { final moduleKey = module['key']!; final settings = _moduleSettings[moduleKey]!; await _preferencesService.saveModulePreference( moduleName: moduleKey, isApiEnabled: settings.isApiEnabled, isFtpEnabled: settings.isFtpEnabled, ); await _preferencesService.saveApiLinksForModule( moduleKey, settings.apiConfigs); await _preferencesService.saveFtpLinksForModule( moduleKey, settings.ftpConfigs); } _showSnackBar('Submission preferences saved successfully.', isError: false); } catch (e) { _showSnackBar('Failed to save settings: $e', isError: true); } finally { if (mounted) { setState(() => _isSaving = false); } } } void _showSnackBar(String message, {bool isError = false}) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(message), backgroundColor: isError ? Theme.of(context).colorScheme.error : Colors.green, ), ); } } Widget _buildSectionHeader(BuildContext context, String title) { return Padding( padding: const EdgeInsets.fromLTRB(8.0, 24.0, 8.0, 16.0), child: Text( title, style: Theme.of(context) .textTheme .headlineSmall ?.copyWith(fontWeight: FontWeight.bold), ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Submission Preferences"), actions: [ Padding( padding: const EdgeInsets.only(right: 8.0), child: _isSaving ? const Center( child: SizedBox( width: 24, height: 24, child: CircularProgressIndicator(color: Colors.white))) : IconButton( icon: const Icon(Icons.save), onPressed: _isLoadingSettings ? null : _saveAllModuleSettings, tooltip: 'Save Submission Preferences', ), ) ], ), body: _isLoadingSettings ? const Center( child: Padding( padding: EdgeInsets.all(16.0), child: CircularProgressIndicator())) : ListView( padding: const EdgeInsets.all(16.0), children: [ _buildSectionHeader(context, "Module Settings"), Card( margin: EdgeInsets.zero, child: ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: _configurableModules.length, itemBuilder: (context, index) { final module = _configurableModules[index]; final settings = _moduleSettings[module['key']]; if (settings == null) return const SizedBox.shrink(); return _buildModulePreferenceTile( module['name']!, module['key']!, settings); }, ), ), ], ), ); } Widget _buildModulePreferenceTile( String title, String moduleKey, _ModuleSettings settings) { return ExpansionTile( title: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)), initiallyExpanded: false, // Start collapsed children: [ SwitchListTile( title: const Text('Enable API Submission'), value: settings.isApiEnabled, onChanged: (value) => setState(() => settings.isApiEnabled = value), ), if (settings.isApiEnabled) _buildDestinationList( 'API Destinations', settings.apiConfigs, 'api_config_id'), const Divider(), SwitchListTile( title: const Text('Enable FTP Submission'), value: settings.isFtpEnabled, onChanged: (value) => setState(() => settings.isFtpEnabled = value), ), if (settings.isFtpEnabled) _buildDestinationList( 'FTP Destinations', settings.ftpConfigs, 'ftp_config_id'), ], ); } Widget _buildDestinationList( String title, List> configs, String idKey) { if (configs.isEmpty) { return const ListTile( dense: true, title: Center(child: Text('No destinations configured. Sync to fetch.')), ); } return Padding( padding: const EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only(left: 16.0, bottom: 8.0), child: Text(title, style: Theme.of(context).textTheme.titleMedium), ), ...configs.map((config) { bool isFtp = config.containsKey('ftp_module'); String subtitleText; if (isFtp) { subtitleText = 'Module: ${config['ftp_module'] ?? 'N/A'} | Host: ${config['ftp_host'] ?? 'N/A'}'; } else { subtitleText = config['api_url'] ?? 'No URL'; } return CheckboxListTile( title: Text(config['config_name'] ?? 'Unnamed'), subtitle: Text(subtitleText, style: const TextStyle(fontSize: 12)), value: config['is_enabled'] ?? false, onChanged: (bool? value) { setState(() { config['is_enabled'] = value ?? false; }); }, dense: true, ); }).toList(), ], ), ); } }