import '../models/subscription_model.dart'; import '../providers/category_provider.dart'; import '../services/subscription_url_matcher.dart'; /// 구독 서비스를 카테고리별로 구분하는 도우미 클래스 class SubscriptionCategoryHelper { /// 구독 서비스 목록을 카테고리별로 그룹화하여 반환 /// /// [subscriptions] 구독 목록 /// [categoryProvider] 카테고리 제공자 /// /// 반환값: 카테고리 이름을 키로 하고 해당 카테고리에 속하는 구독 목록을 값으로 가지는 Map static Map> categorizeSubscriptions( List subscriptions, CategoryProvider categoryProvider, ) { final Map> categorizedSubscriptions = {}; // 카테고리 ID별로 구독 그룹화 for (final subscription in subscriptions) { if (subscription.categoryId != null) { // 카테고리 ID가 있는 경우, 해당 카테고리 이름으로 그룹화 final category = categoryProvider.getCategoryById(subscription.categoryId!); if (category != null) { final categoryName = category.name; if (!categorizedSubscriptions.containsKey(categoryName)) { categorizedSubscriptions[categoryName] = []; } categorizedSubscriptions[categoryName]!.add(subscription); continue; } } // 카테고리 ID가 없거나 카테고리를 찾을 수 없는 경우 서비스 이름 기반 분류 // 음악 if (_isInCategory( subscription.serviceName, SubscriptionUrlMatcher.musicServices)) { if (!categorizedSubscriptions.containsKey('음악')) { categorizedSubscriptions['음악'] = []; } categorizedSubscriptions['음악']!.add(subscription); } // OTT(동영상) else if (_isInCategory( subscription.serviceName, SubscriptionUrlMatcher.ottServices)) { if (!categorizedSubscriptions.containsKey('OTT(동영상)')) { categorizedSubscriptions['OTT(동영상)'] = []; } categorizedSubscriptions['OTT(동영상)']!.add(subscription); } // 저장/클라우드 else if (_isInCategory( subscription.serviceName, SubscriptionUrlMatcher.storageServices)) { if (!categorizedSubscriptions.containsKey('저장/클라우드')) { categorizedSubscriptions['저장/클라우드'] = []; } categorizedSubscriptions['저장/클라우드']!.add(subscription); } // 통신 · 인터넷 · TV else if (_isInCategory( subscription.serviceName, SubscriptionUrlMatcher.telecomServices)) { if (!categorizedSubscriptions.containsKey('통신 · 인터넷 · TV')) { categorizedSubscriptions['통신 · 인터넷 · TV'] = []; } categorizedSubscriptions['통신 · 인터넷 · TV']!.add(subscription); } // 생활/라이프스타일 else if (_isInCategory( subscription.serviceName, SubscriptionUrlMatcher.lifestyleServices)) { if (!categorizedSubscriptions.containsKey('생활/라이프스타일')) { categorizedSubscriptions['생활/라이프스타일'] = []; } categorizedSubscriptions['생활/라이프스타일']!.add(subscription); } // 쇼핑/이커머스 else if (_isInCategory( subscription.serviceName, SubscriptionUrlMatcher.shoppingServices)) { if (!categorizedSubscriptions.containsKey('쇼핑/이커머스')) { categorizedSubscriptions['쇼핑/이커머스'] = []; } categorizedSubscriptions['쇼핑/이커머스']!.add(subscription); } // 프로그래밍 else if (_isInCategory(subscription.serviceName, SubscriptionUrlMatcher.programmingServices)) { if (!categorizedSubscriptions.containsKey('프로그래밍')) { categorizedSubscriptions['프로그래밍'] = []; } categorizedSubscriptions['프로그래밍']!.add(subscription); } // 협업/오피스 else if (_isInCategory( subscription.serviceName, SubscriptionUrlMatcher.officeTools)) { if (!categorizedSubscriptions.containsKey('협업/오피스')) { categorizedSubscriptions['협업/오피스'] = []; } categorizedSubscriptions['협업/오피스']!.add(subscription); } // AI 서비스 else if (_isInCategory( subscription.serviceName, SubscriptionUrlMatcher.aiServices)) { if (!categorizedSubscriptions.containsKey('AI 서비스')) { categorizedSubscriptions['AI 서비스'] = []; } categorizedSubscriptions['AI 서비스']!.add(subscription); } // 기타 else if (_isInCategory( subscription.serviceName, SubscriptionUrlMatcher.otherServices)) { if (!categorizedSubscriptions.containsKey('기타')) { categorizedSubscriptions['기타'] = []; } categorizedSubscriptions['기타']!.add(subscription); } // 미분류된 서비스 else { if (!categorizedSubscriptions.containsKey('미분류')) { categorizedSubscriptions['미분류'] = []; } categorizedSubscriptions['미분류']!.add(subscription); } } // 빈 카테고리 제거 categorizedSubscriptions.removeWhere((key, value) => value.isEmpty); return categorizedSubscriptions; } /// 서비스 이름이 특정 카테고리에 속하는지 확인 static bool _isInCategory( String serviceName, Map categoryServices) { final lowerServiceName = serviceName.toLowerCase(); return categoryServices.keys.any((key) => lowerServiceName.contains(key.toLowerCase()) || (key.isNotEmpty && key.toLowerCase().contains(lowerServiceName))); } }