import 'dart:async'; import 'dart:convert'; import 'dart:math'; import 'package:lunchpick/domain/entities/restaurant.dart'; import 'package:lunchpick/domain/entities/share_device.dart'; /// 실제 Bluetooth 통신을 대체하는 간단한 모의(Mock) 서비스. class BluetoothService { final _incomingDataController = StreamController.broadcast(); final Map _listeningDevices = {}; final Random _random = Random(); Stream get onDataReceived => _incomingDataController.stream; /// 특정 코드로 수신 대기를 시작한다. Future startListening(String code) async { await Future.delayed(const Duration(milliseconds: 300)); stopListening(); final shareDevice = ShareDevice( code: code, deviceId: 'LP-${_random.nextInt(900000) + 100000}', discoveredAt: DateTime.now(), ); _listeningDevices[code] = shareDevice; } /// 더 이상 수신 대기하지 않는다. void stopListening() { if (_listeningDevices.isEmpty) return; final codes = List.from(_listeningDevices.keys); for (final code in codes) { _listeningDevices.remove(code); } } /// 현재 주변에서 수신 대기 중인 기기 목록을 반환한다. Future> scanNearbyDevices() async { await Future.delayed(const Duration(seconds: 1)); return _listeningDevices.values.toList(); } /// 대상 코드로 맛집 리스트를 전송한다. 실제 BT 대신 JSON 문자열을 브로드캐스트한다. Future sendRestaurantList( String targetCode, List restaurants, ) async { await Future.delayed(const Duration(seconds: 1)); if (!_listeningDevices.containsKey(targetCode)) { throw Exception('해당 코드를 찾을 수 없습니다.'); } final payload = jsonEncode( restaurants .map((restaurant) => _serializeRestaurant(restaurant)) .toList(), ); _incomingDataController.add(payload); } Map _serializeRestaurant(Restaurant restaurant) { return { 'id': restaurant.id, 'name': restaurant.name, 'category': restaurant.category, 'subCategory': restaurant.subCategory, 'description': restaurant.description, 'phoneNumber': restaurant.phoneNumber, 'roadAddress': restaurant.roadAddress, 'jibunAddress': restaurant.jibunAddress, 'latitude': restaurant.latitude, 'longitude': restaurant.longitude, 'lastVisitDate': restaurant.lastVisitDate?.toIso8601String(), 'source': restaurant.source.name, 'createdAt': restaurant.createdAt.toIso8601String(), 'updatedAt': restaurant.updatedAt.toIso8601String(), 'naverPlaceId': restaurant.naverPlaceId, 'naverUrl': restaurant.naverUrl, 'businessHours': restaurant.businessHours, 'lastVisited': restaurant.lastVisited?.toIso8601String(), 'visitCount': restaurant.visitCount, }; } void dispose() { _incomingDataController.close(); _listeningDevices.clear(); } }