import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/bluetooth/bt_poller.dart'; import '../../../core/models/units.dart'; import '../../../core/providers/bt_provider.dart'; import '../../../core/providers/settings_provider.dart'; import '../../../core/providers/theme_provider.dart'; import '../../theme/app_colors.dart'; import '../bt_picker/bt_picker_screen.dart'; import '../debug/raw_frame_debug_screen.dart'; class SettingsScreen extends ConsumerWidget { const SettingsScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final settings = ref.watch(settingsProvider); final themeVariant = ref.watch(themeProvider); final bt = ref.watch(btProvider); final colors = AppColors.of(context); final units = ref.watch(unitPrefsProvider); final unitsN = ref.read(unitPrefsProvider.notifier); return Scaffold( appBar: AppBar(title: const Text('Settings')), body: ListView( children: [ // ── Connection ─────────────────────────────────────────── _SectionHeader('CONNECTION'), ListTile( leading: Icon(Icons.bluetooth, color: colors.accent), title: const Text('Bluetooth Device'), subtitle: Text( bt.isConnected ? 'Connected: ${bt.deviceName}' : 'Not connected', style: TextStyle(color: bt.isConnected ? Colors.green : Colors.grey), ), trailing: bt.isConnected ? TextButton( onPressed: () async { await ref.read(btProvider.notifier).disconnect(); }, child: const Text('Disconnect', style: TextStyle(color: Colors.red)), ) : const Icon(Icons.arrow_forward_ios, size: 14, color: Colors.grey), onTap: bt.isConnected ? null : () => Navigator.push( context, MaterialPageRoute(builder: (_) => const BtPickerScreen()), ), ), const Divider(height: 1), // ── ECU Protocol ───────────────────────────────────────── _SectionHeader('ECU PROTOCOL'), RadioListTile( title: const Text('S300'), subtitle: const Text('Honda S300 ECU', style: TextStyle(color: Colors.grey, fontSize: 12)), value: EcuType.s300, groupValue: settings.ecuType, activeColor: colors.accent, onChanged: (v) { if (v != null) ref.read(settingsProvider.notifier).setEcuType(v); }, ), RadioListTile( title: const Text('KPro'), subtitle: const Text('Hondata KPro ECU', style: TextStyle(color: Colors.grey, fontSize: 12)), value: EcuType.kpro, groupValue: settings.ecuType, activeColor: colors.accent, onChanged: (v) { if (v != null) ref.read(settingsProvider.notifier).setEcuType(v); }, ), const Divider(height: 1), // ── Polling Interval ───────────────────────────────────── _SectionHeader('POLLING INTERVAL'), ...pollingIntervalOptionsMs.map((ms) => RadioListTile( title: Text('${ms}ms (~${(1000 / ms).round()} Hz)'), value: ms, groupValue: settings.pollingInterval.inMilliseconds, activeColor: colors.accent, onChanged: (v) { if (v != null) { ref .read(settingsProvider.notifier) .setPollingInterval(Duration(milliseconds: v)); } }, )), const Divider(height: 1), // ── Units ──────────────────────────────────────────────── _SectionHeader('UNITS'), _UnitRow( label: 'Speed', value: units.speed, options: const {SpeedUnit.kmh: 'km/h', SpeedUnit.mph: 'mph'}, onChanged: unitsN.setSpeed, ), _UnitRow( label: 'Temperature', value: units.temp, options: const { TempUnit.celsius: '°C', TempUnit.fahrenheit: '°F', }, onChanged: unitsN.setTemp, ), _UnitRow( label: 'Pressure', value: units.pressure, options: const { PressureUnit.kpa: 'kPa', PressureUnit.bar: 'bar', PressureUnit.psi: 'psi', }, onChanged: unitsN.setPressure, ), const Divider(height: 1), // ── Theme ──────────────────────────────────────────────── _SectionHeader('THEME'), ...AppThemeVariant.values.map((v) { final label = switch (v) { AppThemeVariant.redDark => 'Red — Dark', AppThemeVariant.redLight => 'Red — Light', AppThemeVariant.greenDark => 'Green — Dark', AppThemeVariant.greenLight => 'Green — Light', }; return RadioListTile( title: Text(label), value: v, groupValue: themeVariant, activeColor: AppColors.forTheme(v).accent, onChanged: (val) { if (val != null) ref.read(themeProvider.notifier).set(val); }, ); }), const Divider(height: 1), // ── Diagnostics ────────────────────────────────────────── _SectionHeader('DIAGNOSTICS'), ListTile( leading: Icon(Icons.bug_report_outlined, color: colors.accent), title: const Text('ECU frame debug & app log'), trailing: const Icon(Icons.arrow_forward_ios, size: 14), onTap: () => Navigator.push( context, MaterialPageRoute(builder: (_) => const RawFrameDebugScreen()), ), ), const Divider(height: 1), // ── App info ───────────────────────────────────────────── _SectionHeader('ABOUT'), const ListTile( title: Text('HV BT Dashboard'), subtitle: Text('v1.4.0 — Phase 4', style: TextStyle(color: Colors.grey, fontSize: 12)), leading: Icon(Icons.info_outline, color: Colors.grey), ), const SizedBox(height: 24), ], ), ); } } class _SectionHeader extends StatelessWidget { final String title; const _SectionHeader(this.title); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.fromLTRB(16, 20, 16, 6), child: Text( title, style: const TextStyle( color: Colors.grey, fontSize: 11, letterSpacing: 1.5, fontWeight: FontWeight.w600, ), ), ); } } /// One unit choice (e.g. Speed: km/h | mph). class _UnitRow extends StatelessWidget { final String label; final T value; final Map options; final void Function(T) onChanged; const _UnitRow({ required this.label, required this.value, required this.options, required this.onChanged, }); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), child: Row( children: [ Expanded(child: Text(label)), SegmentedButton( showSelectedIcon: false, segments: [ for (final e in options.entries) ButtonSegment(value: e.key, label: Text(e.value)), ], selected: {value}, onSelectionChanged: (s) => onChanged(s.first), ), ], ), ); } }