import 'package:flutter/material.dart'; import '../../../../common/extension/extension.dart'; import '../../../../common/theme/theme.dart'; import '../../../../domain/analytic/analytic.dart'; class ProfitLossReport extends StatelessWidget { final List mainSummary; final ProfitLossSummary summary; final int selectedTabIndex; const ProfitLossReport({ super.key, required this.mainSummary, required this.summary, required this.selectedTabIndex, }); @override Widget build(BuildContext context) { final isToday = selectedTabIndex == 0; final marginPct = isToday ? summary.netProfitMargin.round() : summary.netProfitMargin.round(); return Container( margin: const EdgeInsets.all(16), padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: AppColor.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: AppColor.textLight.withOpacity(0.08), spreadRadius: 1, blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Title row Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( context.lang.profit_loss_report, style: AppStyle.lg.copyWith( fontWeight: FontWeight.w700, color: AppColor.textPrimary, ), ), Text( 'margin $marginPct%', style: AppStyle.sm.copyWith( color: AppColor.textSecondary, fontWeight: FontWeight.w400, ), ), ], ), const SizedBox(height: 20), // Main summary items ...mainSummary.map((item) => _buildSummarySection(item, isToday)), const SizedBox(height: 12), // Net Profit/Loss footer _buildNetProfitFooter(context, isToday), ], ), ); } Widget _buildSummarySection(ProfitLossMainSummaryItem item, bool isToday) { final nominal = isToday ? item.todayNominal : item.mtdNominal; final pct = isToday ? item.todayPct : item.mtdPct; return Column( children: [ // Main item row _buildItemRow( label: item.label, nominal: nominal, pct: pct, isBold: item.isBold, isSubItem: false, ), // Sub items ...item.subItems.map((subItem) { final subNominal = isToday ? subItem.todayNominal : subItem.mtdNominal; final subPct = isToday ? subItem.todayPct : subItem.mtdPct; return _buildItemRow( label: subItem.label, nominal: subNominal, pct: subPct, isBold: subItem.isBold, isSubItem: true, ); }), // Divider after section (except for sub-items only sections) if (item.isBold) const Padding( padding: EdgeInsets.symmetric(vertical: 8), child: Divider(height: 1, color: AppColor.borderLight), ), ], ); } Widget _buildItemRow({ required String label, required int nominal, required double pct, required bool isBold, required bool isSubItem, }) { final isNegative = nominal < 0; final displayNominal = isNegative ? '-${nominal.abs().currencyFormatRp}' : nominal.currencyFormatRp; final pctText = '${pct.round()}%'; // Determine color based on context Color nominalColor; if (isBold && isNegative) { nominalColor = AppColor.error; } else if (isBold) { nominalColor = AppColor.textPrimary; } else { nominalColor = AppColor.textPrimary; } return Padding( padding: EdgeInsets.only(left: isSubItem ? 16 : 0, top: 6, bottom: 6), child: Row( children: [ // Label Expanded( flex: 5, child: Text( label, style: isBold ? AppStyle.md.copyWith( fontWeight: FontWeight.w700, color: AppColor.textPrimary, ) : AppStyle.md.copyWith( color: AppColor.textSecondary, fontWeight: FontWeight.w400, ), ), ), // Nominal Expanded( flex: 3, child: Text( displayNominal, textAlign: TextAlign.right, style: isBold ? AppStyle.md.copyWith( fontWeight: FontWeight.w700, color: nominalColor, ) : AppStyle.md.copyWith( color: AppColor.textPrimary, fontWeight: FontWeight.w500, ), ), ), // Percentage SizedBox( width: 48, child: Text( pctText, textAlign: TextAlign.right, style: AppStyle.sm.copyWith( color: AppColor.textSecondary, fontWeight: FontWeight.w400, ), ), ), ], ), ); } Widget _buildNetProfitFooter(BuildContext context, bool isToday) { final netProfit = summary.netProfit; final isNegative = netProfit < 0; final displayValue = isNegative ? '-${netProfit.abs().currencyFormatRp}' : netProfit.currencyFormatRp; return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), decoration: BoxDecoration( color: isNegative ? AppColor.error.withOpacity(0.08) : AppColor.success.withOpacity(0.08), borderRadius: BorderRadius.circular(12), ), child: Row( children: [ Flexible( child: Text( context.lang.net_profit_loss, style: AppStyle.md.copyWith( fontWeight: FontWeight.w700, color: isNegative ? AppColor.error : AppColor.success, ), overflow: TextOverflow.ellipsis, ), ), const SizedBox(width: 12), Text( displayValue, style: AppStyle.lg.copyWith( fontWeight: FontWeight.w900, color: isNegative ? AppColor.error : AppColor.success, fontSize: 20, ), ), ], ), ); } }