import 'package:flutter/material.dart'; import '../../../../common/extension/extension.dart'; import '../../../../common/theme/theme.dart'; import '../../../../domain/analytic/analytic.dart'; import '../../../components/spacer/spacer.dart'; class HeaderSummaryCard extends StatelessWidget { final IconData icon; final Color iconColor; final String title; final int value; final String subtitle; final List dailyData; final double? percentage; final bool isValueVisible; final VoidCallback? onTap; const HeaderSummaryCard({ super.key, required this.icon, required this.iconColor, required this.title, required this.value, required this.subtitle, required this.dailyData, this.percentage, this.isValueVisible = true, this.onTap, }); @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(18), gradient: const LinearGradient( colors: [ Color(0xFFE8000A), // sedikit lebih terang di atas Color(0xFFC40202), // primary di tengah Color(0xFF990000), // gelap di bawah ], begin: Alignment.topLeft, end: Alignment.bottomRight, stops: [0.0, 0.5, 1.0], ), boxShadow: [ // Shadow merah di bawah — efek floating/3D BoxShadow( color: const Color(0xFFC40202).withOpacity(0.55), blurRadius: 16, spreadRadius: 0, offset: const Offset(0, 8), ), // Inner highlight di atas kiri (simulasi cahaya) BoxShadow( color: AppColor.white.withOpacity(0.08), blurRadius: 0, spreadRadius: -1, offset: const Offset(0, 1), ), ], ), child: ClipRRect( borderRadius: BorderRadius.circular(18), child: Stack( children: [ // Top highlight strip — efek glossy Positioned( top: 0, left: 0, right: 0, child: Container( height: 1.5, decoration: BoxDecoration( gradient: LinearGradient( colors: [ AppColor.white.withOpacity(0.0), AppColor.white.withOpacity(0.35), AppColor.white.withOpacity(0.0), ], ), ), ), ), // Decorative circles Positioned( top: -30, right: -30, child: Container( width: 120, height: 120, decoration: BoxDecoration( shape: BoxShape.circle, color: AppColor.white.withOpacity(0.07), ), ), ), Positioned( bottom: -20, right: 20, child: Container( width: 70, height: 70, decoration: BoxDecoration( shape: BoxShape.circle, color: AppColor.white.withOpacity(0.05), ), ), ), Positioned( top: 40, left: -20, child: Container( width: 60, height: 60, decoration: BoxDecoration( shape: BoxShape.circle, color: AppColor.white.withOpacity(0.04), ), ), ), // Content Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Top: Icon + Title + Percentage + Chevron Row( children: [ // Icon dengan shadow Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( gradient: LinearGradient( colors: [iconColor.withOpacity(0.9), iconColor], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(10), boxShadow: [ BoxShadow( color: iconColor.withOpacity(0.5), blurRadius: 8, offset: const Offset(0, 4), ), ], ), child: Icon(icon, color: Colors.white, size: 20), ), const SpaceWidth(10), Text( title, style: AppStyle.md.copyWith( color: AppColor.white, fontWeight: FontWeight.w600, shadows: [ Shadow( color: Colors.black.withOpacity(0.2), blurRadius: 4, offset: const Offset(0, 1), ), ], ), ), const Spacer(), if (percentage != null) _buildPercentageBadge(), const SpaceWidth(6), Icon( Icons.chevron_right_rounded, color: AppColor.white.withOpacity(0.7), size: 20, ), ], ), const SpaceHeight(12), // Value isValueVisible ? Text( value.currencyFormatRp, style: AppStyle.h1.copyWith( color: AppColor.white, fontWeight: FontWeight.w900, fontSize: 26, shadows: [ Shadow( color: Colors.black.withOpacity(0.25), blurRadius: 6, offset: const Offset(0, 2), ), ], ), ) : Text( 'Rp ••••••', style: AppStyle.h1.copyWith( color: AppColor.white, fontWeight: FontWeight.w900, fontSize: 26, letterSpacing: 2, ), ), const SpaceHeight(4), // Subtitle Text( subtitle, style: AppStyle.xs.copyWith( color: AppColor.white.withOpacity(0.7), fontWeight: FontWeight.w400, fontStyle: FontStyle.italic, ), ), const Spacer(), // Mini bar chart _buildMiniBarChart(), ], ), ), ], ), ), ), ); } Widget _buildPercentageBadge() { final isPositive = (percentage ?? 0) >= 0; return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: isPositive ? const Color(0xFF4CAF50).withOpacity(0.25) : const Color(0xFFE53E3E).withOpacity(0.25), borderRadius: BorderRadius.circular(8), border: Border.all( color: isPositive ? const Color(0xFF4CAF50).withOpacity(0.4) : const Color(0xFFE53E3E).withOpacity(0.4), width: 0.5, ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( isPositive ? Icons.trending_up_rounded : Icons.trending_down_rounded, color: isPositive ? const Color(0xFF4CAF50) : const Color(0xFFE53E3E), size: 12, ), const SizedBox(width: 3), Text( '${percentage!.toStringAsFixed(1)}%', style: AppStyle.xs.copyWith( color: isPositive ? const Color(0xFF4CAF50) : const Color(0xFFE53E3E), fontWeight: FontWeight.w700, ), ), ], ), ); } Widget _buildMiniBarChart() { if (dailyData.isEmpty) return const SizedBox.shrink(); final maxVal = dailyData .map((d) => d.totalCost) .fold(0, (a, b) => a > b ? a : b); return SizedBox( height: 28, child: Row( crossAxisAlignment: CrossAxisAlignment.end, children: dailyData.map((d) { final ratio = maxVal > 0 ? d.totalCost / maxVal : 0.0; final isMax = maxVal > 0 && d.totalCost == maxVal; return Expanded( child: Container( margin: const EdgeInsets.symmetric(horizontal: 1.5), height: 6 + (22 * ratio), decoration: BoxDecoration( // Bar tertinggi lebih terang color: isMax ? AppColor.white.withOpacity(0.75) : AppColor.white.withOpacity(0.35), borderRadius: BorderRadius.circular(3), boxShadow: isMax ? [ BoxShadow( color: AppColor.white.withOpacity(0.3), blurRadius: 4, offset: const Offset(0, -2), ), ] : null, ), ), ); }).toList(), ), ); } }