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 '../../../core/widgets/gradient_app_bar.dart'; import '../../../models/connection.dart'; import 'connection_detail_screen.dart'; import 'lab_connections_repository.dart'; class LabConnectionsScreen extends ConsumerStatefulWidget { const LabConnectionsScreen({super.key}); @override ConsumerState createState() => _LabConnectionsScreenState(); } class _LabConnectionsScreenState extends ConsumerState { late Future> _future; final _searchController = TextEditingController(); String _searchQuery = ''; @override void initState() { super.initState(); _load(); } @override void dispose() { _searchController.dispose(); super.dispose(); } void _load() { final tenantId = ref.read(authProvider).activeTenant!.tenant.id; setState(() { _future = LabConnectionsRepository.instance.listConnections(tenantId); }); } Future _respond(String connectionId, bool approve) async { try { await LabConnectionsRepository.instance.respondToRequest( connectionId: connectionId, approve: approve, ); _load(); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( approve ? 'Bağlantı onaylandı' : 'Bağlantı reddedildi'), ), ); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Hata: $e')), ); } } } Color _statusColor(ConnectionStatus status) { return switch (status) { ConnectionStatus.pending => AppColors.pending, ConnectionStatus.approved => AppColors.success, ConnectionStatus.rejected => AppColors.cancelled, }; } Color _statusBg(ConnectionStatus status) { return switch (status) { ConnectionStatus.pending => AppColors.pendingBg, ConnectionStatus.approved => AppColors.successBg, ConnectionStatus.rejected => AppColors.cancelledBg, }; } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.background, appBar: GradientAppBar( title: 'Bağlantılar', category: 'LABORATUVAR', searchController: _searchController, onSearchChanged: (v) => setState(() => _searchQuery = v), searchHint: 'Klinik adı ara...', ), 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 allConnections = snap.data!; final q = _searchQuery.toLowerCase().trim(); final connections = q.isEmpty ? allConnections : allConnections.where((c) => (c.clinicName ?? '').toLowerCase().contains(q)).toList(); if (allConnections.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), const Text( 'Kliniklerden gelen istekler burada görünür.', style: TextStyle( color: AppColors.textSecondary, fontSize: 13), textAlign: TextAlign.center, ), ], ), ); } final pending = connections .where((c) => c.status == ConnectionStatus.pending) .toList(); final others = connections .where((c) => c.status != ConnectionStatus.pending) .toList(); return ListView( padding: const EdgeInsets.fromLTRB(16, 12, 16, 24), children: [ if (pending.isNotEmpty) ...[ _SectionHeader( label: 'Bekleyen İstekler', count: pending.length, countColor: AppColors.pending, countBg: AppColors.pendingBg, ), const SizedBox(height: 8), ...pending.map((c) => Padding( padding: const EdgeInsets.only(bottom: 10), child: _ConnectionCard( connection: c, statusColor: _statusColor(c.status), statusBg: _statusBg(c.status), onApprove: () => _respond(c.id, true), onReject: () => _respond(c.id, false), ), )), const SizedBox(height: 8), ], if (others.isNotEmpty) ...[ _SectionHeader( label: 'Bağlantılar', count: others.length, countColor: AppColors.textSecondary, countBg: AppColors.surfaceVariant, ), const SizedBox(height: 8), ...others.map((c) { final tenantId = ref.read(authProvider).activeTenant!.tenant.id; return Padding( padding: const EdgeInsets.only(bottom: 10), child: _ConnectionCard( connection: c, statusColor: _statusColor(c.status), statusBg: _statusBg(c.status), onTap: c.status == ConnectionStatus.approved ? () => Navigator.push( context, MaterialPageRoute( builder: (_) => ConnectionDetailScreen( connection: c, labTenantId: tenantId, ), ), ) : null, ), ); }), ], ], ); }, ), ), ); } } class _SectionHeader extends StatelessWidget { const _SectionHeader({ required this.label, required this.count, required this.countColor, required this.countBg, }); final String label; final int count; final Color countColor; final Color countBg; @override Widget build(BuildContext context) { return Row( children: [ Text( label, style: const TextStyle( fontSize: 13, fontWeight: FontWeight.w600, color: AppColors.accent, letterSpacing: 0.3, ), ), const SizedBox(width: 8), Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration( color: countBg, borderRadius: BorderRadius.circular(10), ), child: Text( '$count', style: TextStyle( color: countColor, fontSize: 12, fontWeight: FontWeight.w600, ), ), ), ], ); } } class _ConnectionCard extends StatefulWidget { const _ConnectionCard({ required this.connection, required this.statusColor, required this.statusBg, this.onApprove, this.onReject, this.onTap, }); final Connection connection; final Color statusColor; final Color statusBg; final VoidCallback? onApprove; final VoidCallback? onReject; final VoidCallback? onTap; @override State<_ConnectionCard> createState() => _ConnectionCardState(); } class _ConnectionCardState extends State<_ConnectionCard> { bool _loading = false; Future _act(VoidCallback? cb) async { if (cb == null) return; setState(() => _loading = true); cb(); await Future.delayed(const Duration(milliseconds: 500)); if (mounted) setState(() => _loading = false); } String _formatDate(String? raw) { if (raw == null) return ''; try { final dt = DateTime.parse(raw); return '${dt.day.toString().padLeft(2, '0')}.${dt.month.toString().padLeft(2, '0')}.${dt.year}'; } catch (_) { return ''; } } @override Widget build(BuildContext context) { final c = widget.connection; final isPending = c.status == ConnectionStatus.pending; return Material( color: AppColors.surface, borderRadius: BorderRadius.circular(14), child: InkWell( onTap: widget.onTap, borderRadius: BorderRadius.circular(14), child: Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( 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: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( width: 44, height: 44, decoration: BoxDecoration( color: widget.statusBg, borderRadius: BorderRadius.circular(12)), child: Icon(Icons.business_outlined, color: widget.statusColor, size: 22), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( c.clinicName ?? 'Klinik', style: const TextStyle( fontSize: 15, fontWeight: FontWeight.w600, color: AppColors.textPrimary), ), if (c.dateCreated != null) ...[ const SizedBox(height: 2), Text( _formatDate(c.dateCreated), style: const TextStyle( color: AppColors.textMuted, fontSize: 12), ), ], ], ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: widget.statusBg, borderRadius: BorderRadius.circular(8), ), child: Text( c.status.label, style: TextStyle( color: widget.statusColor, fontWeight: FontWeight.w600, fontSize: 12, ), ), ), if (widget.onTap != null) ...[ const SizedBox(width: 4), const Icon(Icons.chevron_right_rounded, size: 18, color: AppColors.textMuted), ], ], ), if (isPending) ...[ const SizedBox(height: 12), Row( children: [ Expanded( child: OutlinedButton( onPressed: _loading ? null : () => _act(widget.onReject), style: OutlinedButton.styleFrom( foregroundColor: AppColors.cancelled, side: const BorderSide(color: AppColors.cancelled)), child: const Text('Reddet'), ), ), const SizedBox(width: 8), Expanded( child: FilledButton( onPressed: _loading ? null : () => _act(widget.onApprove), style: FilledButton.styleFrom( backgroundColor: AppColors.success), child: _loading ? const SizedBox( width: 16, height: 16, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.white), ) : const Text('Onayla'), ), ), ], ), ], ], ), ), ), ); } }