import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../../core/theme/app_theme.dart'; import '../../../../core/widgets/glass_container.dart'; import '../../../../core/widgets/shimmer_loading.dart'; import '../../../../core/widgets/status_badge.dart'; import '../../../trades/models/trade_model.dart'; import '../../../trades/widgets/trade_execution_cockpit.dart'; import '../../../trades/widgets/trade_closing_cockpit.dart'; import '../../bloc/trades/asset_trades_bloc.dart'; import '../../bloc/trades/asset_trades_event.dart'; import '../../bloc/trades/asset_trades_state.dart'; import '../../widgets/trades/manual_analysis_dialog.dart'; import '../../widgets/trades/asset_trade_item_card.dart'; class TradesTab extends StatefulWidget { final String symbol; const TradesTab({super.key, required this.symbol}); @override State createState() => _TradesTabState(); } class _TradesTabState extends State { bool _justTriggeredAnalysis = false; @override void initState() { super.initState(); context.read().add(LoadAssetTrades(widget.symbol)); } void _showEditTradeExecutionDialog(BuildContext context, TradeModel trade, {bool isActive = false}) { final tradesBloc = context.read(); TradeExecutionCockpit.show( context, trade: trade, defaultSymbol: widget.symbol, isActive: isActive, onAccept: (dto) { tradesBloc.add(AcceptTradeEvent(dto, widget.symbol)); final tId = trade.id; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(isActive ? 'Einstellungen für Trade $tId gespeichert!' : 'Trade $tId angenommen & Position eröffnet!'), backgroundColor: AppTheme.primaryEmerald, behavior: SnackBarBehavior.floating, ), ); }, onReject: (tId) { tradesBloc.add(RejectTradeEvent(tId, widget.symbol)); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Trade $tId abgelehnt.'), backgroundColor: AppTheme.textSecondary, behavior: SnackBarBehavior.floating, ), ); }, ); } @override Widget build(BuildContext context) { return BlocConsumer( listener: (context, state) { if (_justTriggeredAnalysis && state is AssetTradesLoaded) { final List tradesList = state.data; if (tradesList.isNotEmpty) { _justTriggeredAnalysis = false; final latestTrade = tradesList.first; WidgetsBinding.instance.addPostFrameCallback((_) { _showEditTradeExecutionDialog(context, latestTrade); }); } } }, builder: (context, state) { final List tradesList = (state is AssetTradesLoaded) ? state.data : []; return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ GlassContainer( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('Trade & Signal Management', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15, color: Colors.white)), const SizedBox(height: 4), Text('KI-gestützte technische & fundamentale Trade-Analyse anfordern', style: TextStyle(color: AppTheme.textMuted, fontSize: 12), maxLines: 1, overflow: TextOverflow.ellipsis), ], ), ), const SizedBox(width: 8), StatusBadge(label: widget.symbol, color: AppTheme.accentCyan), ], ), const SizedBox(height: 16), SizedBox( width: double.infinity, child: ElevatedButton.icon( onPressed: () { ManualAnalysisDialog.show( context, symbol: widget.symbol, initialRiskScore: 50.0, onTrigger: (payload) { setState(() => _justTriggeredAnalysis = true); context.read().add(TriggerManualAnalysis(widget.symbol, payload: payload)); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('KI-Analyse für ${widget.symbol} abgeschlossen. Trade-Cockpit öffnet sich...'), backgroundColor: AppTheme.accentCyan, behavior: SnackBarBehavior.floating, ), ); }, ); }, icon: const Icon(Icons.auto_awesome, size: 18), label: const Text('KI-Analyse Starten', style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold)), style: ElevatedButton.styleFrom( backgroundColor: AppTheme.accentCyan, foregroundColor: Colors.black, padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), ), ), ], ), ), const SizedBox(height: 20), if (state is AssetTradesLoading) _buildTradesShimmer(context) else if (state is AssetTradesError) GlassContainer( padding: const EdgeInsets.all(16), child: Text('Fehler: ${state.message}', style: TextStyle(color: AppTheme.accentRed)), ) else if (state is AssetTradesLoaded) ...[ _buildTradeList( 'Aktive Trade-Signale & Positionen', tradesList.where((t) { final s = t.status.toUpperCase(); return s == 'ACTIVE' || s == 'PENDING' || s == 'PROPOSED'; }).toList(), ), const SizedBox(height: 20), _buildTradeList( 'Historische Trades & KI-Bewertungen', tradesList.where((t) { final s = t.status.toUpperCase(); return s == 'CLOSED' || s == 'REJECTED' || (s != 'ACTIVE' && s != 'PENDING' && s != 'PROPOSED'); }).toList(), ), ], ], ), ); }, ); } Widget _buildTradesShimmer(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const ShimmerLoading(width: 260, height: 20, borderRadius: 6), const SizedBox(height: 12), for (int i = 0; i < 3; i++) ...[ const ShimmerLoading(width: double.infinity, height: 105, borderRadius: 14), const SizedBox(height: 12), ], ], ); } Widget _buildTradeList(String title, List trades) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white)), const SizedBox(height: 10), if (trades.isEmpty) GlassContainer( padding: const EdgeInsets.all(16), child: Center( child: Text('Keine Trades in dieser Kategorie vorhanden.', style: TextStyle(color: AppTheme.textMuted, fontSize: 12)), ), ) else ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: trades.length, itemBuilder: (context, index) { final trade = trades[index]; final s = trade.status.toUpperCase(); final isActive = s == 'ACTIVE'; return AssetTradeItemCard( trade: trade, defaultSymbol: widget.symbol, onAccept: () => _showEditTradeExecutionDialog(context, trade), onSettings: () => _showEditTradeExecutionDialog(context, trade, isActive: true), onClose: isActive ? () { TradeClosingCockpit.show( context, trade: trade, defaultSymbol: widget.symbol, onClose: (dto) { final isinVal = trade.isin.isNotEmpty ? trade.isin : widget.symbol; context.read().add(CloseTradeEvent(trade.id, isinVal, dto.userExitPrice)); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Trade ${trade.id} geschlossen! Realisierter Ausstiegskurs: €${dto.userExitPrice.toStringAsFixed(2)}'), backgroundColor: AppTheme.primaryEmerald, behavior: SnackBarBehavior.floating, ), ); }, ); } : null, ); }, ), ], ); } }