import 'package:flutter/material.dart'; import '../../core/constants/app_colors.dart'; import '../../core/constants/app_text_styles.dart'; import '../widgets/teacher_panel_scaffold.dart'; import 'course_page.dart'; import 'license_page.dart'; import 'ticket_page.dart'; import 'transaction_page.dart'; class PlanRenewalPage extends StatefulWidget { const PlanRenewalPage({super.key}); @override State createState() => _PlanRenewalPageState(); } class _PlanRenewalPageState extends State { int _billingCycle = 365; int _selectedPlan = 3; String _extraSpace = '5 GB'; bool _useLocalServer = false; bool _acceptTerms = false; final List> _plans = const [ {'size': '20 GB', 'monthly': 82000}, {'size': '50 GB', 'monthly': 145000}, {'size': '125 GB', 'monthly': 343000}, {'size': '250 GB', 'monthly': 395000}, {'size': '500 GB', 'monthly': 999000}, {'size': '1000 GB', 'monthly': 1455000}, ]; int get _cycleFactor { if (_billingCycle == 60) return 2; if (_billingCycle == 365) return 12; return 1; } int get _fee => (_plans[_selectedPlan]['monthly'] as int) * _cycleFactor; int get _payable => _fee; Widget _buildLabeledField(String label, String value, {String? helperText}) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(label, style: AppTextStyles.bodyLarge), const SizedBox(height: 8), Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), border: Border.all( color: AppColors.sidebarBg.withValues(alpha: 0.6), ), color: Colors.white, ), child: Text( value, style: AppTextStyles.bodyLarge.copyWith(color: AppColors.sidebarBg), ), ), if (helperText != null) ...[ const SizedBox(height: 8), Text(helperText, style: AppTextStyles.bodyMedium), ], ], ); } Widget _buildMainContent() { final isDesktop = MediaQuery.of(context).size.width > 900; final isMobile = !isDesktop; final plan = _plans[_selectedPlan]; return SingleChildScrollView( padding: EdgeInsets.symmetric( horizontal: isDesktop ? 32 : 16, vertical: 24, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ InkWell( onTap: () => Navigator.pop(context), child: Row( mainAxisSize: MainAxisSize.min, children: [ const Icon( Icons.arrow_back, color: AppColors.sidebarBg, size: 20, ), const SizedBox(width: 8), Text( 'بازگشت به داشبورد', style: AppTextStyles.bodyMedium.copyWith( color: AppColors.sidebarBg, ), ), ], ), ), const SizedBox(height: 20), Text('پلن فضا', style: AppTextStyles.headlineMedium), const SizedBox(height: 20), Flex( direction: isMobile ? Axis.vertical : Axis.horizontal, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( flex: isMobile ? 0 : 3, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildLabeledField('سررسید', '۱۴۰۵/۰۸/۱۰'), const SizedBox(height: 16), Text('فضای اضافه', style: AppTextStyles.bodyLarge), const SizedBox(height: 8), DropdownButtonFormField( initialValue: _extraSpace, isExpanded: true, decoration: InputDecoration( filled: true, fillColor: Colors.white, border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide( color: AppColors.sidebarBg.withValues(alpha: 0.6), ), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide( color: AppColors.sidebarBg.withValues(alpha: 0.6), ), ), ), items: const ['0 GB', '5 GB', '10 GB', '20 GB', '50 GB'] .map( (value) => DropdownMenuItem( value: value, child: Text( value, style: AppTextStyles.bodyLarge, ), ), ) .toList(), onChanged: (value) { if (value == null) return; setState(() => _extraSpace = value); }, ), const SizedBox(height: 8), Text( 'فضای اضافه روی همین مجموعه فعال می‌شود و در صورت نیاز می‌توانید بعدا آن را تغییر دهید.', style: AppTextStyles.bodyMedium, ), const SizedBox(height: 16), Row( children: [ Checkbox( value: _useLocalServer, onChanged: (value) { setState(() => _useLocalServer = value ?? false); }, ), Text('سرور آلمان', style: AppTextStyles.bodyLarge), ], ), Text( 'در صورت انتخاب، بکاپ‌گیری روی سرور ثانویه هم انجام می‌شود و هزینه سرویس تغییر می‌کند.', style: AppTextStyles.bodyMedium, ), ], ), ), SizedBox(width: isMobile ? 0 : 32, height: isMobile ? 24 : 0), Expanded( flex: isMobile ? 0 : 2, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('دوره پرداخت', style: AppTextStyles.headlineMedium), const SizedBox(height: 10), Wrap( spacing: 20, runSpacing: 8, children: [ _buildCycleOption('۳۰ ماهه', 30), _buildCycleOption('۶۰ ماهه', 60), _buildCycleOption('سالانه', 365), ], ), const SizedBox(height: 24), Text('فضا', style: AppTextStyles.headlineMedium), const SizedBox(height: 8), ...List.generate(_plans.length, (index) { final item = _plans[index]; final monthly = item['monthly'] as int; final selected = index == _selectedPlan; return InkWell( onTap: () => setState(() => _selectedPlan = index), borderRadius: BorderRadius.circular(8), child: Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: Row( children: [ Icon( selected ? Icons.radio_button_checked : Icons.radio_button_unchecked, color: selected ? AppColors.sidebarBg : AppColors.textSecondary, ), const SizedBox(width: 8), Expanded( child: RichText( text: TextSpan( style: AppTextStyles.bodyLarge, children: [ TextSpan( text: 'ماهانه ${_formatNumber(monthly)} تومان - ', ), TextSpan( text: item['size'] as String, style: AppTextStyles.bodyLarge.copyWith( color: selected ? AppColors.creditCardBorder : AppColors.textPrimary, fontWeight: FontWeight.bold, ), ), ], ), ), ), ], ), ), ); }), ], ), ), ], ), const SizedBox(height: 28), Text('پرداخت', style: AppTextStyles.headlineMedium), const SizedBox(height: 12), _buildLabeledField('تعرفه', '${_formatNumber(_fee)} تومان'), const SizedBox(height: 14), _buildLabeledField( 'پرداخت', '${_formatNumber(_payable)} تومان', helperText: 'مبلغ پرداخت با توجه به زمان باقی‌مانده از اعتبار فعلی و تغییرات پلن، ممکن است کمی تغییر کند.', ), const SizedBox(height: 14), _buildLabeledField('اعتبار', '۰'), const SizedBox(height: 18), Row( children: [ Checkbox( value: _acceptTerms, onChanged: (value) { setState(() => _acceptTerms = value ?? false); }, ), Expanded( child: Text( 'شرایط و قوانین سایت را مطالعه کرده و می‌پذیرم.', style: AppTextStyles.bodyMedium, ), ), ], ), const SizedBox(height: 20), Wrap( spacing: 12, runSpacing: 10, children: [ SizedBox( width: isMobile ? double.infinity : 160, height: 44, child: ElevatedButton( onPressed: _acceptTerms ? () {} : null, style: ElevatedButton.styleFrom( backgroundColor: AppColors.success, foregroundColor: Colors.white, disabledBackgroundColor: AppColors.success.withValues( alpha: 0.35, ), ), child: const Text('تایید'), ), ), SizedBox( width: isMobile ? double.infinity : 160, height: 44, child: ElevatedButton( onPressed: () => Navigator.pop(context), style: ElevatedButton.styleFrom( backgroundColor: AppColors.error.withValues(alpha: 0.85), foregroundColor: Colors.white, ), child: const Text('انصراف'), ), ), ], ), const SizedBox(height: 16), Text( 'پلن انتخاب‌شده: ${plan['size']}', style: AppTextStyles.bodyMedium, ), ], ), ); } Widget _buildCycleOption(String title, int value) { final selected = _billingCycle == value; return InkWell( borderRadius: BorderRadius.circular(8), onTap: () => setState(() => _billingCycle = value), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( selected ? Icons.radio_button_checked : Icons.radio_button_unchecked, color: selected ? AppColors.sidebarBg : AppColors.textSecondary, ), Text(title, style: AppTextStyles.bodyLarge), ], ), ); } String _formatNumber(int number) { final chars = number.toString().split('').reversed.toList(); final buffer = StringBuffer(); for (var i = 0; i < chars.length; i++) { if (i != 0 && i % 3 == 0) { buffer.write(','); } buffer.write(chars[i]); } return buffer.toString().split('').reversed.join(); } @override Widget build(BuildContext context) { return TeacherPanelScaffold( selectedMenu: PanelMenu.none, onDashboardTap: () { if (Navigator.of(context).canPop()) { Navigator.of(context).pop(); } }, onCourseTap: () { Navigator.of(context).push( MaterialPageRoute(builder: (context) => const CoursePage()), ); }, onLicenseTap: () { Navigator.of(context).push( MaterialPageRoute(builder: (context) => const PanelLicensePage()), ); }, onTransactionTap: () { Navigator.of(context).push( MaterialPageRoute(builder: (context) => const TransactionPage()), ); }, onTicketTap: () { Navigator.of(context).push( MaterialPageRoute(builder: (context) => const TicketPage()), ); }, child: _buildMainContent(), ); } }