// ServiceInfo를 외부에서 접근 가능하도록 export export 'url_matcher/models/service_info.dart'; import 'url_matcher/models/service_info.dart'; import 'url_matcher/data/service_data_repository.dart'; import 'url_matcher/services/url_matcher_service.dart'; import 'url_matcher/services/category_mapper_service.dart'; import 'url_matcher/services/cancellation_url_service.dart'; import 'url_matcher/services/service_name_resolver.dart'; import 'url_matcher/services/sms_extractor_service.dart'; /// 구독 서비스와 웹사이트 URL 매칭을 처리하는 서비스 클래스 (Facade 패턴) class SubscriptionUrlMatcher { static ServiceDataRepository? _dataRepository; static UrlMatcherService? _urlMatcher; static CategoryMapperService? _categoryMapper; static CancellationUrlService? _cancellationService; static ServiceNameResolver? _nameResolver; static SmsExtractorService? _smsExtractor; /// 서비스 초기화 static Future initialize() async { if (_dataRepository != null && _dataRepository!.isInitialized) return; // 1. 데이터 저장소 초기화 _dataRepository = ServiceDataRepository(); await _dataRepository!.initialize(); // 2. 서비스 초기화 _categoryMapper = CategoryMapperService(_dataRepository!); _urlMatcher = UrlMatcherService(_dataRepository!, _categoryMapper!); _cancellationService = CancellationUrlService(_dataRepository!, _urlMatcher!); _nameResolver = ServiceNameResolver(_dataRepository!); _smsExtractor = SmsExtractorService(_urlMatcher!, _categoryMapper!); } /// 도메인 추출 (www와 TLD 제외) static String? extractDomain(String url) { return _urlMatcher?.extractDomain(url); } /// URL로 서비스 찾기 static Future findServiceByUrl(String url) async { await initialize(); return _urlMatcher?.findServiceByUrl(url); } /// 서비스명으로 URL 찾기 (기존 suggestUrl 메서드 유지) static String? suggestUrl(String serviceName) { return _urlMatcher?.suggestUrl(serviceName); } /// 서비스명 또는 URL로 해지 안내 페이지 URL 찾기 static Future findCancellationUrl({ String? serviceName, String? websiteUrl, String locale = 'kr', }) async { await initialize(); return _cancellationService?.findCancellationUrl( serviceName: serviceName, websiteUrl: websiteUrl, locale: locale, ); } /// 서비스에 공식 해지 안내 페이지가 있는지 확인 static Future hasCancellationPage(String serviceNameOrUrl) async { await initialize(); return await _cancellationService?.hasCancellationPage(serviceNameOrUrl) ?? false; } /// 서비스명으로 카테고리 찾기 static Future findCategoryByServiceName(String serviceName) async { await initialize(); return _categoryMapper?.findCategoryByServiceName(serviceName); } /// 현재 로케일에 따라 서비스 표시명 가져오기 static Future getServiceDisplayName({ required String serviceName, required String locale, }) async { await initialize(); return await _nameResolver?.getServiceDisplayName( serviceName: serviceName, locale: locale, ) ?? serviceName; } /// SMS에서 URL과 서비스 정보 추출 static Future extractServiceFromSms(String smsText) async { await initialize(); return _smsExtractor?.extractServiceFromSms(smsText); } /// URL이 알려진 서비스 URL인지 확인 static Future isKnownServiceUrl(String url) async { await initialize(); return await _urlMatcher?.isKnownServiceUrl(url) ?? false; } /// 입력된 서비스 이름이나 문자열에서 매칭되는 URL을 찾아 반환 (레거시 호환성) static String? findMatchingUrl(String text, {bool usePartialMatch = true}) { return _urlMatcher?.findMatchingUrl(text, usePartialMatch: usePartialMatch); } }