import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'package:onsolgo/core/constants.dart'; import 'package:onsolgo/screens/reader/reader_view.dart'; import 'package:onsolgo/widgets/energy_user_chip.dart'; import 'package:onsolgo/screens/auth/tier_comparison_screen.dart'; import 'package:share_plus/share_plus.dart'; class SeriesDetail extends StatefulWidget { final DocumentSnapshot manga; const SeriesDetail({super.key, required this.manga}); @override State createState() => _SeriesDetailState(); } class _SeriesDetailState extends State { InterstitialAd? _interstitialAd; @override void initState() { super.initState(); if (!kIsWeb) _loadInterstitial(); } void _loadInterstitial() { InterstitialAd.load(adUnitId: "ca-app-pub-3940256099942544/1033173712", request: const AdRequest(), adLoadCallback: InterstitialAdLoadCallback(onAdLoaded: (ad) => setState(() => _interstitialAd = ad), onAdFailedToLoad: (e) => debugPrint('$e'))); } Future _handleAccess(DocumentSnapshot ch) async { final uid = FirebaseAuth.instance.currentUser?.uid; if (uid == null) return; final userDoc = await FirebaseFirestore.instance.collection('users').doc(uid).get(); final uData = userDoc.data() ?? {}; // ELITE BYPASS: Rank 5 or Paid Tier if ((uData['tier'] ?? 'free') != 'free' || safeInt(uData['rankLevel']) == 5 || (uData['isVerified'] ?? false)) { _openReader(ch); return; } int energy = safeInt(uData['energy'] ?? 2); if (energy > 0) { await userDoc.reference.update({'energy': energy - 1, 'lastEnergyRefill': FieldValue.serverTimestamp()}); if (_interstitialAd != null && !kIsWeb) { _interstitialAd!.fullScreenContentCallback = FullScreenContentCallback(onAdDismissedFullScreenContent: (ad) { ad.dispose(); _openReader(ch); _loadInterstitial(); }); _interstitialAd!.show(); _interstitialAd = null; } else { _openReader(ch); } } else { _showExhausted(); } } void _openReader(DocumentSnapshot ch) { Navigator.push(context, MaterialPageRoute(builder: (c) => ReaderView(manga: widget.manga, chapter: ch))); } void _showExhausted() { showDialog(context: context, builder: (ctx) => AlertDialog(backgroundColor: Colors.grey[900], shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15), side: const BorderSide(color: Colors.red)), title: const Text("ENERGY DEPLETED"), content: const Text("Recharge in 24 hours or upgrade to OGO+."), actions: [ElevatedButton(onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (c) => const TierComparisonScreen())), child: const Text("UPGRADE"))])); } @override Widget build(BuildContext context) { final md = widget.manga.data() as Map; final String cover = (md['coverUrl'] as String?)?.trim() ?? ''; final String banner = (md['bannerUrl'] as String?)?.trim() ?? ''; final bool hasBanner = banner.isNotEmpty; final String heroUrl = hasBanner ? banner : cover; final String uid = FirebaseAuth.instance.currentUser?.uid ?? ""; return Scaffold( backgroundColor: Colors.black, extendBodyBehindAppBar: true, appBar: AppBar(backgroundColor: Colors.transparent, elevation: 0, actions: [IconButton( icon: const Icon(Icons.share_outlined), onPressed: () => SharePlus.instance.share( ShareParams(text: 'Check out ${md['title']} on ONSOL-GO!\n\n$kOnsolAppWebUrl'), ), )]), body: SingleChildScrollView(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Stack(children: [ CachedNetworkImage( imageUrl: heroUrl, width: double.infinity, height: hasBanner ? 300 : 380, fit: BoxFit.cover, alignment: Alignment.topCenter, placeholder: (context, url) => Container( height: hasBanner ? 300 : 380, color: Colors.grey[900], ), ), Container( height: hasBanner ? 301 : 381, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.transparent, Colors.black.withValues(alpha: 0.9), Colors.black], ), ), ), ]), Padding( padding: const EdgeInsets.all(20), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ if (hasBanner) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(md['title'] ?? '', style: const TextStyle(fontSize: 26, fontWeight: FontWeight.bold)), Text(md['author'] ?? '', style: const TextStyle(fontSize: 17, color: kOnsolGold)), ], ) else ...[ Text(md['title'] ?? '', style: const TextStyle(fontSize: 28, fontWeight: FontWeight.bold)), Text(md['author'] ?? '', style: const TextStyle(fontSize: 18, color: kOnsolGold)), ], const SizedBox(height: 12), Align(alignment: Alignment.centerLeft, child: EnergyUserChip(uid: uid)), const SizedBox(height: 16), const Text("SYNOPSIS", style: TextStyle(fontSize: 10, color: Colors.grey, fontWeight: FontWeight.bold, letterSpacing: 2)), Text(md['synopsis'] ?? "No transmission recorded.", style: const TextStyle(color: Colors.white70, height: 1.4)), const SizedBox(height: 30), const Text("CHAPTERS", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), StreamBuilder( stream: widget.manga.reference.collection('chapters').orderBy('chapterNumber', descending: true).snapshots(), builder: (context, snapshot) { if (!snapshot.hasData) return const CircularProgressIndicator(); return ListView.builder( padding: const EdgeInsets.only(top: 10), shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: snapshot.data!.docs.length, itemBuilder: (c, i) => _ChapterTile(ch: snapshot.data!.docs[i], manga: widget.manga, uid: uid, onTap: () => _handleAccess(snapshot.data!.docs[i])), ); }, ) ]), ), ])), ); } } class _ChapterTile extends StatelessWidget { final DocumentSnapshot ch; final DocumentSnapshot manga; final String uid; final VoidCallback onTap; const _ChapterTile({required this.ch, required this.manga, required this.uid, required this.onTap}); @override Widget build(BuildContext context) { final cd = ch.data() as Map; return StreamBuilder( stream: FirebaseFirestore.instance.collection('users').doc(uid).collection('progress').doc(manga.id).snapshots(), builder: (context, prog) { double p = (prog.hasData && prog.data!.exists && prog.data!['lastChapter'] == cd['chapterNumber']) ? prog.data!['percent'] : 0.0; return Card( color: Colors.grey[900], margin: const EdgeInsets.only(bottom: 12), child: ListTile( onTap: onTap, leading: ClipRRect(borderRadius: BorderRadius.circular(4), child: CachedNetworkImage(imageUrl: cd['chapterCoverUrl'] ?? (manga.data() as Map)['coverUrl'], width: 50, height: 50, fit: BoxFit.cover)), title: Text("Ch ${cd['chapterNumber']}"), subtitle: LinearProgressIndicator(value: p, color: kOnsolGold, backgroundColor: Colors.white10, minHeight: 2), trailing: const Icon(Icons.bolt, color: Colors.orangeAccent, size: 18), ), ); } ); } }