import 'package:flutter/material.dart'; import '../models/models.dart'; import '../risk_engine/mortality_tables.dart'; import '../storage/local_storage.dart'; import '../theme.dart'; import 'behavioral_screen.dart'; class BaselineScreen extends StatefulWidget { const BaselineScreen({super.key}); @override State createState() => _BaselineScreenState(); } class _BaselineScreenState extends State { int _age = 35; Sex _sex = Sex.male; String _country = 'United States'; double _heightCm = 170; double _weightKg = 70; final Set _diagnoses = {}; late List _countries; @override void initState() { super.initState(); _countries = getSupportedCountries(); _loadExistingProfile(); } Future _loadExistingProfile() async { final profile = await LocalStorage.getProfile(); if (profile != null) { setState(() { _age = profile.age; _sex = profile.sex; _country = profile.country; _heightCm = profile.heightCm; _weightKg = profile.weightKg; _diagnoses.clear(); _diagnoses.addAll(profile.diagnoses); }); } } double get _bmi => _weightKg / ((_heightCm / 100) * (_heightCm / 100)); String get _bmiCategory { if (_bmi < 18.5) return 'Underweight'; if (_bmi < 25) return 'Normal'; if (_bmi < 30) return 'Overweight'; if (_bmi < 35) return 'Obese I'; if (_bmi < 40) return 'Obese II'; return 'Obese III'; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Baseline'), leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () => Navigator.pop(context), ), ), body: SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Demographics', style: Theme.of(context).textTheme.headlineSmall, ), const SizedBox(height: 8), Text( 'This information establishes your baseline life expectancy.', style: Theme.of(context).textTheme.bodyMedium, ), const SizedBox(height: 24), // Age _buildSectionLabel('Age'), const SizedBox(height: 8), _buildAgeSelector(), const SizedBox(height: 24), // Sex _buildSectionLabel('Biological Sex'), const SizedBox(height: 8), _buildSexSelector(), const SizedBox(height: 24), // Country _buildSectionLabel('Country'), const SizedBox(height: 8), _buildCountryDropdown(), const SizedBox(height: 24), // Height _buildSectionLabel('Height'), const SizedBox(height: 8), _buildHeightSlider(), const SizedBox(height: 24), // Weight _buildSectionLabel('Weight'), const SizedBox(height: 8), _buildWeightSlider(), const SizedBox(height: 16), // BMI display _buildBmiDisplay(), const SizedBox(height: 32), // Existing conditions Text( 'Existing Conditions', style: Theme.of(context).textTheme.headlineSmall, ), const SizedBox(height: 8), Text( 'Select any diagnosed conditions. These affect baseline calculations but are not modifiable factors.', style: Theme.of(context).textTheme.bodyMedium, ), const SizedBox(height: 16), _buildDiagnosisCheckboxes(), const SizedBox(height: 32), // Continue button SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _continue, child: const Text('Continue'), ), ), const SizedBox(height: 16), ], ), ), ); } Widget _buildSectionLabel(String label) { return Text( label, style: Theme.of(context).textTheme.labelLarge, ); } Widget _buildAgeSelector() { return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: AppColors.surfaceVariant, borderRadius: BorderRadius.circular(12), ), child: Row( children: [ IconButton( icon: const Icon(Icons.remove), onPressed: _age > 18 ? () => setState(() => _age--) : null, ), Expanded( child: Text( '$_age years', textAlign: TextAlign.center, style: Theme.of(context).textTheme.headlineMedium, ), ), IconButton( icon: const Icon(Icons.add), onPressed: _age < 100 ? () => setState(() => _age++) : null, ), ], ), ); } Widget _buildSexSelector() { return Row( children: [ Expanded( child: _buildToggleButton( 'Male', _sex == Sex.male, () => setState(() => _sex = Sex.male), ), ), const SizedBox(width: 12), Expanded( child: _buildToggleButton( 'Female', _sex == Sex.female, () => setState(() => _sex = Sex.female), ), ), ], ); } Widget _buildToggleButton(String label, bool selected, VoidCallback onTap) { return GestureDetector( onTap: onTap, child: Container( padding: const EdgeInsets.symmetric(vertical: 14), decoration: BoxDecoration( color: selected ? AppColors.primary : AppColors.surfaceVariant, borderRadius: BorderRadius.circular(12), ), child: Text( label, textAlign: TextAlign.center, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: selected ? Colors.white : AppColors.textSecondary, ), ), ), ); } Widget _buildCountryDropdown() { return Container( padding: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( color: AppColors.surfaceVariant, borderRadius: BorderRadius.circular(12), ), child: DropdownButtonHideUnderline( child: DropdownButton( value: _country, isExpanded: true, icon: const Icon(Icons.keyboard_arrow_down), items: _countries.map((country) { return DropdownMenuItem( value: country, child: Text(country), ); }).toList(), onChanged: (value) { if (value != null) setState(() => _country = value); }, ), ), ); } Widget _buildHeightSlider() { return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '${_heightCm.round()} cm', style: Theme.of(context).textTheme.headlineMedium, ), Text( _cmToFeetInches(_heightCm), style: Theme.of(context).textTheme.bodyMedium, ), ], ), Slider( value: _heightCm, min: 120, max: 220, divisions: 100, onChanged: (value) => setState(() => _heightCm = value), ), ], ); } Widget _buildWeightSlider() { return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '${_weightKg.round()} kg', style: Theme.of(context).textTheme.headlineMedium, ), Text( '${(_weightKg * 2.205).round()} lbs', style: Theme.of(context).textTheme.bodyMedium, ), ], ), Slider( value: _weightKg, min: 30, max: 200, divisions: 170, onChanged: (value) => setState(() => _weightKg = value), ), ], ); } Widget _buildBmiDisplay() { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColors.surfaceVariant, borderRadius: BorderRadius.circular(12), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'BMI', style: Theme.of(context).textTheme.bodyMedium, ), Text( _bmi.toStringAsFixed(1), style: Theme.of(context).textTheme.headlineMedium, ), ], ), Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), decoration: BoxDecoration( color: _getBmiColor(), borderRadius: BorderRadius.circular(8), ), child: Text( _bmiCategory, style: const TextStyle( color: Colors.white, fontWeight: FontWeight.w600, ), ), ), ], ), ); } Color _getBmiColor() { if (_bmi < 18.5 || _bmi >= 30) return AppColors.warning; if (_bmi >= 25) return AppColors.primary; return AppColors.success; } Widget _buildDiagnosisCheckboxes() { return Column( children: Diagnosis.values.map((diagnosis) { return CheckboxListTile( value: _diagnoses.contains(diagnosis), onChanged: (checked) { setState(() { if (checked == true) { _diagnoses.add(diagnosis); } else { _diagnoses.remove(diagnosis); } }); }, title: Text(_getDiagnosisLabel(diagnosis)), controlAffinity: ListTileControlAffinity.leading, contentPadding: EdgeInsets.zero, ); }).toList(), ); } String _getDiagnosisLabel(Diagnosis diagnosis) { switch (diagnosis) { case Diagnosis.cardiovascular: return 'Cardiovascular disease'; case Diagnosis.diabetes: return 'Diabetes'; case Diagnosis.cancer: return 'Cancer (active)'; case Diagnosis.copd: return 'COPD'; case Diagnosis.hypertension: return 'Hypertension'; } } String _cmToFeetInches(double cm) { final totalInches = cm / 2.54; final feet = (totalInches / 12).floor(); final inches = (totalInches % 12).round(); return "$feet'$inches\""; } void _continue() async { final profile = UserProfile( age: _age, sex: _sex, country: _country, heightCm: _heightCm, weightKg: _weightKg, diagnoses: _diagnoses, ); await LocalStorage.saveProfile(profile); if (mounted) { Navigator.of(context).push( MaterialPageRoute( builder: (_) => BehavioralScreen(profile: profile), ), ); } } }