import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_web/pages/routiens/bloc/routine_bloc.dart'; import 'package:syncrow_web/pages/routiens/models/device_functions.dart'; import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart'; import 'package:syncrow_web/pages/routiens/models/gang_switches/one_gang_switch/one_gang_switch.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; class OneGangSwitchHelper { static Future showSwitchFunctionsDialog( BuildContext context, List> functions) async { List> switchFunctions = functions .where( (f) => f is OneGangSwitchFunction || f is OneGangCountdownFunction) .toList(); Map selectedValues = {}; List selectedFunctions = []; String? selectedCondition = "<"; List selectedConditions = [true, false, false]; await showDialog( context: context, builder: (BuildContext context) { return StatefulBuilder( builder: (context, setState) { return AlertDialog( contentPadding: EdgeInsets.zero, content: Container( width: 600, height: 450, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(20), ), padding: const EdgeInsets.only(top: 20), child: Column( mainAxisSize: MainAxisSize.min, children: [ Text( '1 Gang Light Switch Condition', style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: ColorsManager.primaryColorWithOpacity, fontWeight: FontWeight.bold, ), ), Padding( padding: const EdgeInsets.symmetric( vertical: 15, horizontal: 50), child: Container( height: 1, width: double.infinity, color: ColorsManager.greyColor, ), ), Expanded( child: Row( children: [ // Left side: Function list Expanded( child: ListView.separated( itemCount: switchFunctions.length, separatorBuilder: (_, __) => const Divider( color: ColorsManager.dividerColor, ), itemBuilder: (context, index) { final function = switchFunctions[index]; final isSelected = selectedValues.containsKey(function.code); return ListTile( tileColor: isSelected ? Colors.grey.shade100 : null, leading: SvgPicture.asset( function.icon, width: 24, height: 24, ), title: Text( function.operationName, style: context.textTheme.bodyMedium, ), trailing: isSelected ? Icon( Icons.check_circle, color: ColorsManager .primaryColorWithOpacity, size: 20, ) : const Icon( Icons.arrow_forward_ios, size: 16, color: ColorsManager.textGray, ), onTap: () { if (isSelected) { selectedValues.remove(function.code); selectedFunctions.removeWhere( (f) => f.function == function.code); } (context as Element).markNeedsBuild(); }, ); }, ), ), // Right side: Value selector Expanded( child: Builder( builder: (context) { final selectedFn = switchFunctions.firstWhere( (f) => selectedValues.containsKey(f.code), orElse: () => switchFunctions.first, ) as BaseSwitchFunction; if (selectedFn is OneGangCountdownFunction) { return _buildCountDownSelector( context, setState, selectedValues[selectedFn.code] ?? 0, selectedCondition, selectedConditions, (value) { selectedValues[selectedFn.code] = value; final functionData = DeviceFunctionData( entityId: selectedFn.deviceId, function: selectedFn.code, operationName: selectedFn.operationName, value: value, condition: selectedCondition, valueDescription: '${value} sec', ); final existingIndex = selectedFunctions.indexWhere((f) => f.function == selectedFn.code); if (existingIndex != -1) { selectedFunctions[existingIndex] = functionData; } else { selectedFunctions.add(functionData); } (context as Element).markNeedsBuild(); }, (condition) { setState(() { selectedCondition = condition; }); }, ); } final values = selectedFn.getOperationalValues(); return ListView.builder( itemCount: values.length, itemBuilder: (context, index) { final value = values[index]; return ListTile( leading: SvgPicture.asset( value.icon, width: 24, height: 24, ), title: Text( value.description, style: context.textTheme.bodyMedium, ), trailing: Radio( value: value.value, groupValue: selectedValues[selectedFn.code], onChanged: (newValue) { selectedValues[selectedFn.code] = newValue; final functionData = DeviceFunctionData( entityId: selectedFn.deviceId, function: selectedFn.code, operationName: selectedFn.operationName, value: newValue, valueDescription: value.description, ); final existingIndex = selectedFunctions.indexWhere( (f) => f.function == selectedFn.code); if (existingIndex != -1) { selectedFunctions[existingIndex] = functionData; } else { selectedFunctions.add(functionData); } (context as Element).markNeedsBuild(); }, ), ); }, ); }, ), ), ], ), ), Container( height: 1, width: double.infinity, color: ColorsManager.greyColor, ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ TextButton( onPressed: () => Navigator.pop(context), child: Text( 'Cancel', style: Theme.of(context) .textTheme .bodyMedium! .copyWith(color: ColorsManager.greyColor), ), ), TextButton( onPressed: selectedFunctions.isNotEmpty ? () { for (final function in selectedFunctions) { context .read() .add(AddFunction(function)); } Navigator.pop(context, true); } : null, child: Text( 'Confirm', style: Theme.of(context) .textTheme .bodyMedium! .copyWith( color: ColorsManager.primaryColorWithOpacity, ), ), ), ], ), ], ), ), ); }, ); }, ); } /// Build countdown selector for switch functions dialog static Widget _buildCountDownSelector( BuildContext context, StateSetter setState, dynamic selectedValue, String? selectedCondition, List selectedConditions, Function(dynamic) onValueSelected, Function(String?) onConditionSelected, ) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ _buildConditionToggle( context, setState, selectedConditions, onConditionSelected, ), const SizedBox(height: 20), Text( '${selectedValue.toString()} sec', style: Theme.of(context).textTheme.headlineMedium, ), const SizedBox(height: 20), Slider( value: selectedValue.toDouble(), min: 0, max: 300, // 5 minutes in seconds divisions: 300, onChanged: (value) { setState(() { onValueSelected(value.toInt()); }); }, ), ], ); } /// Build condition toggle for AC functions dialog static Widget _buildConditionToggle( BuildContext context, StateSetter setState, List selectedConditions, Function(String?) onConditionSelected, ) { return ToggleButtons( onPressed: (int index) { setState(() { for (int i = 0; i < selectedConditions.length; i++) { selectedConditions[i] = i == index; } onConditionSelected(index == 0 ? "<" : index == 1 ? "==" : ">"); }); }, borderRadius: const BorderRadius.all(Radius.circular(8)), selectedBorderColor: ColorsManager.primaryColorWithOpacity, selectedColor: Colors.white, fillColor: ColorsManager.primaryColorWithOpacity, color: ColorsManager.primaryColorWithOpacity, constraints: const BoxConstraints( minHeight: 40.0, minWidth: 40.0, ), isSelected: selectedConditions, children: const [Text("<"), Text("="), Text(">")], ); } }