// ignore_for_file: use_build_context_synchronously import 'dart:async'; import 'dart:convert'; 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/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() async { List> provincesData = []; provincesData.clear(); sinkListProvinces.add(provincesData); final body = await apiServices.getAllProvinces(); final data = jsonDecode(body); List items = data["items"]; final provinces = Province.fromJsonDynamicList(items); for (var province in provinces) { provincesData.add( DropdownMenuItem(value: province, child: Text(province.fullName!))); } sinkListProvinces.add(provincesData); } Future getAllDistricts(String provinceID) async { List> districtsData = []; districtsData.clear(); sinkListDistricts.add(districtsData); final body = await apiServices.getAllDistricts(provinceID); final data = jsonDecode(body); List items = data["items"]; final districts = District.fromJsonDynamicList(items); for (var district in districts) { districtsData.add( DropdownMenuItem(value: district, child: Text(district.fullName!))); } sinkListDistricts.add(districtsData); } Future getAllWards(String districtID) async { List> wardsData = []; wardsData.clear(); sinkListWards.add(wardsData); final body = await apiServices.getAllWards(districtID); final data = jsonDecode(body); List items = data["items"]; final wards = Ward.fromJsonDynamicList(items); for (var ward in wards) { wardsData.add(DropdownMenuItem(value: ward, child: Text(ward.fullName!))); } sinkListWards.add(wardsData); } Future getDeviceInfomation( String thingID, List> districtsData, List> wardsData, TextEditingController deviceNameController, TextEditingController latitudeController, TextEditingController longitudeController) async { String body = await apiServices.getDeviceInfomation(thingID); final data = jsonDecode(body); Device device = Device.fromJson(data); sinkDeviceInfo.add(device); deviceNameController.text = device.name ?? ""; latitudeController.text = device.settings!.latitude ?? ""; longitudeController.text = device.settings!.longitude ?? ""; if (device.areaPath != "") { List areaPath = device.areaPath!.split('_'); String provinceCode = areaPath[0]; String districtCode = areaPath[1]; String wardCode = areaPath[2]; getAllDistricts(provinceCode); getAllWards(districtCode); final provinceResponse = await apiServices.getProvinceByID(provinceCode); final provincesData = jsonDecode(provinceResponse); Province province = Province.fromJson(provincesData['data']); final districtResponse = await apiServices.getDistrictByID(districtCode); final districtData = jsonDecode(districtResponse); District district = District.fromJson(districtData['data']); final wardResponse = await apiServices.getWardByID(wardCode); final wardData = jsonDecode(wardResponse); Ward ward = Ward.fromJson(wardData['data']); Map provinceData = { "name": province.fullName!, "code": province.code! }; sinkProvinceData.add(provinceData); Map districData = { "name": district.fullName!, "code": district.code!, }; sinkDistrictData.add(districData); Map wardMap = { "name": ward.fullName!, "code": ward.code!, }; sinkWardData.add(wardMap); } } Future getProvinceByName(String name) async { final response = await apiServices.getProvincesByName(name); final data = jsonDecode(response); if (data != null && data.containsKey('items') && data['items'] != null && data['items'].isNotEmpty) { List items = data['items']; List provinces = Province.fromJsonDynamicList(items); if (provinces.isNotEmpty) { return provinces[0]; } } return Province(name: "null"); } Future getDistrictByName(String name, String provinceCode) async { final response = await apiServices.getDistrictsByName(name); if (response != "") { final data = jsonDecode(response); List items = data['items']; if (items.isNotEmpty) { List districts = District.fromJsonDynamicList(items); if (districts.isNotEmpty) { for (var district in districts) { if (district.provinceCode == provinceCode) { return district; } } } } } return District(name: "null"); } Future getWardByName(String name, String districtCode) async { final response = await apiServices.getWarsdByName(name); final data = jsonDecode(response); if (data != null && data['items'] != null) { List items = data['items']; if (items.isNotEmpty) { List wards = Ward.fromJsonDynamicList(items); if (wards.isNotEmpty) { for (var ward in wards) { if (ward.districtCode == districtCode) { return ward; } } } } } return Ward(name: "null"); } Future updateDevice( BuildContext context, String thingID, String name, String latitude, String longitude, String provinceCode, String districtCode, String wardCode, ) 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, ); } }