import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../../core/models/financial_table_entry.dart'; String _formatIndianCurrency(double amount) { // Convert to integer to avoid decimal places int intAmount = amount.round(); // Format with Indian numbering system (commas every 2 digits after the first 3) String amountStr = intAmount.toString(); String formatted = ''; if (amountStr.length <= 3) { formatted = amountStr; } else { // For amounts > 999, use Indian comma system int remaining = amountStr.length; int start = 0; // First group (rightmost 3 digits) if (remaining > 3) { formatted = amountStr.substring(amountStr.length - 3); remaining -= 3; start = amountStr.length - 3; } else { formatted = amountStr; remaining = 0; } // Subsequent groups (2 digits each) while (remaining > 0) { int groupSize = remaining >= 2 ? 2 : remaining; int groupStart = start - groupSize; String group = amountStr.substring(groupStart, start); formatted = group + ',' + formatted; start = groupStart; remaining -= groupSize; } } return '₹$formatted'; } class FinancialTable extends StatelessWidget { final List entries; final bool isLoading; final VoidCallback? onRefresh; const FinancialTable({ super.key, required this.entries, this.isLoading = false, this.onRefresh, }); @override Widget build(BuildContext context) { return Card( elevation: 2, margin: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header Container( padding: EdgeInsets.all(20.w), decoration: BoxDecoration( color: Colors.green.shade50, borderRadius: BorderRadius.only( topLeft: Radius.circular(8.r), topRight: Radius.circular(8.r), ), ), child: Row( children: [ Icon( Icons.table_chart, color: Colors.green.shade700, size: 28.w, ), SizedBox(width: 12.w), Expanded( child: Text( 'Financial Summary', style: TextStyle( fontSize: 22.sp, fontWeight: FontWeight.w600, color: Colors.green.shade700, ), ), ), if (onRefresh != null) Material( color: Colors.transparent, child: InkWell( borderRadius: BorderRadius.circular(24.r), onTap: onRefresh, child: Padding( padding: EdgeInsets.all(12.w), child: Icon( Icons.refresh, size: 24.w, color: Colors.green.shade700, ), ), ), ), ], ), ), // Table if (isLoading) Container( height: 200.h, alignment: Alignment.center, child: const CircularProgressIndicator(), ) else if (entries.isEmpty) Container( height: 200.h, alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.table_rows_outlined, size: 48.w, color: Colors.grey.shade400, ), SizedBox(height: 16.h), Text( 'No financial data available', style: TextStyle( fontSize: 18.sp, color: Colors.grey.shade600, ), ), ], ), ) else SingleChildScrollView( scrollDirection: Axis.horizontal, child: DataTable( columnSpacing: 20.w, headingRowColor: MaterialStateProperty.all(Colors.green.shade100), columns: [ _buildHeaderColumn('Month/Year', 140.w), _buildHeaderColumn('Chit Value', 140.w), _buildHeaderColumn('Bid Amount', 140.w), _buildHeaderColumn('Subscription', 140.w), _buildHeaderColumn('Commission', 140.w), _buildHeaderColumn('Total Payable', 140.w), _buildHeaderColumn('Dividend', 140.w), ], rows: entries.map((entry) { return DataRow( cells: [ _buildCell(entry.monthYear, isBold: entry.isTotal), _buildCell('₹${entry.chitValue.toStringAsFixed(0)}', isBold: entry.isTotal), _buildCell('₹${entry.bidAmount.toStringAsFixed(0)}', isBold: entry.isTotal), _buildCell('₹${entry.subscriptionAmount.toStringAsFixed(0)}', isBold: entry.isTotal), _buildCell('₹${entry.commissionInstallment.toStringAsFixed(0)}', isBold: entry.isTotal), _buildCell('₹${entry.totalPayableInstallment.toStringAsFixed(0)}', isBold: entry.isTotal), _buildCell( '₹${entry.dividendAmount.toStringAsFixed(0)}', isBold: entry.isTotal, color: entry.isDividendNegative ? Colors.red : Colors.green, ), ], ); }).toList(), ), ), ], ), ); } DataColumn _buildHeaderColumn(String label, double width) { return DataColumn( label: Container( width: width, child: Text( label, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: Colors.green.shade800, ), overflow: TextOverflow.ellipsis, ), ), ); } DataCell _buildCell(String text, {bool isBold = false, Color? color}) { return DataCell( Container( padding: EdgeInsets.symmetric(vertical: 12.h), child: Text( text, style: TextStyle( fontSize: 15.sp, fontWeight: isBold ? FontWeight.w600 : FontWeight.normal, color: color ?? (isBold ? Colors.green.shade800 : Colors.grey.shade800), ), overflow: TextOverflow.ellipsis, ), ), ); } } class CompactFinancialTable extends StatelessWidget { final List entries; final bool isLoading; final VoidCallback? onRefresh; const CompactFinancialTable({ super.key, required this.entries, this.isLoading = false, this.onRefresh, }); @override Widget build(BuildContext context) { return Card( elevation: 2, margin: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: Colors.green.shade50, borderRadius: BorderRadius.only( topLeft: Radius.circular(12.r), topRight: Radius.circular(12.r), ), ), child: Row( children: [ Container( padding: EdgeInsets.all(8.w), decoration: BoxDecoration( color: Colors.green.shade600.withOpacity(0.1), borderRadius: BorderRadius.circular(8.r), ), child: Icon( Icons.table_chart, color: Colors.green.shade700, size: 20.w, ), ), SizedBox(width: 12.w), Expanded( child: Text( 'Financial Summary', style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w600, color: Colors.green.shade700, ), ), ), if (onRefresh != null) Material( color: Colors.transparent, child: InkWell( borderRadius: BorderRadius.circular(20.r), onTap: onRefresh, child: Padding( padding: EdgeInsets.all(8.w), child: Icon( Icons.refresh, size: 20.w, color: Colors.green.shade700, ), ), ), ), ], ), ), // Mobile-optimized list view if (isLoading) Container( height: 150.h, alignment: Alignment.center, child: const CircularProgressIndicator(), ) else if (entries.isEmpty) Container( height: 150.h, alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.table_rows_outlined, size: 32.w, color: Colors.grey.shade400, ), SizedBox(height: 8.h), Text( 'No financial data', style: TextStyle( fontSize: 16.sp, color: Colors.grey.shade600, ), ), ], ), ) else ListView.separated( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: entries.length, separatorBuilder: (context, index) => Divider(height: 1.h, color: Colors.grey.shade200), itemBuilder: (context, index) { final entry = entries[index]; return _buildMobileRow(entry); }, ), ], ), ); } Widget _buildMobileRow(FinancialTableEntry entry) { final isTotal = entry.isTotal; return Container( padding: EdgeInsets.all(16.w), color: isTotal ? Colors.green.shade50 : Colors.transparent, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Month/Year header Row( children: [ Container( padding: EdgeInsets.all(6.w), decoration: BoxDecoration( color: (isTotal ? Colors.green.shade600 : Colors.grey.shade600).withOpacity(0.1), borderRadius: BorderRadius.circular(6.r), ), child: Icon( isTotal ? Icons.calculate : Icons.calendar_today, size: 16.w, color: isTotal ? Colors.green.shade700 : Colors.grey.shade600, ), ), SizedBox(width: 8.w), Expanded( child: Text( entry.monthYear, style: TextStyle( fontSize: 16.sp, fontWeight: isTotal ? FontWeight.w600 : FontWeight.w500, color: isTotal ? Colors.green.shade800 : Colors.grey.shade800, ), ), ), if (isTotal) Container( padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 3.h), decoration: BoxDecoration( color: Colors.green.shade100, borderRadius: BorderRadius.circular(12.r), ), child: Text( 'TOTAL', style: TextStyle( fontSize: 10.sp, fontWeight: FontWeight.w600, color: Colors.green.shade700, ), ), ), ], ), SizedBox(height: 12.h), // Financial data grid - optimized for mobile Column( children: [ Row( children: [ Expanded( child: _buildMobileCard('Chit Value', _formatIndianCurrency(entry.chitValue), Icons.currency_rupee, Colors.blue), ), SizedBox(width: 8.w), Expanded( child: _buildMobileCard('Bid Amount', _formatIndianCurrency(entry.bidAmount), Icons.payment, Colors.green), ), ], ), SizedBox(height: 6.h), Row( children: [ Expanded( child: _buildMobileCard('Subscription', _formatIndianCurrency(entry.subscriptionAmount), Icons.account_balance_wallet, Colors.orange), ), SizedBox(width: 8.w), Expanded( child: _buildMobileCard('Commission', _formatIndianCurrency(entry.commissionInstallment), Icons.percent, Colors.purple), ), ], ), SizedBox(height: 6.h), Row( children: [ Expanded( child: _buildMobileCard('Total Payable', _formatIndianCurrency(entry.totalPayableInstallment), Icons.calculate, Colors.indigo), ), SizedBox(width: 8.w), Expanded( child: _buildMobileCard( 'Dividend', _formatIndianCurrency(entry.dividendAmount), Icons.trending_up, entry.isDividendNegative ? Colors.red : Colors.green, ), ), ], ), ], ), ], ), ); } Widget _buildMobileCard(String label, String value, IconData icon, Color color) { return Container( padding: EdgeInsets.all(12.w), decoration: BoxDecoration( color: color.withOpacity(0.08), borderRadius: BorderRadius.circular(8.r), border: Border.all(color: color.withOpacity(0.2), width: 1), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(icon, size: 16.w, color: color), SizedBox(width: 6.w), Expanded( child: Text( label, style: TextStyle( fontSize: 12.sp, color: color, fontWeight: FontWeight.w500, ), overflow: TextOverflow.ellipsis, ), ), ], ), SizedBox(height: 2.h), Text( value, style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w600, color: color, ), overflow: TextOverflow.ellipsis, ), ], ), ); } DataColumn _buildCompactHeaderColumn(String label, double width) { return DataColumn( label: Container( width: width, child: Text( label, style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w600, color: Colors.green.shade800, ), overflow: TextOverflow.ellipsis, ), ), ); } DataCell _buildCompactCell(String text, {bool isBold = false, Color? color}) { return DataCell( Container( padding: EdgeInsets.symmetric(vertical: 6.h), child: Text( text, style: TextStyle( fontSize: 13.sp, fontWeight: isBold ? FontWeight.w600 : FontWeight.normal, color: color ?? (isBold ? Colors.green.shade800 : Colors.grey.shade800), ), overflow: TextOverflow.ellipsis, ), ), ); } }