import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; import '../../../database/database.dart'; import '../../../providers/auth_provider.dart'; import '../../../providers/database_provider.dart'; import '../../../providers/customer_provider.dart'; import '../../../database/tables/clienti.dart'; import '../../../database/tables/filiali.dart'; import '../../../database/tables/scadenze.dart'; import '../../../core/responsive.dart'; class CustomerDetailPage extends ConsumerWidget { final int id; const CustomerDetailPage({super.key, required this.id}); @override Widget build(BuildContext context, WidgetRef ref) { final clientiDao = ref.read(clientiDaoProvider); final clienteAsync = clientiDao.getById(id); final theme = Theme.of(context); return DefaultTabController( length: 4, child: Scaffold( appBar: AppBar( title: FutureBuilder( future: clienteAsync, builder: (_, snap) => Text(snap.data?.ragioneSociale ?? 'Cliente'), ), bottom: const TabBar( tabs: [ Tab(text: 'Info', icon: Icon(Icons.info_outline)), Tab(text: 'Ordini', icon: Icon(Icons.receipt_long_outlined)), Tab(text: 'Destinazioni', icon: Icon(Icons.location_on_outlined)), Tab( text: 'Scadenze', icon: Icon(Icons.account_balance_wallet_outlined), ), ], ), ), body: FutureBuilder( future: clienteAsync, builder: (_, snap) { final cliente = snap.data; if (cliente == null) return const Center(child: CircularProgressIndicator()); return TabBarView( children: [ _InfoTab(cliente: cliente, theme: theme), _OrdersTab(idCliente: id, theme: theme), _DestinationsTab(idCliente: id, theme: theme), _PaymentsTab( idCliente: cliente.idClienteRemoto ?? 0, theme: theme, ), ], ); }, ), ), ); } } class _InfoTab extends StatelessWidget { final Cliente cliente; final ThemeData theme; const _InfoTab({required this.cliente, required this.theme}); @override Widget build(BuildContext context) { return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _infoRow('Codice', cliente.codCliente ?? '-'), _infoRow('Ragione Sociale', cliente.ragioneSociale ?? '-'), _infoRow('Indirizzo', cliente.indirizzo ?? '-'), _infoRow( 'Città', '${cliente.citta ?? ""} ${cliente.provincia ?? ""} ${cliente.cap ?? ""}', ), _infoRow('Telefono', cliente.telefono ?? '-'), _infoRow('Cellulare', cliente.cellulare ?? '-'), _infoRow('Email', cliente.email ?? '-'), _infoRow('Partita IVA', cliente.partitaIva ?? '-'), _infoRow('Codice Fiscale', cliente.codiceFiscale ?? '-'), if (cliente.sdi != null && cliente.sdi!.isNotEmpty) _infoRow('SDI', cliente.sdi!), if (cliente.pec != null && cliente.pec!.isNotEmpty) _infoRow('PEC', cliente.pec!), if (cliente.note != null && cliente.note!.isNotEmpty) _infoRow('Note', cliente.note!), if (cliente.codBlocco != null && cliente.codBlocco!.isNotEmpty) Card( color: Colors.red.shade50, child: Padding( padding: const EdgeInsets.all(12), child: Row( children: [ Icon(Icons.block, color: Colors.red), const SizedBox(width: 8), Text('Blocco: ${cliente.codBlocco}'), ], ), ), ), ], ), ); } Widget _infoRow(String label, String value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 120, child: Text( label, style: theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.outline, ), ), ), Expanded(child: Text(value)), ], ), ); } } class _OrdersTab extends ConsumerWidget { final int idCliente; final ThemeData theme; const _OrdersTab({required this.idCliente, required this.theme}); @override Widget build(BuildContext context, WidgetRef ref) { final ordiniDao = ref.read(ordiniDaoProvider); return Scaffold( body: FutureBuilder( future: ordiniDao.customerOrders(idCliente, false), builder: (_, snap) { if (!snap.hasData) return const Center(child: CircularProgressIndicator()); final orders = snap.data!; if (orders.isEmpty) return const Center(child: Text('Nessun ordine')); return ListView.builder( itemCount: orders.length, itemBuilder: (_, i) => ListTile( title: Text('Ordine #${orders[i].numeroOrdine ?? ""}'), subtitle: Text(orders[i].dataOrdine ?? ''), onTap: () => context.push('/dashboard/orders/${orders[i].idOrdine}'), ), ); }, ), floatingActionButton: FloatingActionButton( heroTag: 'addOrder', child: const Icon(Icons.add), onPressed: () => context.push('/dashboard/orders/new?cliente=$idCliente'), ), ); } } class _DestinationsTab extends ConsumerWidget { final int idCliente; final ThemeData theme; const _DestinationsTab({required this.idCliente, required this.theme}); @override Widget build(BuildContext context, WidgetRef ref) { final destsAsync = ref.watch(customerDestinationsProvider(idCliente)); return destsAsync.when( data: (dests) { if (dests.isEmpty) return const Center(child: Text('Nessuna destinazione')); return ListView.builder( itemCount: dests.length, itemBuilder: (_, i) => ListTile( leading: const Icon(Icons.location_on_outlined), title: Text(dests[i].descrizione ?? ''), subtitle: Text( '${dests[i].indirizzo ?? ""} ${dests[i].citta ?? ""}', ), ), ); }, loading: () => const Center(child: CircularProgressIndicator()), error: (e, _) => Center(child: Text('Errore: $e')), ); } } class _PaymentsTab extends ConsumerWidget { final int idCliente; final ThemeData theme; const _PaymentsTab({required this.idCliente, required this.theme}); @override Widget build(BuildContext context, WidgetRef ref) { final paysAsync = ref.watch(customerPaymentsProvider(idCliente)); return paysAsync.when( data: (pays) { if (pays.isEmpty) return const Center(child: Text('Nessuna scadenza')); return ListView.builder( padding: const EdgeInsets.all(8), itemCount: pays.length, itemBuilder: (_, i) { final p = pays[i]; return Card( margin: const EdgeInsets.symmetric(vertical: 4), child: Padding( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _row('Fattura N.', p.numDoc ?? '-'), _row('Data fatt.', _formatDate(p.dataDoc)), _row('Data scad', _formatDate(p.dataScadenza)), _row('Totale fattura', _formatAmount(p.importoFattura)), _row('Totale scad.', _formatAmount(p.importoScadenza)), _row('Saldo', _formatAmount(p.saldo)), ], ), ), ); }, ); }, loading: () => const Center(child: CircularProgressIndicator()), error: (e, _) => Center(child: Text('Errore: $e')), ); } String _formatDate(String? dateStr) { if (dateStr == null) return '-'; try { final dt = DateTime.parse(dateStr); return DateFormat('dd/MM/yyyy').format(dt); } catch (_) { return dateStr; } } String _formatAmount(double? amount) { if (amount == null) return '-'; final fmt = NumberFormat('#,##0.00', 'it'); return '€ ${fmt.format(amount)}'; } Widget _row(String label, String value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 2), child: Row( children: [ SizedBox( width: 110, child: Text( label, style: theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.outline, ), ), ), Expanded( child: Text(value, style: theme.textTheme.bodyMedium), ), ], ), ); } }