import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:hive/hive.dart'; import '../models/budget.dart'; import '../models/transaction.dart'; import '../services/hive_service.dart'; import 'create_budget_screen.dart'; class BudgetScreen extends StatefulWidget { const BudgetScreen({super.key}); @override State createState() => _BudgetScreenState(); } class _BudgetScreenState extends State { late HiveService _hiveService; List> _budgetEntries = []; BudgetPeriod _selectedPeriodFilter = BudgetPeriod.month; @override void initState() { super.initState(); _hiveService = HiveService(); _loadBudgets(); } Future _loadBudgets() async { final box = Hive.box(HiveService.budgetsBox); final entries = box.toMap().entries.map((e) => MapEntry(e.key as int, e.value)).toList(); if (mounted) { setState(() { _budgetEntries = entries; }); } } Future _deleteBudget(int key) async { await _hiveService.deleteBudget(key); _loadBudgets(); } String _getCategoryName(TransactionCategory category) { return { TransactionCategory.food: 'Comida', TransactionCategory.transport: 'Transporte', TransactionCategory.social: 'Social', TransactionCategory.education: 'Educação', TransactionCategory.medical: 'Médico', TransactionCategory.shopping: 'Compras', TransactionCategory.salary: 'Salário', TransactionCategory.invest: 'Investir', TransactionCategory.business: 'Negócios', TransactionCategory.others: 'Outros', TransactionCategory.house: 'Casa', TransactionCategory.utilities: 'Utilidades', TransactionCategory.subscriptions: 'Assinaturas', TransactionCategory.leisure: 'Lazer', TransactionCategory.gym: 'Academia', TransactionCategory.gifts: 'Presentes', TransactionCategory.pets: 'Animais', TransactionCategory.freelance: 'Freelance', TransactionCategory.dividends: 'Dividendos', TransactionCategory.loan: 'Empréstimo', TransactionCategory.refund: 'Reembolso', TransactionCategory.tax: 'Imposto', TransactionCategory.bonus: 'Bônus', TransactionCategory.allowance: 'Mesada', }[category] ?? 'Desconhecido'; } IconData _getCategoryIcon(TransactionCategory category) { switch (category) { case TransactionCategory.food: return Icons.fastfood; case TransactionCategory.transport: return Icons.directions_car; case TransactionCategory.social: return Icons.group; case TransactionCategory.education: return Icons.school; case TransactionCategory.medical: return Icons.medical_services; case TransactionCategory.shopping: return Icons.shopping_bag; case TransactionCategory.salary: return Icons.attach_money; case TransactionCategory.invest: return Icons.trending_up; case TransactionCategory.business: return Icons.business_center; case TransactionCategory.others: return Icons.category; case TransactionCategory.house: return Icons.home; case TransactionCategory.utilities: return Icons.lightbulb; case TransactionCategory.subscriptions: return Icons.subscriptions; case TransactionCategory.leisure: return Icons.movie; case TransactionCategory.gym: return Icons.fitness_center; case TransactionCategory.gifts: return Icons.card_giftcard; case TransactionCategory.pets: return Icons.pets; case TransactionCategory.freelance: return Icons.work; case TransactionCategory.dividends: return Icons.monetization_on; case TransactionCategory.loan: return Icons.account_balance; case TransactionCategory.refund: return Icons.reply; case TransactionCategory.tax: return Icons.account_balance_wallet; case TransactionCategory.bonus: return Icons.star; case TransactionCategory.allowance: return Icons.money; default: return Icons.help; } } String _getPeriodName(BudgetPeriod period) { switch (period) { case BudgetPeriod.week: return 'Semana'; case BudgetPeriod.month: return 'Mês'; case BudgetPeriod.quarter: return 'Trimestre'; case BudgetPeriod.year: return 'Ano'; } } @override Widget build(BuildContext context) { final filteredEntries = _budgetEntries.where((e) => e.value.period == _selectedPeriodFilter).toList(); final List isSelected = BudgetPeriod.values.map((period) => period == _selectedPeriodFilter).toList(); return Scaffold( extendBodyBehindAppBar: true, appBar: AppBar( title: const Text( 'Orçamentos', style: TextStyle( fontWeight: FontWeight.bold, color: Color.fromARGB(255, 15, 16, 24), shadows: [ Shadow( blurRadius: 10.0, color: Color.fromARGB(137, 0, 76, 253), offset: Offset(0, 0), ), ], ), ), centerTitle: true, ), body: Container( decoration: const BoxDecoration( gradient: LinearGradient( colors: [ Color(0xFF0A0A16), Color(0xFF0F0F23), ], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), ), child: Column( children: [ Padding( padding: const EdgeInsets.fromLTRB(16.0, 100.0, 16.0, 8.0), child: ClipRRect( borderRadius: BorderRadius.circular(16), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), child: Container( padding: const EdgeInsets.all(4.0), decoration: BoxDecoration( color: Colors.white.withOpacity(0.05), borderRadius: BorderRadius.circular(16), border: Border.all(color: Colors.white.withOpacity(0.1)), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: BudgetPeriod.values.asMap().entries.map((entry) { int index = entry.key; BudgetPeriod period = entry.value; bool selected = isSelected[index]; return Expanded( child: InkWell( onTap: () { setState(() { _selectedPeriodFilter = period; }); }, child: AnimatedContainer( duration: const Duration(milliseconds: 300), alignment: Alignment.center, padding: const EdgeInsets.symmetric(vertical: 12.0), decoration: BoxDecoration( gradient: selected ? const LinearGradient( colors: [Color(0xFF4B77BE), Color(0xFF2E5894)], begin: Alignment.topLeft, end: Alignment.bottomRight, ) : null, color: selected ? null : Colors.transparent, borderRadius: BorderRadius.circular(12), border: selected ? Border.all(color: Colors.blue.shade200) : null, ), child: Text( _getPeriodName(period), style: TextStyle( color: selected ? Colors.white : Colors.white70, fontWeight: FontWeight.bold, fontSize: 14, ), ), ), ), ); }).toList(), ), ), ), ), ), Expanded( child: filteredEntries.isEmpty ? Center( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.data_usage_outlined, size: 120, color: Colors.blueGrey), const SizedBox(height: 20), const Text( 'Nenhum orçamento para este período.', textAlign: TextAlign.center, style: TextStyle(fontSize: 18, color: Colors.white, fontWeight: FontWeight.w500), ), const SizedBox(height: 10), const Text( 'Crie um orçamento e comece a controlar seus gastos!', textAlign: TextAlign.center, style: TextStyle(color: Colors.grey, fontSize: 15), ), ], ), ), ) : ListView.builder( itemCount: filteredEntries.length, itemBuilder: (context, index) { final entry = filteredEntries[index]; final budget = entry.value; final key = entry.key; return Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: ClipRRect( borderRadius: BorderRadius.circular(15), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), child: Container( padding: const EdgeInsets.all(20.0), decoration: BoxDecoration( color: Colors.white.withOpacity(0.05), borderRadius: BorderRadius.circular(15), border: Border.all(color: Colors.white.withOpacity(0.1)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.white.withOpacity(0.1), shape: BoxShape.circle, ), child: Icon(_getCategoryIcon(budget.category), color: Colors.blue[300]), ), const SizedBox(width: 12), Text( _getCategoryName(budget.category), style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white), ), ], ), IconButton( icon: const Icon(Icons.delete_outline, color: Colors.redAccent, size: 24), onPressed: () async { bool? confirm = await showDialog( context: context, builder: (BuildContext context) { return AlertDialog( backgroundColor: const Color(0xFF1A1A2E), title: const Text('Confirmar Exclusão', style: TextStyle(color: Colors.white)), content: const Text('Tem certeza que deseja excluir este orçamento?', style: TextStyle(color: Colors.white70)), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: const Text('Cancelar', style: TextStyle(color: Colors.white54)), ), TextButton( onPressed: () => Navigator.of(context).pop(true), child: const Text('Excluir', style: TextStyle(color: Colors.red)), ), ], ); }, ); if (confirm == true) { await _deleteBudget(key); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Orçamento excluído com sucesso!'), backgroundColor: Colors.green, ), ); } } }, ), ], ), const SizedBox(height: 15), Text( 'Período: ${_getPeriodName(budget.period)}', style: TextStyle(fontSize: 14, color: Colors.white54), ), Text( 'De ${DateFormat('dd/MM/yyyy').format(budget.startDate)} a ${DateFormat('dd/MM/yyyy').format(budget.endDate)}', style: TextStyle(fontSize: 14, color: Colors.white54), ), const SizedBox(height: 20), ClipRRect( borderRadius: BorderRadius.circular(10), child: LinearProgressIndicator( value: 0.0, // Placeholder backgroundColor: Colors.white.withOpacity(0.1), color: Colors.cyan, minHeight: 12, ), ), const SizedBox(height: 10), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Orçado: ${NumberFormat.currency(locale: 'pt_BR', symbol: 'KZ').format(budget.amount)}', style: const TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: Colors.white), ), ], ), const SizedBox(height: 15), if (budget.note != null && budget.note!.isNotEmpty) Text( 'Nota: ${budget.note}', style: const TextStyle(fontSize: 14, color: Colors.white38, fontStyle: FontStyle.italic), ), ], ), ), ), ), ); }, ), ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: () async { final result = await Navigator.push( context, MaterialPageRoute(builder: (context) => const CreateBudgetScreen()), ); if (result == true) { _loadBudgets(); } }, tooltip: 'Adicionar Orçamento', shape: const CircleBorder(), child: Container( width: 60, height: 60, decoration: BoxDecoration( shape: BoxShape.circle, gradient: const LinearGradient( colors: [Color(0xFF4B77BE), Color(0xFF2E5894)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), boxShadow: [ BoxShadow( color: const Color(0xFF4B77BE).withOpacity(0.5), blurRadius: 10, offset: const Offset(0, 5), ), ], ), child: const Icon(Icons.add, color: Colors.white, size: 28), ), ), floatingActionButtonLocation: FloatingActionButtonLocation.endFloat, ); } }