import 'package:flutter/material.dart'; import '../../../../core/theme/app_theme.dart'; import '../models/trade_model.dart'; import 'trade_calculation_card.dart'; class TradeDetailContent extends StatelessWidget { final TradeModel trade; const TradeDetailContent({super.key, required this.trade}); @override Widget build(BuildContext context) { final pnlAbs = trade.calculatedPnlAbs; final pnlPct = trade.calculatedPnlPct; final isPnlPos = pnlAbs >= 0; final pnlColor = isPnlPos ? AppTheme.primaryEmerald : AppTheme.accentRed; final currPrice = trade.effectiveCurrentPrice; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Drift Radar Status if (trade.isActive) ...[ _buildDriftRadarCard(trade), const SizedBox(height: 14), ], // Exit Alert if pending if (trade.isActive && trade.hasPendingExitAlert) ...[ Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: AppTheme.accentRed.withValues(alpha: 0.15), borderRadius: BorderRadius.circular(12), border: Border.all(color: AppTheme.accentRed.withValues(alpha: 0.5)), ), child: Row( children: [ Icon(Icons.warning_amber_rounded, color: AppTheme.accentRed, size: 24), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Ausstiegs-Empfehlung der KI!', style: TextStyle(color: AppTheme.accentRed, fontWeight: FontWeight.bold, fontSize: 13)), const SizedBox(height: 2), Text( trade.pendingExitReason.isNotEmpty ? trade.pendingExitReason : 'Die Indikatoren raten zum Verlassen der Position zur Gewinnsicherung / Risikominimierung.', style: const TextStyle(color: Colors.white70, fontSize: 12), ), ], ), ), ], ), ), const SizedBox(height: 14), ], // Metrics Grid Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.black.withValues(alpha: 0.3), borderRadius: BorderRadius.circular(14), border: Border.all(color: Colors.white.withValues(alpha: 0.08)), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _metricItem( trade.isActive || trade.isClosed ? 'Ausführung' : 'Ziel-Einstieg', trade.actualEntryPrice > 0 ? '€${trade.actualEntryPrice.toStringAsFixed(2)}' : (trade.entryPrice > 0 ? '€${trade.entryPrice.toStringAsFixed(2)}' : '-'), Colors.white, ), _metricItem('Live-Kurs', '€${currPrice.toStringAsFixed(2)}', AppTheme.accentCyan), _metricItem( trade.driftStatus == DriftStatus.trailingActive ? 'Stop (Trailing)' : 'Stop-Loss', '€${trade.stopLoss.toStringAsFixed(2)}', AppTheme.accentRed, ), _metricItem( trade.takeProfitTargets.length > 1 ? 'TP (Aktuell)' : 'Take-Profit', '€${trade.takeProfit.toStringAsFixed(2)}', AppTheme.primaryEmerald, ), ], ), ), if (trade.takeProfitTargets.length > 1) ...[ const SizedBox(height: 10), Row( children: [ Text( 'Alle Gewinn-Ziele: ', style: TextStyle(color: AppTheme.textMuted, fontSize: 12, fontWeight: FontWeight.bold), ), Expanded( child: Wrap( spacing: 6, runSpacing: 4, children: trade.takeProfitTargets.asMap().entries.map((entry) { final idx = entry.key; final tpVal = entry.value; final isCurrent = (trade.takeProfit - tpVal).abs() < 0.01; return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( color: isCurrent ? AppTheme.primaryEmerald.withValues(alpha: 0.2) : Colors.white.withValues(alpha: 0.05), borderRadius: BorderRadius.circular(6), border: Border.all( color: isCurrent ? AppTheme.primaryEmerald : Colors.white.withValues(alpha: 0.15), ), ), child: Text( 'TP${idx + 1}: €${tpVal.toStringAsFixed(2)}', style: TextStyle( color: isCurrent ? AppTheme.primaryEmerald : Colors.white70, fontSize: 11, fontWeight: isCurrent ? FontWeight.w900 : FontWeight.bold, ), ), ); }).toList(), ), ), ], ), ], if (trade.isActive || trade.isClosed) ...[ const SizedBox(height: 14), Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( color: pnlColor.withValues(alpha: 0.12), borderRadius: BorderRadius.circular(12), border: Border.all(color: pnlColor.withValues(alpha: 0.3)), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text('Aktueller PnL:', style: TextStyle(color: Colors.white70, fontSize: 13)), Text( '${isPnlPos ? '+' : ''}€${pnlAbs.abs().toStringAsFixed(2)} (${isPnlPos ? '+' : ''}${pnlPct.toStringAsFixed(2)}%)', style: TextStyle(color: pnlColor, fontWeight: FontWeight.bold, fontSize: 15), ), ], ), ), ], const SizedBox(height: 20), // 3. LIVE-KALKULATION (AUTOMATISCH) & MEHRSTUFIGE TP-ZIELE TradeCalculationCard(trade: trade), const SizedBox(height: 18), // Trade Parameters & Instrument _sectionTitle(Icons.tune, 'Trade-Parameter & Instrument', Colors.white70), const SizedBox(height: 8), Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.02), borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.white.withValues(alpha: 0.06)), ), child: Column( children: [ _paramRow('Instrument Typ:', trade.instrumentType.isNotEmpty ? trade.instrumentType : 'Stock'), if (trade.derivativeIsin.isNotEmpty) _paramRow('Derivat / Hebel ISIN:', trade.derivativeIsin), _paramRow('Zeithorizont:', trade.timeframe.isNotEmpty ? trade.timeframe : '1D'), if (trade.leverageUsed > 1) _paramRow('Hebel:', '${trade.leverageUsed.toStringAsFixed(1)}x'), if (trade.positionSize > 0) _paramRow('Positionsgröße:', '€${trade.positionSize.toStringAsFixed(2)}'), ], ), ), const SizedBox(height: 18), // AUFKLAPPBARE KARTE: KI-Analysen, Bewertungen & Begründungen Container( decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.03), borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.white.withValues(alpha: 0.08)), ), child: Theme( data: ThemeData(dividerColor: Colors.transparent), child: ExpansionTile( initiallyExpanded: false, tilePadding: const EdgeInsets.symmetric(horizontal: 14, vertical: 4), childrenPadding: const EdgeInsets.fromLTRB(14, 0, 14, 14), iconColor: AppTheme.accentCyan, collapsedIconColor: Colors.white70, leading: Icon(Icons.auto_awesome, color: AppTheme.primaryEmerald, size: 20), title: const Text( 'KI-Analysen, Bewertungen & Begründungen', style: TextStyle(color: Colors.white, fontSize: 13, fontWeight: FontWeight.bold), ), subtitle: Text( 'Technische & fundamentale Begründung, Risikowarnung & Guardian-Protokoll', style: TextStyle(color: AppTheme.textMuted, fontSize: 11), ), children: [ const Divider(color: Colors.white10, height: 16), // Hourly Updates Timeline if (trade.hourlyUpdates.isNotEmpty) ...[ _sectionTitle(Icons.history_toggle_off, 'KI-Guardian Überwachungsprotokoll (${trade.hourlyUpdates.length} Checks)', AppTheme.accentCyan), const SizedBox(height: 8), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.black.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(10), border: Border.all(color: Colors.white.withValues(alpha: 0.06)), ), child: Column( children: trade.hourlyUpdates.reversed.map((u) { return Padding( padding: const EdgeInsets.only(bottom: 8), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '${u.timestamp.day.toString().padLeft(2, '0')}.${u.timestamp.month.toString().padLeft(2, '0')} ${u.timestamp.hour.toString().padLeft(2, '0')}:${u.timestamp.minute.toString().padLeft(2, '0')}', style: TextStyle(color: AppTheme.textMuted, fontSize: 11, fontWeight: FontWeight.bold), ), const SizedBox(width: 10), Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( color: (u.recommendation.toLowerCase().contains('close') ? AppTheme.accentRed : (u.recommendation.toLowerCase().contains('adjust') ? Colors.blue : AppTheme.primaryEmerald)) .withValues(alpha: 0.2), borderRadius: BorderRadius.circular(4), ), child: Text(u.recommendation, style: const TextStyle(color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold)), ), const SizedBox(width: 10), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( u.reasoning.isNotEmpty ? u.reasoning : 'Stündliche Überprüfung durchgeführt.', style: const TextStyle(color: Colors.white70, fontSize: 12), ), Text( 'Kurs: €${u.currentPrice.toStringAsFixed(2)}${u.suggestedStopLoss != null ? " • Neuer SL: €${u.suggestedStopLoss!.toStringAsFixed(2)}" : ""} • VIX: ${u.vixValue.toStringAsFixed(1)}', style: TextStyle(color: AppTheme.textMuted, fontSize: 11), ), ], ), ), ], ), ); }).toList(), ), ), const SizedBox(height: 14), ], if (trade.reasoning.isNotEmpty) ...[ _sectionTitle(Icons.auto_awesome, 'KI-Gesamteinschätzung & Begründung', AppTheme.primaryEmerald), const SizedBox(height: 8), Container( width: double.infinity, padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppTheme.primaryEmerald.withValues(alpha: 0.08), borderRadius: BorderRadius.circular(10), border: Border.all(color: AppTheme.primaryEmerald.withValues(alpha: 0.2)), ), child: Text(trade.reasoning, style: const TextStyle(color: Colors.white, fontSize: 13, height: 1.4)), ), const SizedBox(height: 14), ], if (trade.technicalRationale.isNotEmpty) ...[ _sectionTitle(Icons.show_chart, 'Technische Analyse & Indikatoren', AppTheme.accentCyan), const SizedBox(height: 8), Container( width: double.infinity, padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.03), borderRadius: BorderRadius.circular(10), border: Border.all(color: Colors.white.withValues(alpha: 0.08)), ), child: Text(trade.technicalRationale, style: TextStyle(color: AppTheme.textMuted, fontSize: 12.5, height: 1.4)), ), const SizedBox(height: 14), ], if (trade.fundamentalRationale.isNotEmpty) ...[ _sectionTitle(Icons.account_balance, 'Fundamentale Bewertung', Colors.purpleAccent), const SizedBox(height: 8), Container( width: double.infinity, padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.03), borderRadius: BorderRadius.circular(10), border: Border.all(color: Colors.white.withValues(alpha: 0.08)), ), child: Text(trade.fundamentalRationale, style: TextStyle(color: AppTheme.textMuted, fontSize: 12.5, height: 1.4)), ), const SizedBox(height: 14), ], if (trade.riskWarning.isNotEmpty) ...[ _sectionTitle(Icons.warning_amber_rounded, 'Risikohinweis & Marktumfeld', AppTheme.accentRed), const SizedBox(height: 8), Container( width: double.infinity, padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppTheme.accentRed.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(10), border: Border.all(color: AppTheme.accentRed.withValues(alpha: 0.3)), ), child: Text(trade.riskWarning, style: TextStyle(color: AppTheme.accentRed, fontSize: 12, height: 1.4)), ), ], ], ), ), ), ], ); } Widget _buildDriftRadarCard(TradeModel t) { Color col; String title; String desc; switch (t.driftStatus) { case DriftStatus.exitAlert: col = AppTheme.accentRed; title = 'Ausstiegssignal aktiv'; desc = 'Die Marktbedingungen oder Stop-Limits deuten auf einen Ausstieg hin.'; break; case DriftStatus.trailingActive: col = AppTheme.accentCyan; title = 'Trailing Stop aktiv nachgezogen'; desc = 'Die KI hat den Stop-Loss zur Absicherung von Gewinnen nachgezogen.'; break; case DriftStatus.driftWarning: col = Colors.orangeAccent; title = 'Leichte Drift / Kursabweichung'; desc = 'Der Kurs bewegt sich leicht entgegen der primären Prognose.'; break; case DriftStatus.onTrack: col = AppTheme.primaryEmerald; title = 'Auf Kurs • Prognose intakt'; desc = 'Die Entwicklung entspricht der statistischen KI-Prognose.'; break; } return Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: col.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(12), border: Border.all(color: col.withValues(alpha: 0.4)), ), child: Row( children: [ Icon(Icons.radar, color: col, size: 22), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Drift-Radar: $title', style: TextStyle(color: col, fontWeight: FontWeight.bold, fontSize: 13)), Text(desc, style: TextStyle(color: AppTheme.textMuted, fontSize: 11)), ], ), ), ], ), ); } Widget _sectionTitle(IconData icon, String title, Color color) { return Row( children: [ Icon(icon, size: 16, color: color), const SizedBox(width: 8), Text(title, style: TextStyle(color: color, fontWeight: FontWeight.bold, fontSize: 13)), ], ); } Widget _metricItem(String label, String value, Color color) { return Column( children: [ Text(label, style: TextStyle(color: AppTheme.textMuted, fontSize: 11)), const SizedBox(height: 4), Text(value, style: TextStyle(color: color, fontWeight: FontWeight.bold, fontSize: 13)), ], ); } Widget _paramRow(String label, String value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(label, style: TextStyle(color: AppTheme.textMuted, fontSize: 12)), Text(value, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12)), ], ), ); } }