import 'package:flutter/material.dart'; import 'package:kmobile/api/services/cheque_service.dart'; import 'package:kmobile/data/models/user.dart'; import 'package:kmobile/di/injection.dart'; class ChequeStatusScreen extends StatefulWidget { final List users; final int selectedIndex; const ChequeStatusScreen({ super.key, required this.users, required this.selectedIndex, }); @override State createState() => _ChequeStatusScreenState(); } class _ChequeStatusScreenState extends State { User? _selectedAccount; final TextEditingController _searchController = TextEditingController(); var service = getIt(); bool _isLoading = true; List _allCheques = []; Map> _groupedCheques = {}; @override void initState() { super.initState(); final List _filteredUsers = widget.users .where((user) => ['SA', 'SB', 'CA', 'CC'].contains(user.accountType)) .toList(); if (widget.users.isNotEmpty && widget.selectedIndex < widget.users.length) { if (_filteredUsers.isNotEmpty) { if (_filteredUsers.contains(widget.users[widget.selectedIndex])) { _selectedAccount = widget.users[widget.selectedIndex]; } else { _selectedAccount = _filteredUsers.first; } } else { _selectedAccount = widget.users[widget.selectedIndex]; } } else { if (_filteredUsers.isNotEmpty) { _selectedAccount = _filteredUsers.first; } } _loadCheques(); _searchController.addListener(() { _filterCheques(_searchController.text); }); } Future _loadCheques() async { if (_selectedAccount == null) { setState(() { _isLoading = false; _groupedCheques = {}; }); return; } setState(() { _isLoading = true; }); String instrType; switch (_selectedAccount!.accountType) { case 'SA': case 'SB': instrType = '10'; break; case 'CA': instrType = '11'; break; case 'CC': instrType = '13'; break; default: instrType = '10'; } try { final data = await service.ChequeEnquiry( accountNumber: _selectedAccount!.accountNo!, instrType: instrType); _allCheques = data; _groupedCheques.clear(); for (var cheque in _allCheques) { if (cheque.type != null) { if (!_groupedCheques.containsKey(cheque.type)) { _groupedCheques[cheque.type!] = []; } _groupedCheques[cheque.type!]!.add(cheque); } } setState(() { _isLoading = false; }); } catch (e) { setState(() { _isLoading = false; _groupedCheques = {}; }); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Failed to fetch cheque status: ${e.toString()}'), ), ); } } void _filterCheques(String query) { _groupedCheques.clear(); List filteredCheques; if (query.isEmpty) { filteredCheques = _allCheques; } else { filteredCheques = _allCheques.where((cheque) { final lowerQuery = query.toLowerCase(); return (cheque.ChequeNumber?.toLowerCase().contains(lowerQuery) ?? false) || (cheque.amount?.toLowerCase().contains(lowerQuery) ?? false) || (cheque.status?.toLowerCase().contains(lowerQuery) ?? false) || (cheque.fromCheque?.toLowerCase().contains(lowerQuery) ?? false) || (cheque.toCheque?.toLowerCase().contains(lowerQuery) ?? false); }).toList(); } for (var cheque in filteredCheques) { if (cheque.type != null) { if (!_groupedCheques.containsKey(cheque.type)) { _groupedCheques[cheque.type!] = []; } _groupedCheques[cheque.type!]!.add(cheque); } } setState(() {}); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Track Cheque Status'), centerTitle: false, ), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ Card( elevation: 4, margin: const EdgeInsets.symmetric(vertical: 8.0), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( "Account Number", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18), ), if (_selectedAccount != null) DropdownButtonFormField( value: _selectedAccount, onChanged: (User? newUser) { if (newUser != null) { setState(() { _selectedAccount = newUser; _loadCheques(); }); } }, items: widget.users .where((user) => ['SA', 'SB', 'CA', 'CC'].contains(user.accountType)) .map((user) { return DropdownMenuItem( value: user, child: Text(user.accountNo.toString()), ); }).toList(), ) else const Text('No accounts found'), ], ), ), ), const SizedBox(height: 20), TextField( controller: _searchController, decoration: const InputDecoration( labelText: 'Search...', prefixIcon: Icon(Icons.search), ), ), const SizedBox(height: 20), Expanded( child: _isLoading ? const Center(child: CircularProgressIndicator()) : _groupedCheques.isEmpty ? const Center(child: Text('No cheque status found.')) : ListView( children: _groupedCheques.entries.map((entry) { return ExpansionTile( title: Text(entry.key, style: TextStyle(fontWeight: FontWeight.bold)), children: entry.value .map((cheque) => ChequeStatusTile(cheque: cheque)) .toList(), ); }).toList(), ), ), ], ), ), ); } } class ChequeStatusTile extends StatelessWidget { final Cheque cheque; const ChequeStatusTile({ super.key, required this.cheque, }); @override Widget build(BuildContext context) { switch (cheque.type) { case 'CI': return _buildCiTile(context); case 'PR': return _buildPrTile(context); case 'ST': return _buildStTile(context); default: return const SizedBox.shrink(); } } Widget _buildCiTile(BuildContext context) { return Card( margin: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildInfoRow('Branch Code:', cheque.branchCode), _buildInfoRow('From Cheque:', cheque.fromCheque), _buildInfoRow('To Cheque:', cheque.toCheque), _buildInfoRow('Date:', cheque.Date), _buildInfoRow('Cheques Count:', cheque.Chequescount), _buildInfoRow('Instrument Type:', cheque.InstrType), ], ), ), ); } Widget _buildPrTile(BuildContext context) { return Card( margin: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildInfoRow('Branch Code:', cheque.branchCode), _buildInfoRow('Cheque Number:', cheque.ChequeNumber), _buildInfoRow('Date:', cheque.Date), _buildInfoRow('Transaction Code:', cheque.transactionCode), _buildInfoRow('Amount:', cheque.amount), _buildInfoRow('Status:', cheque.status, statusColor: _getStatusColor(cheque.status ?? '')), _buildInfoRow('Instrument Type:', cheque.InstrType), ], ), ), ); } Widget _buildStTile(BuildContext context) { return Card( margin: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildInfoRow('Branch Code:', cheque.branchCode), _buildInfoRow('From Cheque:', cheque.fromCheque), _buildInfoRow('To Cheque:', cheque.toCheque), _buildInfoRow('Stop Issue Date:', cheque.stopIssueDate), _buildInfoRow('Stop Expiry Date:', cheque.StopExpiryDate), _buildInfoRow('Cheques Count:', cheque.Chequescount), _buildInfoRow('Instrument Type:', cheque.InstrType), ], ), ), ); } Widget _buildInfoRow(String label, String? value, {Color? statusColor}) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(label, style: const TextStyle(fontWeight: FontWeight.bold)), Text(value ?? '', style: TextStyle(color: statusColor)), ], ), ); } Color _getStatusColor(String status) { switch (status.toLowerCase()) { case 'cashed': return Colors.green; case 'pending': return Colors.orange; case 'bounced': return Colors.red; default: return Colors.grey; } } }