import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../../services/billing/product_catalog.dart'; import '../../../services/entitlements/entitlement_providers.dart'; import '../../../services/entitlements/entitlement_state.dart'; import '../../entitlements/widgets/pro_lock_badge.dart'; /// Reusable card displaying the current plan and subscription management options. /// Used in both Classic Settings and Evolution Settings. class CurrentPlanCard extends ConsumerWidget { final bool isEvolution; const CurrentPlanCard({super.key, this.isEvolution = false}); Future _openGooglePlaySubscriptions() async { // Official Google Play subscription management deep link final uri = Uri.parse( 'https://play.google.com/store/account/subscriptions?package=app.motorsignal.motorcycle&sku=${ProductCatalog.proMonthly}', ); try { if (await canLaunchUrl(uri)) { await launchUrl(uri, mode: LaunchMode.externalApplication); } } catch (_) {} } @override Widget build(BuildContext context, WidgetRef ref) { final entitlement = ref.watch(entitlementProvider); final isPro = entitlement.isPro; final plan = entitlement.plan; final status = entitlement.status; String planTitle = 'MotorSignal Free'; String statusSubtitle = 'Basic telemetry & local recording active'; Color badgeColor = Colors.white54; String badgeText = 'FREE'; if (plan == MotorSignalPlan.proLifetime && isPro) { planTitle = 'MotorSignal Pro'; statusSubtitle = 'Lifetime access • Permanent ownership'; badgeColor = const Color(0xFF00E5FF); badgeText = 'LIFETIME'; } else if (plan == MotorSignalPlan.proMonthly) { planTitle = 'MotorSignal Pro'; badgeColor = const Color(0xFF00E5FF); badgeText = 'MONTHLY'; switch (status) { case MotorSignalEntitlementStatus.proMonthlyActive: statusSubtitle = entitlement.expiresAt != null ? 'Active • Renews ${entitlement.expiresAt!.toLocal().toString().split(' ')[0]}' : 'Active subscription'; break; case MotorSignalEntitlementStatus.proMonthlyGrace: statusSubtitle = 'Payment grace period • Action needed in Google Play'; badgeColor = Colors.amberAccent; badgeText = 'GRACE PERIOD'; break; case MotorSignalEntitlementStatus.proMonthlyAccountHold: statusSubtitle = 'Account on hold • Please update billing in Google Play'; badgeColor = Colors.redAccent; badgeText = 'ON HOLD'; break; case MotorSignalEntitlementStatus.proMonthlyPaused: statusSubtitle = 'Subscription paused by rider in Google Play'; badgeColor = Colors.amberAccent; badgeText = 'PAUSED'; break; case MotorSignalEntitlementStatus.proMonthlyExpired: statusSubtitle = 'Subscription expired'; badgeColor = Colors.white38; badgeText = 'EXPIRED'; break; case MotorSignalEntitlementStatus.syncPending: statusSubtitle = 'Verification pending with Google Play...'; badgeColor = Colors.amberAccent; badgeText = 'VERIFYING'; break; default: statusSubtitle = 'Status: ${status.name}'; break; } } else if (status == MotorSignalEntitlementStatus.syncPending) { statusSubtitle = 'Checking purchases with Google Play...'; badgeColor = Colors.amberAccent; badgeText = 'PENDING'; } final isMonthlySub = plan == MotorSignalPlan.proMonthly; return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: isEvolution ? const Color(0xFF0D0D0D) : null, borderRadius: BorderRadius.circular(isEvolution ? 16 : 12), border: Border.all( color: isPro ? const Color(0xFF00E5FF).withValues(alpha: 0.6) : (isEvolution ? const Color(0xFF1F1F1F) : Colors.white12), width: 1.2, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Wrap( alignment: WrapAlignment.spaceBetween, crossAxisAlignment: WrapCrossAlignment.center, spacing: 8, runSpacing: 6, children: [ Row( mainAxisSize: MainAxisSize.min, children: [ Icon( isPro ? Icons.verified : Icons.shield_outlined, color: isPro ? const Color(0xFF00E5FF) : Colors.white70, size: 20, ), const SizedBox(width: 10), Text( planTitle.toUpperCase(), style: TextStyle( fontFamily: isEvolution ? 'Sora' : null, fontSize: 13, fontWeight: FontWeight.w800, color: isPro ? const Color(0xFF00E5FF) : Colors.white, letterSpacing: 0.5, ), ), if (isPro) ...[const SizedBox(width: 8), const ProBadge()], ], ), Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( color: badgeColor.withValues(alpha: 0.15), borderRadius: BorderRadius.circular(6), border: Border.all( color: badgeColor.withValues(alpha: 0.5), width: 0.8, ), ), child: Text( badgeText, style: TextStyle( fontFamily: 'Inter', fontSize: 9, fontWeight: FontWeight.w900, color: badgeColor, letterSpacing: 0.5, ), ), ), ], ), const SizedBox(height: 8), Text( statusSubtitle, style: const TextStyle( fontSize: 12, color: Colors.white70, height: 1.3, ), ), const SizedBox(height: 16), Row( children: [ if (!isPro) ...[ Expanded( child: ElevatedButton( key: const ValueKey('settings_upgrade_to_pro_button'), style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF00E5FF), foregroundColor: Colors.black, padding: const EdgeInsets.symmetric(vertical: 10), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), onPressed: () => context.push('/settings/pro'), child: const Text( 'UPGRADE TO PRO', style: TextStyle( fontSize: 11, fontWeight: FontWeight.w800, ), ), ), ), const SizedBox(width: 10), ], if (isMonthlySub) ...[ Expanded( child: OutlinedButton( style: OutlinedButton.styleFrom( foregroundColor: Colors.white70, side: const BorderSide(color: Colors.white24), padding: const EdgeInsets.symmetric(vertical: 10), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), onPressed: _openGooglePlaySubscriptions, child: const Text( 'MANAGE SUBSCRIPTION', style: TextStyle( fontSize: 11, fontWeight: FontWeight.bold, ), ), ), ), const SizedBox(width: 10), ], OutlinedButton( key: const ValueKey('settings_pro_details_button'), style: OutlinedButton.styleFrom( foregroundColor: Colors.white70, side: const BorderSide(color: Colors.white24), padding: const EdgeInsets.symmetric( vertical: 10, horizontal: 12, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), onPressed: () => context.push('/settings/pro'), child: Text( isPro ? 'VIEW PLANS' : 'DETAILS', style: const TextStyle(fontSize: 11), ), ), ], ), ], ), ); } }