import 'package:hive_flutter/hive_flutter.dart'; import 'package:lunchpick/domain/entities/visit_record.dart'; import 'package:lunchpick/domain/repositories/visit_repository.dart'; class VisitRepositoryImpl implements VisitRepository { static const String _boxName = 'visit_records'; Future> get _box async => await Hive.openBox(_boxName); @override Future> getAllVisitRecords() async { final box = await _box; final records = box.values.toList(); records.sort((a, b) => b.visitDate.compareTo(a.visitDate)); return records; } @override Future> getVisitRecordsByRestaurantId(String restaurantId) async { final records = await getAllVisitRecords(); return records.where((r) => r.restaurantId == restaurantId).toList(); } @override Future> getVisitRecordsByDate(DateTime date) async { final records = await getAllVisitRecords(); return records.where((record) { return record.visitDate.year == date.year && record.visitDate.month == date.month && record.visitDate.day == date.day; }).toList(); } @override Future> getVisitRecordsByDateRange({ required DateTime startDate, required DateTime endDate, }) async { final records = await getAllVisitRecords(); return records.where((record) { return record.visitDate.isAfter(startDate.subtract(const Duration(days: 1))) && record.visitDate.isBefore(endDate.add(const Duration(days: 1))); }).toList(); } @override Future addVisitRecord(VisitRecord visitRecord) async { final box = await _box; await box.put(visitRecord.id, visitRecord); } @override Future updateVisitRecord(VisitRecord visitRecord) async { final box = await _box; await box.put(visitRecord.id, visitRecord); } @override Future deleteVisitRecord(String id) async { final box = await _box; await box.delete(id); } @override Future confirmVisit(String visitRecordId) async { final box = await _box; final record = box.get(visitRecordId); if (record != null) { final updatedRecord = VisitRecord( id: record.id, restaurantId: record.restaurantId, visitDate: record.visitDate, isConfirmed: true, createdAt: record.createdAt, ); await updateVisitRecord(updatedRecord); } } @override Stream> watchVisitRecords() async* { final box = await _box; try { yield await getAllVisitRecords(); } catch (_) { yield []; } yield* box.watch().asyncMap((_) async => await getAllVisitRecords()); } @override Future getLastVisitDate(String restaurantId) async { final records = await getVisitRecordsByRestaurantId(restaurantId); if (records.isEmpty) return null; // 이미 visitDate 기준으로 정렬되어 있으므로 첫 번째가 가장 최근 return records.first.visitDate; } @override Future> getMonthlyVisitStats(int year, int month) async { final startDate = DateTime(year, month, 1); final endDate = DateTime(year, month + 1, 0); // 해당 월의 마지막 날 final records = await getVisitRecordsByDateRange( startDate: startDate, endDate: endDate, ); final stats = {}; for (final record in records) { final dayKey = record.visitDate.day.toString(); stats[dayKey] = (stats[dayKey] ?? 0) + 1; } return stats; } @override Future> getCategoryVisitStats() async { // 이 메서드는 RestaurantRepository와 연동이 필요하므로 // 실제 구현은 UseCase나 Provider 레벨에서 처리 // 여기서는 빈 Map 반환 return {}; } }