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 '../../../core/theme/theme_extensions.dart'; import '../../../core/theme/app_typography.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 canonical responsive card displaying the current plan and subscription management options. class CurrentPlanCard extends ConsumerWidget { const CurrentPlanCard({super.key}); 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 colors = context.motorColors; 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.outlineVariant; String badgeText = 'FREE'; if (plan == MotorSignalPlan.proLifetime && isPro) { planTitle = 'MotorSignal Pro'; statusSubtitle = 'Lifetime access • Permanent ownership'; badgeColor = colors.cyberCyan; badgeText = 'LIFETIME'; } else if (plan == MotorSignalPlan.proMonthly) { planTitle = 'MotorSignal Pro'; badgeColor = colors.cyberCyan; 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.warningAmber; badgeText = 'GRACE PERIOD'; break; case MotorSignalEntitlementStatus.proMonthlyAccountHold: statusSubtitle = 'Account on hold • Please update billing in Google Play'; badgeColor = colors.raceRed; badgeText = 'ON HOLD'; break; case MotorSignalEntitlementStatus.proMonthlyPaused: statusSubtitle = 'Subscription paused by rider in Google Play'; badgeColor = colors.warningAmber; badgeText = 'PAUSED'; break; case MotorSignalEntitlementStatus.proMonthlyExpired: statusSubtitle = 'Subscription expired'; badgeColor = colors.outlineVariant; badgeText = 'EXPIRED'; break; case MotorSignalEntitlementStatus.syncPending: statusSubtitle = 'Verification pending with Google Play...'; badgeColor = colors.warningAmber; badgeText = 'VERIFYING'; break; default: statusSubtitle = 'Status: ${status.name}'; break; } } else if (status == MotorSignalEntitlementStatus.syncPending) { statusSubtitle = 'Checking purchases with Google Play...'; badgeColor = colors.warningAmber; badgeText = 'PENDING'; } final isMonthlySub = plan == MotorSignalPlan.proMonthly; return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: colors.surfaceContainer, borderRadius: BorderRadius.circular(16), border: Border.all( color: isPro ? colors.cyberCyan.withValues(alpha: 0.6) : colors.outlineVariant, 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 ? colors.cyberCyan : colors.outline, size: 18, ), const SizedBox(width: 8), Text( planTitle, style: TextStyle( fontFamily: AppTypography.fontHeadline, fontSize: 13, fontWeight: FontWeight.w700, color: isPro ? colors.cyberCyan : Theme.of(context).colorScheme.onSurface, letterSpacing: 0.2, ), ), if (isPro) ...[const SizedBox(width: 6), const ProBadge()], ], ), Container( padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 2.5), 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.w700, color: badgeColor, letterSpacing: 0.5, ), ), ), ], ), const SizedBox(height: 8), Text( statusSubtitle, style: TextStyle( fontSize: 12, color: Theme.of(context).colorScheme.onSurfaceVariant, height: 1.3, ), ), const SizedBox(height: 16), Wrap( spacing: 8, runSpacing: 8, children: [ if (!isPro) ElevatedButton( key: const ValueKey('settings_upgrade_to_pro_button'), style: ElevatedButton.styleFrom( backgroundColor: colors.cyberCyan, foregroundColor: Colors.black, minimumSize: const Size(130, 44), padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), onPressed: () => context.push('/settings/pro'), child: const Text( 'Upgrade to Pro', style: TextStyle( fontSize: 11.5, fontWeight: FontWeight.w600, letterSpacing: 0.2, ), ), ), if (isMonthlySub) OutlinedButton( style: OutlinedButton.styleFrom( foregroundColor: Theme.of(context).colorScheme.onSurface, side: BorderSide(color: colors.outlineVariant), minimumSize: const Size(140, 44), padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), onPressed: _openGooglePlaySubscriptions, child: const Text( 'Manage Subscription', style: TextStyle( fontSize: 11.5, fontWeight: FontWeight.w600, ), ), ), OutlinedButton( key: const ValueKey('settings_pro_details_button'), style: OutlinedButton.styleFrom( foregroundColor: Theme.of(context).colorScheme.onSurface, side: BorderSide(color: colors.outlineVariant), minimumSize: const Size(90, 44), padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), onPressed: () => context.push('/settings/pro'), child: Text( isPro ? 'View Plans' : 'Details', style: const TextStyle(fontSize: 11.5, fontWeight: FontWeight.w600), ), ), ], ), ], ), ); } }