import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart'; import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart'; import 'package:syncrow_web/pages/routines/models/ac/ac_function.dart'; import 'package:syncrow_web/pages/routines/models/ac/ac_operational_value.dart'; import 'package:syncrow_web/pages/routines/models/device_functions.dart'; import 'package:syncrow_web/pages/routines/widgets/custom_routines_textbox.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart'; import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/helpers/routine_tap_function_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; class ACHelper { static Future?> showACFunctionsDialog({ required BuildContext context, required List functions, required AllDevicesModel? device, required List? deviceSelectedFunctions, required String uniqueCustomId, required bool? removeComparetors, required String dialogType, }) async { List acFunctions = functions.whereType().where((function) { if (dialogType == 'THEN') { return function.type == 'THEN' || function.type == 'BOTH'; } return function.type == 'IF' || function.type == 'BOTH'; }).toList(); // List acFunctions = functions.whereType().toList(); return showDialog?>( context: context, builder: (BuildContext context) { return BlocProvider( create: (_) => FunctionBloc() ..add(InitializeFunctions(deviceSelectedFunctions ?? [])), child: AlertDialog( contentPadding: EdgeInsets.zero, content: BlocBuilder( builder: (context, state) { final selectedFunction = state.selectedFunction; final selectedOperationName = state.selectedOperationName; final selectedFunctionData = state.addedFunctions .firstWhere((f) => f.functionCode == selectedFunction, orElse: () => DeviceFunctionData( entityId: '', functionCode: selectedFunction ?? '', operationName: '', value: null, )); return Container( width: selectedFunction != null ? 600 : 360, height: 450, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(20), ), padding: const EdgeInsets.only(top: 20), child: Column( mainAxisSize: MainAxisSize.min, children: [ DialogHeader(dialogType == 'THEN' ? 'AC Functions' : 'AC Conditions'), Expanded( child: Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Function list SizedBox( width: selectedFunction != null ? 320 : 360, child: _buildFunctionsList( context: context, acFunctions: acFunctions, onFunctionSelected: (functionCode, operationName) { RoutineTapFunctionHelper.onTapFunction( context, functionCode: functionCode, functionOperationName: operationName, functionValueDescription: selectedFunctionData .valueDescription, deviceUuid: device?.uuid, codesToAddIntoFunctionsWithDefaultValue: [ 'temp_set', 'temp_current', ], defaultValue: 0); }), ), // Value selector if (selectedFunction != null) Expanded( child: _buildValueSelector( context: context, selectedFunction: selectedFunction, selectedFunctionData: selectedFunctionData, acFunctions: acFunctions, device: device, operationName: selectedOperationName ?? '', removeComparators: removeComparetors, ), ), ], ), ), DialogFooter( onCancel: () { Navigator.pop(context); }, onConfirm: state.addedFunctions.isNotEmpty ? () { /// add the functions to the routine bloc context.read().add( AddFunctionToRoutine( state.addedFunctions, uniqueCustomId, ), ); // Return the device data to be added to the container Navigator.pop(context, { 'deviceId': functions.first.deviceId, }); } : null, isConfirmEnabled: selectedFunction != null, ), ], ), ); }, ), ), ); }, ).then((value) { return value; }); } /// Build functions list for AC functions dialog static Widget _buildFunctionsList({ required BuildContext context, required List acFunctions, required Function(String, String) onFunctionSelected, }) { return ListView.separated( shrinkWrap: false, physics: const AlwaysScrollableScrollPhysics(), itemCount: acFunctions.length, separatorBuilder: (context, index) => const Padding( padding: EdgeInsets.symmetric(horizontal: 40.0), child: Divider( color: ColorsManager.dividerColor, ), ), itemBuilder: (context, index) { final function = acFunctions[index]; return ListTile( leading: SvgPicture.asset( function.icon, width: 24, height: 24, placeholderBuilder: (BuildContext context) => Container( width: 24, height: 24, color: Colors.transparent, ), ), title: Text( function.operationName, style: context.textTheme.bodyMedium, ), trailing: const Icon( Icons.arrow_forward_ios, size: 16, color: ColorsManager.textGray, ), onTap: () => onFunctionSelected( function.code, function.operationName, ), ); }, ); } static Widget _buildValueSelector({ required BuildContext context, required String selectedFunction, required DeviceFunctionData? selectedFunctionData, required List acFunctions, AllDevicesModel? device, required String operationName, bool? removeComparators, }) { final selectedFn = acFunctions.firstWhere((f) => f.code == selectedFunction); if (selectedFunction == 'temp_set' || selectedFunction == 'temp_current') { final displayValue = (selectedFunctionData?.value ?? selectedFn.min!) / 10; final minValue = selectedFn.min! / 10; final maxValue = selectedFn.max! / 10; return CustomRoutinesTextbox( withSpecialChar: true, dividendOfRange: maxValue, currentCondition: selectedFunctionData?.condition, dialogType: selectedFn.type, sliderRange: (minValue, maxValue), displayedValue: displayValue.toString(), initialValue: displayValue, unit: selectedFn.unit!, onConditionChanged: (condition) => context.read().add( AddFunction( functionData: DeviceFunctionData( entityId: device?.uuid ?? '', functionCode: selectedFunction, operationName: selectedFn.operationName, condition: condition, value: (displayValue * 10).round(), step: selectedFn.step, unit: selectedFn.unit, max: selectedFn.max, min: selectedFn.min, ), ), ), onTextChanged: (value) { final numericValue = double.tryParse(value.toString()) ?? minValue; context.read().add( AddFunction( functionData: DeviceFunctionData( entityId: device?.uuid ?? '', functionCode: selectedFunction, operationName: selectedFn.operationName, value: (numericValue * 10).round(), condition: selectedFunctionData?.condition, step: selectedFn.step, unit: selectedFn.unit, max: selectedFn.max, min: selectedFn.min, ), ), ); }, stepIncreaseAmount: selectedFn.step! / 10, ); } // Rest of your existing code for other value selectors final values = selectedFn.getOperationalValues(); return _buildOperationalValuesList( context: context, values: values, selectedValue: selectedFunctionData?.value, device: device, operationName: operationName, selectCode: selectedFunction, selectedFunctionData: selectedFunctionData, ); } // /// Build temperature selector for AC functions dialog // static Widget _buildTemperatureSelector({ // required BuildContext context, // required dynamic initialValue, // required String? currentCondition, // required String selectCode, // AllDevicesModel? device, // required String operationName, // DeviceFunctionData? selectedFunctionData, // bool? removeComparators, // }) { // return Column( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // if (removeComparators != true) // _buildConditionToggle( // context, // currentCondition, // selectCode, // device, // operationName, // selectedFunctionData, // ), // const SizedBox(height: 20), // _buildTemperatureDisplay( // context, // initialValue, // device, // operationName, // selectedFunctionData, // selectCode, // ), // const SizedBox(height: 20), // _buildTemperatureSlider( // context, // initialValue, // device, // operationName, // selectedFunctionData, // selectCode, // ), // ], // ); // } /// Build condition toggle for AC functions dialog // static Widget _buildConditionToggle( // BuildContext context, // String? currentCondition, // String selectCode, // AllDevicesModel? device, // String operationName, // DeviceFunctionData? selectedFunctionData, // // Function(String) onConditionChanged, // ) { // final conditions = ["<", "==", ">"]; // return ToggleButtons( // onPressed: (int index) { // context.read().add( // AddFunction( // functionData: DeviceFunctionData( // entityId: device?.uuid ?? '', // functionCode: selectCode, // operationName: operationName, // condition: conditions[index], // value: selectedFunctionData?.value ?? selectCode == 'temp_set' // ? 200 // : -100, // valueDescription: selectedFunctionData?.valueDescription, // ), // ), // ); // }, // 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: // conditions.map((c) => c == (currentCondition ?? "==")).toList(), // children: conditions.map((c) => Text(c)).toList(), // ); // } // /// Build temperature display for AC functions dialog // static Widget _buildTemperatureDisplay( // BuildContext context, // dynamic initialValue, // AllDevicesModel? device, // String operationName, // DeviceFunctionData? selectedFunctionData, // String selectCode, // ) { // final initialVal = selectCode == 'temp_set' ? 200 : -100; // return Container( // padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), // decoration: BoxDecoration( // color: ColorsManager.primaryColorWithOpacity.withOpacity(0.1), // borderRadius: BorderRadius.circular(10), // ), // child: Text( // '${(initialValue ?? initialVal) / 10}°C', // style: context.textTheme.headlineMedium!.copyWith( // color: ColorsManager.primaryColorWithOpacity, // ), // ), // ); // } // static Widget _buildTemperatureSlider( // BuildContext context, // dynamic initialValue, // AllDevicesModel? device, // String operationName, // DeviceFunctionData? selectedFunctionData, // String selectCode, // ) { // return Slider( // value: initialValue is int ? initialValue.toDouble() : 200.0, // min: selectCode == 'temp_current' ? -100 : 200, // max: selectCode == 'temp_current' ? 900 : 300, // divisions: 10, // label: '${((initialValue ?? 160) / 10).toInt()}°C', // onChanged: (value) { // context.read().add( // AddFunction( // functionData: DeviceFunctionData( // entityId: device?.uuid ?? '', // functionCode: selectCode, // operationName: operationName, // value: value, // condition: selectedFunctionData?.condition, // valueDescription: selectedFunctionData?.valueDescription, // ), // ), // ); // }, // ); // } static Widget _buildOperationalValuesList({ required BuildContext context, required List values, required dynamic selectedValue, AllDevicesModel? device, required String operationName, required String selectCode, DeviceFunctionData? selectedFunctionData, // required Function(dynamic) onValueChanged, }) { return ListView.builder( shrinkWrap: false, physics: const AlwaysScrollableScrollPhysics(), itemCount: values.length, itemBuilder: (context, index) { final value = values[index]; final isSelected = selectedValue == value.value; return ListTile( leading: SvgPicture.asset( value.icon, width: 24, height: 24, placeholderBuilder: (BuildContext context) => Container( width: 24, height: 24, color: Colors.transparent, ), ), title: Text( value.description, style: context.textTheme.bodyMedium, ), trailing: Icon( isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked, size: 24, color: isSelected ? ColorsManager.primaryColorWithOpacity : ColorsManager.textGray, ), onTap: () { if (!isSelected) { context.read().add( AddFunction( functionData: DeviceFunctionData( entityId: device?.uuid ?? '', functionCode: selectCode, operationName: operationName, value: value.value, condition: selectedFunctionData?.condition, valueDescription: selectedFunctionData?.valueDescription, ), ), ); } }, ); }, ); } }