import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'package:lunchpick/core/utils/ad_helper.dart'; /// 실제 구글 전면 광고(Interstitial Ad) 서비스. class AdService { InterstitialAd? _interstitialAd; Completer? _loadingCompleter; /// 광고를 로드하고 재생한 뒤 완료 여부를 반환한다. Future showInterstitialAd(BuildContext context) async { if (!AdHelper.isMobilePlatform) return true; final closeLoading = _showLoadingOverlay(context); await _enterImmersiveMode(); final loaded = await _ensureAdLoaded(); closeLoading(); if (!loaded) { await _restoreSystemUi(); return false; } final ad = _interstitialAd; if (ad == null) { await _restoreSystemUi(); return false; } _interstitialAd = null; final completer = Completer(); ad.fullScreenContentCallback = FullScreenContentCallback( onAdDismissedFullScreenContent: (ad) { ad.dispose(); _preload(); unawaited(_restoreSystemUi()); completer.complete(true); }, onAdFailedToShowFullScreenContent: (ad, error) { ad.dispose(); _preload(); unawaited(_restoreSystemUi()); completer.complete(false); }, ); // 상하단 여백 없이 전체 화면으로 표시하도록 immersive 모드 설정. ad.setImmersiveMode(true); try { ad.show(); } catch (_) { unawaited(_restoreSystemUi()); completer.complete(false); } return completer.future; } Future _enterImmersiveMode() async { try { await SystemChrome.setEnabledSystemUIMode( SystemUiMode.immersiveSticky, overlays: [], ); } catch (_) {} } Future _restoreSystemUi() async { try { await SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); } catch (_) {} } VoidCallback _showLoadingOverlay(BuildContext context) { final navigator = Navigator.of(context, rootNavigator: true); showDialog( context: context, barrierDismissible: false, barrierColor: Colors.black.withOpacity(0.35), builder: (_) => const Center(child: CircularProgressIndicator()), ); return () { if (navigator.mounted && navigator.canPop()) { navigator.pop(); } }; } Future _ensureAdLoaded() async { if (_interstitialAd != null) return true; if (_loadingCompleter != null) { return _loadingCompleter!.future; } final completer = Completer(); _loadingCompleter = completer; InterstitialAd.load( adUnitId: AdHelper.interstitialAdUnitId, request: const AdRequest(), adLoadCallback: InterstitialAdLoadCallback( onAdLoaded: (ad) { _interstitialAd = ad; completer.complete(true); _loadingCompleter = null; }, onAdFailedToLoad: (error) { completer.complete(false); _loadingCompleter = null; }, ), ); return completer.future; } void _preload() { if (_interstitialAd != null || _loadingCompleter != null) return; _ensureAdLoaded(); } }