import 'package:flutter/material.dart'; import '../../../core/theme/app_theme.dart'; import '../../../core/widgets/asset_logo_widget.dart'; import '../../../core/widgets/glass_container.dart'; import '../models/bot_models.dart'; class BotPositionCard extends StatelessWidget { final BotTradeOrderModel position; final VoidCallback? onClosePressed; const BotPositionCard({ super.key, required this.position, this.onClosePressed, }); @override Widget build(BuildContext context) { final isLong = position.isLong; final isProfitable = position.unrealizedPnlEur >= 0; final pnlPercent = position.pnlPercent; final rMult = position.rMultiple; return GlassContainer( margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ AssetLogoWidget( symbolOrName: position.symbol.isNotEmpty ? position.symbol : position.isin, imageUrl: '/api/v1/logo/${position.isin}', size: 36, ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text( position.symbol, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16, color: Colors.white), ), const SizedBox(width: 8), Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: isLong ? AppTheme.primaryEmerald.withValues(alpha: 0.2) : AppTheme.accentRed.withValues(alpha: 0.2), ), child: Text( position.direction.toUpperCase(), style: TextStyle( fontSize: 10, fontWeight: FontWeight.bold, color: isLong ? AppTheme.primaryEmerald : AppTheme.accentRed, ), ), ), const SizedBox(width: 6), _buildVenueBadge(position.venue), ], ), const SizedBox(height: 2), Text( position.isin, style: TextStyle(color: AppTheme.textMuted, fontSize: 11), ), ], ), ), Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( '${isProfitable ? '+' : ''}€${position.unrealizedPnlEur.toStringAsFixed(2)}', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: isProfitable ? AppTheme.primaryEmerald : AppTheme.accentRed, ), ), Text( '${isProfitable ? '+' : ''}${pnlPercent.toStringAsFixed(2)}% (${rMult >= 0 ? '+' : ''}${rMult.toStringAsFixed(1)}R)', style: TextStyle( fontSize: 11, fontWeight: FontWeight.w600, color: isProfitable ? AppTheme.primaryEmerald : AppTheme.accentRed, ), ), ], ), ], ), const SizedBox(height: 12), const Divider(height: 1, color: Colors.white10), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildPriceInfo('Entry / Buy-In', '€${position.averageBuyIn > 0 ? position.averageBuyIn.toStringAsFixed(2) : position.entryPrice.toStringAsFixed(2)}'), _buildPriceInfo('Current Price', '€${position.currentPrice.toStringAsFixed(2)}'), _buildPriceInfo('Stop Loss', '€${position.currentStopLoss.toStringAsFixed(2)}'), _buildPriceInfo('Take Profit 1', '€${position.takeProfit1.toStringAsFixed(2)}'), ], ), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildDynamicStateBadge(position), if (position.isActive && onClosePressed != null) TextButton.icon( onPressed: onClosePressed, icon: Icon(Icons.close, size: 14, color: AppTheme.accentRed), label: Text('Glattstellen', style: TextStyle(fontSize: 12, color: AppTheme.accentRed)), style: TextButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), visualDensity: VisualDensity.compact, ), ), ], ), ], ), ); } Widget _buildPriceInfo(String label, String value) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(label, style: TextStyle(color: AppTheme.textMuted, fontSize: 10)), const SizedBox(height: 2), Text(value, style: const TextStyle(color: Colors.white70, fontSize: 12, fontWeight: FontWeight.w600)), ], ); } Widget _buildVenueBadge(String venue) { final isAlpaca = venue.toLowerCase().contains('alpaca'); return Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: isAlpaca ? Colors.blue.withValues(alpha: 0.15) : Colors.purple.withValues(alpha: 0.15), ), child: Text( isAlpaca ? 'Alpaca US' : 'Synthetic KO', style: TextStyle( fontSize: 9, fontWeight: FontWeight.w600, color: isAlpaca ? Colors.lightBlueAccent : Colors.purpleAccent, ), ), ); } Widget _buildDynamicStateBadge(BotTradeOrderModel position) { String text = 'Pending TP1'; Color color = Colors.amber; if (position.isBreakEven) { text = 'Free-Roll Active (BE)'; color = AppTheme.primaryEmerald; } else if (position.isTp1Hit) { text = 'TP1 Hit (Trailing Active)'; color = Colors.cyanAccent; } else if (position.isClosed) { text = 'Closed'; color = Colors.grey; } return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: color.withValues(alpha: 0.15), border: Border.all(color: color.withValues(alpha: 0.4), width: 1), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.bolt, size: 12, color: color), const SizedBox(width: 4), Text( text, style: TextStyle(color: color, fontSize: 11, fontWeight: FontWeight.bold), ), ], ), ); } }