// ignore_for_file: use_build_context_synchronously import 'dart:async'; import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:intl/intl.dart'; import '../product/services/api_services.dart'; import '../product/services/language_services.dart'; import '../product/shared/model/ward_model.dart'; import '../product/shared/shared_snack_bar.dart'; import '../product/utils/response_status_utils.dart'; import '../product/shared/model/district_model.dart'; import '../product/shared/model/province_model.dart'; import '../feature/devices/device_model.dart'; import '../product/base/bloc/base_bloc.dart'; class DeviceUpdateBloc extends BlocBase { APIServices apiServices = APIServices(); final deviceInfo = StreamController.broadcast(); StreamSink get sinkDeviceInfo => deviceInfo.sink; Stream get streamDeviceInfo => deviceInfo.stream; // DeviceUpdateScreen final isChanged = StreamController.broadcast(); StreamSink get sinkIsChanged => isChanged.sink; Stream get streamIsChanged => isChanged.stream; final provinceData = StreamController>.broadcast(); StreamSink> get sinkProvinceData => provinceData.sink; Stream> get streamProvinceData => provinceData.stream; final listProvinces = StreamController>>.broadcast(); StreamSink>> get sinkListProvinces => listProvinces.sink; Stream>> get streamListProvinces => listProvinces.stream; final districtData = StreamController>.broadcast(); StreamSink> get sinkDistrictData => districtData.sink; Stream> get streamDistrictData => districtData.stream; final listDistricts = StreamController>>.broadcast(); StreamSink>> get sinkListDistricts => listDistricts.sink; Stream>> get streamListDistricts => listDistricts.stream; final wardData = StreamController>.broadcast(); StreamSink> get sinkWardData => wardData.sink; Stream> get streamWardData => wardData.stream; final listWards = StreamController>>.broadcast(); StreamSink>> get sinkListWards => listWards.sink; Stream>> get streamListWards => listWards.stream; // Show Maps in DeviceUpdateScreen final markers = StreamController>.broadcast(); StreamSink> get sinkMarkers => markers.sink; Stream> get streamMarkers => markers.stream; final searchLocation = StreamController.broadcast(); StreamSink get sinkSearchLocation => searchLocation.sink; Stream get streamSearchLocation => searchLocation.stream; @override void dispose() { // deviceInfo.done; } Future getAllProvinces(BuildContext context) async { List> provincesData = []; provincesData.clear(); sinkListProvinces.add(provincesData); await apiServices.execute(context, () async { List provinces = await apiServices.getAllProvinces(); for (var province in provinces) { provincesData.add( DropdownMenuItem(value: province, child: Text(province.fullName!))); } sinkListProvinces.add(provincesData); }); } Future getAllDistricts(BuildContext context, String provinceID) async { List> districtsData = []; districtsData.clear(); sinkListDistricts.add(districtsData); await apiServices.execute(context, () async { final districts = await apiServices.getAllDistricts(provinceID); for (var district in districts) { districtsData.add( DropdownMenuItem(value: district, child: Text(district.fullName!))); } sinkListDistricts.add(districtsData); }); } Future getAllWards(BuildContext context, String districtID) async { List> wardsData = []; wardsData.clear(); sinkListWards.add(wardsData); await apiServices.execute(context, () async { final wards = await apiServices.getAllWards(districtID); for (var ward in wards) { wardsData .add(DropdownMenuItem(value: ward, child: Text(ward.fullName!))); } sinkListWards.add(wardsData); }); } Future getDeviceInformation( BuildContext context, String thingID, TextEditingController deviceNameController, TextEditingController latitudeController, TextEditingController longitudeController) async { await apiServices.execute(context, () async { Device device = await apiServices.getDeviceInformation(thingID); sinkDeviceInfo.add(device); deviceNameController.text = device.name ?? ""; latitudeController.text = device.settings!.latitude ?? ""; longitudeController.text = device.settings!.longitude ?? ""; if (device.areaPath != null && device.areaPath!.isNotEmpty) { List areaPath = device.areaPath!.split('_'); // Kiểm tra độ dài của areaPath if (areaPath.length >= 3) { String provinceCode = areaPath[0]; String districtCode = areaPath[1]; String wardCode = areaPath[2]; // Kiểm tra các mã có hợp lệ không (không rỗng) if (provinceCode.isNotEmpty && districtCode.isNotEmpty && wardCode.isNotEmpty) { try { // Lấy danh sách districts và wards await getAllDistricts(context, provinceCode); await getAllWards(context, districtCode); // Xử lý Province try { Province province = await apiServices.getProvinceByID(provinceCode); Map provinceData = { "name": province.fullName ?? "Unknown Province", "code": province.code ?? provinceCode }; sinkProvinceData.add(provinceData); } catch (e) { // Thêm dữ liệu mặc định khi lỗi Map provinceData = { "name": "Error Loading Province", "code": provinceCode }; sinkProvinceData.add(provinceData); if (!context.mounted) return; showErrorTopSnackBarCustom(context, e.toString()); } // Xử lý District try { District district = await apiServices.getDistrictByID(districtCode); Map districData = { "name": district.fullName ?? "Unknown District", "code": district.code ?? districtCode, }; sinkDistrictData.add(districData); } catch (e) { log("Lỗi khi lấy thông tin district ($districtCode): $e"); Map districData = { "name": "Error Loading District", "code": districtCode, }; sinkDistrictData.add(districData); } // Xử lý Ward try { Ward ward = await apiServices.getWardByID(wardCode); Map wardMap = { "name": ward.fullName ?? "Unknown Ward", "code": ward.code ?? wardCode, }; sinkWardData.add(wardMap); } catch (e) { log("Lỗi khi lấy thông tin ward ($wardCode): $e"); Map wardMap = { "name": "Error Loading Ward", "code": wardCode, }; sinkWardData.add(wardMap); } } catch (e) { log("Lỗi khi gọi getAllDistricts hoặc getAllWards: $e"); } } else { await getAllProvinces(context); log("Một hoặc nhiều mã địa phương trống: Province: $provinceCode, District: $districtCode, Ward: $wardCode"); } } else { showNoIconTopSnackBar( context, "AreaPath không đủ thông tin: ${device.areaPath}", Colors.orangeAccent, Colors.white); } } }); // try { // Device device = await apiServices.getDeviceInformation(thingID); // sinkDeviceInfo.add(device); // deviceNameController.text = device.name ?? ""; // latitudeController.text = device.settings!.latitude ?? ""; // longitudeController.text = device.settings!.longitude ?? ""; // if (device.areaPath != null && device.areaPath!.isNotEmpty) { // List areaPath = device.areaPath!.split('_'); // // Kiểm tra độ dài của areaPath // if (areaPath.length >= 3) { // String provinceCode = areaPath[0]; // String districtCode = areaPath[1]; // String wardCode = areaPath[2]; // // Kiểm tra các mã có hợp lệ không (không rỗng) // if (provinceCode.isNotEmpty && // districtCode.isNotEmpty && // wardCode.isNotEmpty) { // try { // // Lấy danh sách districts và wards // await getAllDistricts(context, provinceCode); // await getAllWards(context, districtCode); // // Xử lý Province // try { // Province province = // await apiServices.getProvinceByID(provinceCode); // Map provinceData = { // "name": province.fullName ?? "Unknown Province", // "code": province.code ?? provinceCode // }; // sinkProvinceData.add(provinceData); // } catch (e) { // // Thêm dữ liệu mặc định khi lỗi // Map provinceData = { // "name": "Error Loading Province", // "code": provinceCode // }; // sinkProvinceData.add(provinceData); // if (!context.mounted) return; // showErrorTopSnackBarCustom(context, e.toString()); // } // // Xử lý District // try { // District district = // await apiServices.getDistrictByID(districtCode); // Map districData = { // "name": district.fullName ?? "Unknown District", // "code": district.code ?? districtCode, // }; // sinkDistrictData.add(districData); // } catch (e) { // log("Lỗi khi lấy thông tin district ($districtCode): $e"); // Map districData = { // "name": "Error Loading District", // "code": districtCode, // }; // sinkDistrictData.add(districData); // } // // Xử lý Ward // try { // Ward ward = await apiServices.getWardByID(wardCode); // Map wardMap = { // "name": ward.fullName ?? "Unknown Ward", // "code": ward.code ?? wardCode, // }; // sinkWardData.add(wardMap); // } catch (e) { // print("Lỗi khi lấy thông tin ward ($wardCode): $e"); // Map wardMap = { // "name": "Error Loading Ward", // "code": wardCode, // }; // sinkWardData.add(wardMap); // } // } catch (e) { // print("Lỗi khi gọi getAllDistricts hoặc getAllWards: $e"); // } // } else { // await getAllProvinces(context); // print( // "Một hoặc nhiều mã địa phương trống: Province: $provinceCode, District: $districtCode, Ward: $wardCode"); // } // } else { // showNoIconTopSnackBar( // context, // "AreaPath không đủ thông tin: ${device.areaPath}", // Colors.orangeAccent, // Colors.white); // } // } // } catch (e) { // showNoIconTopSnackBar(context, "Lỗi trong getDeviceInfomation: $e", // Colors.orangeAccent, Colors.white); // } } Future getProvinceByName(BuildContext context, String name) async { return await apiServices.execute(context, () async { List provinces = await apiServices.getProvincesByName(name); if (provinces.isNotEmpty) { return provinces[0]; } else { return Province(name: "null"); } }); } Future getDistrictByName( BuildContext context, String name, String provinceCode) async { return apiServices.execute(context, () async { final districts = await apiServices.getDistrictsByName(name); return districts.firstWhere( (district) => district.provinceCode == provinceCode, orElse: () => District(name: "null"), ); }); } Future getWardByName( BuildContext context, String name, String districtCode) async { return apiServices.execute(context, () async { final wards = await apiServices.getWardsByName(name); return wards.firstWhere( (ward) => ward.districtCode == districtCode, orElse: () => Ward(name: "null"), ); }); } Future updateDevice( BuildContext context, String thingID, String name, String latitude, String longitude, String provinceCode, String districtCode, String wardCode, ) async { await apiServices.execute(context, () async { DateTime dateTime = DateTime.now(); String formattedDateTime = DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime); Map body = { "name": name, "area_province": provinceCode, "area_district": districtCode, "area_ward": wardCode, "latitude": latitude, "longitude": longitude, "note": "User updated device infomation at $formattedDateTime", }; int statusCode = await apiServices.updateOwnerDevice(thingID, body); showSnackBarResponseByStatusCodeNoIcon( context, statusCode, appLocalization(context).notification_update_device_success, appLocalization(context).notification_update_device_failed, ); }); // try { // DateTime dateTime = DateTime.now(); // String formattedDateTime = // DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime); // Map body = { // "name": name, // "area_province": provinceCode, // "area_district": districtCode, // "area_ward": wardCode, // "latitude": latitude, // "longitude": longitude, // "note": "User updated device infomation at $formattedDateTime", // }; // int statusCode = await apiServices.updateOwnerDevice(thingID, body); // showSnackBarResponseByStatusCodeNoIcon( // context, // statusCode, // appLocalization(context).notification_update_device_success, // appLocalization(context).notification_update_device_failed, // ); // } catch (e) { // if (!context.mounted) return; // showErrorTopSnackBarCustom(context, e.toString()); // } } }