import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/providers/auth_provider.dart'; import '../../../core/theme/app_theme.dart'; import '../../../models/connection.dart'; import 'clinic_connections_repository.dart'; class ClinicConnectionsScreen extends ConsumerStatefulWidget { const ClinicConnectionsScreen({super.key}); @override ConsumerState createState() => _ClinicConnectionsScreenState(); } class _ClinicConnectionsScreenState extends ConsumerState { late Future> _future; @override void initState() { super.initState(); _load(); } void _load() { final tenantId = ref.read(authProvider).activeTenant!.tenant.id; setState(() { _future = ClinicConnectionsRepository.instance .listConnections(tenantId); }); } void _showSearchDialog() { showDialog( context: context, builder: (ctx) => _LabSearchDialog( onRequested: (labId, labName) async { Navigator.of(ctx).pop(); final tenantId = ref.read(authProvider).activeTenant!.tenant.id; try { await ClinicConnectionsRepository.instance.requestConnection( clinicTenantId: tenantId, labTenantId: labId, ); _load(); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( '$labName\'a bağlantı talebi gönderildi.')), ); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Hata: $e')), ); } } }, ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Bağlantılar'), actions: [ IconButton( icon: const Icon(Icons.add_link), tooltip: 'Laboratuvar Bul', onPressed: _showSearchDialog, ), ], ), body: RefreshIndicator( color: AppColors.accent, onRefresh: () async => _load(), child: FutureBuilder>( future: _future, builder: (ctx, snap) { if (snap.connectionState == ConnectionState.waiting) { return const Center( child: CircularProgressIndicator(color: AppColors.accent)); } if (snap.hasError) { return Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( width: 64, height: 64, decoration: BoxDecoration( color: AppColors.cancelledBg, borderRadius: BorderRadius.circular(16)), child: const Icon(Icons.wifi_off_rounded, color: AppColors.cancelled, size: 30), ), const SizedBox(height: 16), Text('Hata: ${snap.error}', style: const TextStyle(color: AppColors.textSecondary)), const SizedBox(height: 12), FilledButton.icon( onPressed: _load, icon: const Icon(Icons.refresh_rounded, size: 18), label: const Text('Tekrar Dene'), ), ], ), ); } final connections = snap.data!; if (connections.isEmpty) { return Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( width: 72, height: 72, decoration: BoxDecoration( color: AppColors.inProgressBg, borderRadius: BorderRadius.circular(20)), child: const Icon(Icons.link_off, color: AppColors.inProgress, size: 32), ), const SizedBox(height: 16), const Text( 'Henüz bağlantı yok', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.textPrimary), ), const SizedBox(height: 8), FilledButton.icon( onPressed: _showSearchDialog, icon: const Icon(Icons.search), label: const Text('Laboratuvar Bul'), ), ], ), ); } return ListView.builder( padding: const EdgeInsets.fromLTRB(16, 12, 16, 24), itemCount: connections.length, itemBuilder: (context, index) { final conn = connections[index]; final statusColor = _statusColor(conn.status); final statusBg = _statusBg(conn.status); return Padding( padding: const EdgeInsets.only(bottom: 10), child: Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(14), border: Border.all(color: AppColors.border), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.04), blurRadius: 8, offset: const Offset(0, 2)) ]), child: Row( children: [ Container( width: 44, height: 44, decoration: BoxDecoration( color: statusBg, borderRadius: BorderRadius.circular(12)), child: Icon(Icons.science_outlined, color: statusColor, size: 22), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( conn.labName ?? 'Laboratuvar', style: const TextStyle( fontSize: 15, fontWeight: FontWeight.w600, color: AppColors.textPrimary), ), if (conn.dateCreated != null) ...[ const SizedBox(height: 2), Text( _formatDate(conn.dateCreated!), style: const TextStyle( fontSize: 12, color: AppColors.textSecondary), ), ], ], ), ), _StatusChip(status: conn.status), ], ), ), ); }, ); }, ), ), floatingActionButton: FloatingActionButton.extended( onPressed: _showSearchDialog, backgroundColor: AppColors.accent, foregroundColor: Colors.white, icon: const Icon(Icons.search), label: const Text('Laboratuvar Bul'), ), ); } Color _statusColor(ConnectionStatus s) { switch (s) { case ConnectionStatus.pending: return AppColors.pending; case ConnectionStatus.approved: return AppColors.success; case ConnectionStatus.rejected: return AppColors.cancelled; } } Color _statusBg(ConnectionStatus s) { switch (s) { case ConnectionStatus.pending: return AppColors.pendingBg; case ConnectionStatus.approved: return AppColors.successBg; case ConnectionStatus.rejected: return AppColors.cancelledBg; } } String _formatDate(String dateStr) { try { final d = DateTime.parse(dateStr); return '${d.day.toString().padLeft(2, '0')}.${d.month.toString().padLeft(2, '0')}.${d.year}'; } catch (_) { return dateStr; } } } class _StatusChip extends StatelessWidget { const _StatusChip({required this.status}); final ConnectionStatus status; @override Widget build(BuildContext context) { final color = _color(status); final bg = _bg(status); return Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: bg, borderRadius: BorderRadius.circular(8), ), child: Text( status.label, style: TextStyle( color: color, fontSize: 12, fontWeight: FontWeight.w600, ), ), ); } Color _color(ConnectionStatus s) { switch (s) { case ConnectionStatus.pending: return AppColors.pending; case ConnectionStatus.approved: return AppColors.success; case ConnectionStatus.rejected: return AppColors.cancelled; } } Color _bg(ConnectionStatus s) { switch (s) { case ConnectionStatus.pending: return AppColors.pendingBg; case ConnectionStatus.approved: return AppColors.successBg; case ConnectionStatus.rejected: return AppColors.cancelledBg; } } } class _LabSearchDialog extends StatefulWidget { const _LabSearchDialog({required this.onRequested}); final void Function(String labId, String labName) onRequested; @override State<_LabSearchDialog> createState() => _LabSearchDialogState(); } class _LabSearchDialogState extends State<_LabSearchDialog> { final _searchController = TextEditingController(); List> _results = []; bool _isLoading = false; bool _searched = false; @override void dispose() { _searchController.dispose(); super.dispose(); } Future _search() async { final query = _searchController.text.trim(); if (query.isEmpty) return; setState(() { _isLoading = true; _searched = true; }); try { final results = await ClinicConnectionsRepository.instance.searchLabs(query); setState(() { _results = results; _isLoading = false; }); } catch (e) { setState(() => _isLoading = false); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Hata: $e')), ); } } } @override Widget build(BuildContext context) { return AlertDialog( title: const Text('Laboratuvar Bul'), content: SizedBox( width: double.maxFinite, child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( children: [ Expanded( child: TextField( controller: _searchController, decoration: const InputDecoration( hintText: 'Lab adı ile arayın...', contentPadding: EdgeInsets.symmetric( horizontal: 12, vertical: 8), ), onSubmitted: (_) => _search(), ), ), const SizedBox(width: 8), FilledButton( onPressed: _search, child: const Text('Ara'), ), ], ), const SizedBox(height: 12), if (_isLoading) const Padding( padding: EdgeInsets.all(16), child: CircularProgressIndicator(color: AppColors.accent), ) else if (_searched && _results.isEmpty) const Padding( padding: EdgeInsets.all(16), child: Text('Sonuç bulunamadı', style: TextStyle(color: AppColors.textSecondary)), ) else if (_results.isNotEmpty) ConstrainedBox( constraints: const BoxConstraints(maxHeight: 240), child: ListView.builder( shrinkWrap: true, itemCount: _results.length, itemBuilder: (context, index) { final lab = _results[index]; final name = lab['company_name'] as String? ?? 'Lab'; return ListTile( dense: true, leading: Container( width: 36, height: 36, decoration: BoxDecoration( color: AppColors.inProgressBg, borderRadius: BorderRadius.circular(8)), child: const Icon(Icons.science_outlined, color: AppColors.inProgress, size: 18), ), title: Text(name, style: const TextStyle( fontWeight: FontWeight.w600, color: AppColors.textPrimary)), subtitle: lab['member_number'] != null ? Text('No: ${lab['member_number']}', style: const TextStyle( color: AppColors.textSecondary)) : null, onTap: () => widget.onRequested(lab['id'] as String, name), ); }, ), ), ], ), ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('İptal'), ), ], ); } }