import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:gal/gal.dart';
import 'package:go_router/go_router.dart';
import 'package:path_provider/path_provider.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'package:share_plus/share_plus.dart';

import '../../../core/l10n/app_localizations.dart';
import '../../../core/network/dio_client.dart';
import '../../../core/theme/app_colors.dart';
import '../../../core/utils/dialog_utils.dart' show showConfirmDialog, showTipDialog, extractErrorMessage;
import '../../../core/utils/number_format.dart';
import '../../../core/utils/top_toast.dart';
import '../../widgets/common/app_refresh_indicator.dart';
import '../../widgets/common/app_shimmer.dart';
import '../../widgets/common/app_tab_bar.dart';
import '../../../data/models/copy_trading/copy_position.dart';
import '../../../data/models/copy_trading/trader.dart';
import '../../../data/repositories/copy_trading_repository.dart';
import '../../../data/services/auth_service.dart';
import '../../../providers/my_copy_trading_provider.dart';

class MyCopyTradingScreen extends ConsumerStatefulWidget {
  const MyCopyTradingScreen({super.key});

  @override
  ConsumerState<MyCopyTradingScreen> createState() => _MyCopyTradingScreenState();
}

class _MyCopyTradingScreenState extends ConsumerState<MyCopyTradingScreen>
    with SingleTickerProviderStateMixin {
  late TabController _tabController;
  late PageController _pageController;
  final _currentScrollCtrl = ScrollController();
  final _tradersScrollCtrl = ScrollController();
  final _historyScrollCtrl = ScrollController();

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 3, vsync: this);
    _pageController = PageController();
    // 每次进入页面都重置 tab 并刷新数据
    WidgetsBinding.instance.addPostFrameCallback((_) {
      ref.read(myCopyTradingProvider.notifier).setTab(0);
      ref.read(myCopyTradingProvider.notifier).refresh();
    });
    _tabController.addListener(() {
      if (!mounted) return;
      if (_tabController.indexIsChanging) {
        _pageController.animateToPage(
          _tabController.index,
          duration: const Duration(milliseconds: 280),
          curve: Curves.easeOut,
        );
      } else {
        ref.read(myCopyTradingProvider.notifier).setTab(_tabController.index);
      }
    });
    _pageController.addListener(() {
      if (!mounted) return;
      if (!_pageController.hasClients) return;
      final page = _pageController.page!;
      final offset = page - _tabController.index;
      if (offset.abs() <= 1.0 && !_tabController.indexIsChanging) {
        _tabController.offset = offset.clamp(-1.0, 1.0);
      }
    });
    _currentScrollCtrl.addListener(() {
      if (!mounted) return;
      if (_currentScrollCtrl.position.pixels >= _currentScrollCtrl.position.maxScrollExtent - 200) {
        ref.read(myCopyTradingProvider.notifier).loadMoreCurrent();
      }
    });
    _tradersScrollCtrl.addListener(() {
      if (!mounted) return;
      if (_tradersScrollCtrl.position.pixels >= _tradersScrollCtrl.position.maxScrollExtent - 200) {
        ref.read(myCopyTradingProvider.notifier).loadMoreTraders();
      }
    });
    _historyScrollCtrl.addListener(() {
      if (!mounted) return;
      if (_historyScrollCtrl.position.pixels >= _historyScrollCtrl.position.maxScrollExtent - 200) {
        ref.read(myCopyTradingProvider.notifier).loadMoreHistory();
      }
    });
  }

  @override
  void dispose() {
    _tabController.dispose();
    _pageController.dispose();
    _currentScrollCtrl.dispose();
    _tradersScrollCtrl.dispose();
    _historyScrollCtrl.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final cardBg = isDark ? AppColors.darkBgSecondary : AppColors.lightBg;
    final state = ref.watch(myCopyTradingProvider);

    final currentCount = state.currentPositions.length;
    final traderCount = state.myTraders.length;

    return Scaffold(
      backgroundColor: cardBg,
      appBar: AppBar(
        leading: IconButton(
          icon: const Icon(Icons.arrow_back_ios, size: 18),
          onPressed: () => context.pop(),
        ),
        title: Text(AppLocalizations.of(context)!.myCopyTrading, style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w600)),
      ),
      body: state.isLoading
          ? _MyCopyTradingFullSkeleton(cardBg: cardBg)
          : Column(
              children: [
                // 统计卡片（带眼睛隐藏）—— 铺满白色背景
                if (state.account != null)
                  _StatsCard(
                    account: state.account!,
                    onTransfer: () async {
                      await context.push('/asset/transfer?from=SPOT&to=FOLLOW');
                      if (context.mounted) {
                        ref.read(myCopyTradingProvider.notifier).refresh();
                      }
                    },
                  ),
                // Tab
                Container(
                  decoration: BoxDecoration(
                    border: Border(
                      bottom: BorderSide(color: cs.outlineVariant.withAlpha(60), width: 1),
                    ),
                  ),
                  child: TabBar(
                    controller: _tabController,
                    indicator: StretchTabIndicator(
                      controller: _tabController,
                      color: AppColors.brand,
                    ),
                    indicatorSize: TabBarIndicatorSize.tab,
                    dividerColor: Colors.transparent,
                    labelColor: AppColors.brand,
                    unselectedLabelColor: cs.onSurface.withAlpha(153),
                    labelStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
                    unselectedLabelStyle: const TextStyle(fontSize: 14),
                    tabs: [
                      Tab(text: currentCount > 0 ? '${AppLocalizations.of(context)!.currentFollowOrders}($currentCount)' : AppLocalizations.of(context)!.currentFollowOrders),
                      Tab(text: traderCount > 0 ? '${AppLocalizations.of(context)!.myTraders}($traderCount)' : AppLocalizations.of(context)!.myTraders),
                      Tab(text: AppLocalizations.of(context)!.historyFollowOrders),
                    ],
                  ),
                ),
                // 内容区
                Expanded(
                  child: PageView(
                    controller: _pageController,
                    physics: const BouncingScrollPhysics(
                      parent: AlwaysScrollableScrollPhysics(),
                    ),
                    onPageChanged: (index) {
                      if (_tabController.indexIsChanging) return;
                      _tabController.index = index;
                    },
                    children: [
                      _buildCurrentTab(state),
                      _buildTradersTab(state),
                      _buildHistoryTab(state),
                    ],
                  ),
                ),
              ],
            ),
    );
  }

  Widget _buildCurrentTab(MyCopyTradingState state) {
    final onRefresh = () => ref.read(myCopyTradingProvider.notifier).silentRefresh();
    if (state.isLoading && state.currentPositions.isEmpty) {
      return ListView.builder(
        padding: const EdgeInsets.fromLTRB(0, 8, 0, 16),
        itemCount: 3,
        itemBuilder: (_, __) => const _PositionCardSkeleton(),
      );
    }
    return AppRefreshIndicator(
      onRefresh: onRefresh,
      child: state.currentPositions.isEmpty
          ? ListView(
              physics: const AlwaysScrollableScrollPhysics(),
              children: [_EmptyState(onGoMarket: () => context.pop())],
            )
          : ListView.builder(
              controller: _currentScrollCtrl,
              physics: const AlwaysScrollableScrollPhysics(),
              padding: const EdgeInsets.fromLTRB(0, 8, 0, 16),
              itemCount: state.currentPositions.length + 1,
              itemBuilder: (_, i) {
                if (i >= state.currentPositions.length) {
                  return _loadMoreFooter(state.currentLoadingMore, state.currentHasMore);
                }
                return _PositionCard(
                  position: state.currentPositions[i],
                  isHistory: false,
                  onClose: (id) async {
                    final confirmed = await showConfirmDialog(
                      context,
                      content: AppLocalizations.of(context)!.closePositionConfirmMsg,
                    );
                    if (!confirmed || !context.mounted) return;
                    try {
                      await ref.read(myCopyTradingProvider.notifier).closePosition(id);
                      if (context.mounted) {
                        showTopToast(context, message: AppLocalizations.of(context)!.closePositionSuccess, backgroundColor: AppColors.rise);
                      }
                    } catch (e) {
                      if (context.mounted) {
                        showTopToast(context, message: extractErrorMessage(e), backgroundColor: AppColors.fall);
                      }
                    }
                  },
                );
              },
            ),
    );
  }

  Widget _buildTradersTab(MyCopyTradingState state) {
    final onRefresh = () => ref.read(myCopyTradingProvider.notifier).silentRefresh();
    if (state.isLoading && state.myTraders.isEmpty) {
      return ListView.builder(
        padding: const EdgeInsets.fromLTRB(0, 8, 0, 16),
        itemCount: 3,
        itemBuilder: (_, __) => const _MyTraderCardSkeleton(),
      );
    }
    return AppRefreshIndicator(
      onRefresh: onRefresh,
      child: state.myTraders.isEmpty
          ? ListView(
              physics: const AlwaysScrollableScrollPhysics(),
              children: [_EmptyState(onGoMarket: () => context.pop())],
            )
          : ListView.builder(
              controller: _tradersScrollCtrl,
              physics: const AlwaysScrollableScrollPhysics(),
              padding: const EdgeInsets.fromLTRB(0, 8, 0, 16),
              itemCount: state.myTraders.length + 1,
              itemBuilder: (_, i) {
                if (i >= state.myTraders.length) {
                  return _loadMoreFooter(state.tradersLoadingMore, state.tradersHasMore);
                }
                return _MyTraderCard(
                  trader: state.myTraders[i],
                  onUnfollow: () async {
                    final confirmed = await showConfirmDialog(
                      context,
                      content: AppLocalizations.of(context)!.unfollowTraderConfirm,
                    );
                    if (!confirmed || !context.mounted) return;
                    try {
                      await ref.read(myCopyTradingProvider.notifier).unfollowTrader(state.myTraders[i].id);
                    } catch (e) {
                      if (context.mounted) showTipDialog(context, content: extractErrorMessage(e));
                    }
                  },
                );
              },
            ),
    );
  }

  Widget _buildHistoryTab(MyCopyTradingState state) {
    final onRefresh = () => ref.read(myCopyTradingProvider.notifier).silentRefresh();
    if (state.isLoading && state.historyPositions.isEmpty) {
      return ListView.builder(
        padding: const EdgeInsets.fromLTRB(0, 8, 0, 16),
        itemCount: 3,
        itemBuilder: (_, __) => const _PositionCardSkeleton(),
      );
    }
    return AppRefreshIndicator(
      onRefresh: onRefresh,
      child: state.historyPositions.isEmpty
          ? ListView(
              physics: const AlwaysScrollableScrollPhysics(),
              children: [_EmptyState(onGoMarket: () => context.pop())],
            )
          : ListView.builder(
              controller: _historyScrollCtrl,
              physics: const AlwaysScrollableScrollPhysics(),
              padding: const EdgeInsets.fromLTRB(0, 8, 0, 16),
              itemCount: state.historyPositions.length + 1,
              itemBuilder: (_, i) {
                if (i >= state.historyPositions.length) {
                  return _loadMoreFooter(state.historyLoadingMore, state.historyHasMore);
                }
                return _PositionCard(
                  position: state.historyPositions[i],
                  isHistory: true,
                );
              },
            ),
    );
  }

  Widget _loadMoreFooter(bool loading, bool hasMore) {
    if (loading) {
      return const Padding(
        padding: EdgeInsets.symmetric(vertical: 16),
        child: Center(child: CircularProgressIndicator(color: AppColors.brand, strokeWidth: 2)),
      );
    }
    if (!hasMore) {
      return Padding(
        padding: const EdgeInsets.symmetric(vertical: 16),
        child: Center(
          child: Text(AppLocalizations.of(context)!.noMore, style: TextStyle(color: Theme.of(context).colorScheme.onSurface.withAlpha(100), fontSize: 12)),
        ),
      );
    }
    return const SizedBox(height: 8);
  }
}

// ── 统计卡片（眼睛隐藏） ───────────────────────────────────

class _StatsCard extends StatefulWidget {
  const _StatsCard({required this.account, this.onTransfer});
  final dynamic account;
  final VoidCallback? onTransfer;

  @override
  State<_StatsCard> createState() => _StatsCardState();
}

class _StatsCardState extends State<_StatsCard> {
  bool _visible = true;

  /// 截断到2位小数，不四舍五入（等同 Java RoundingMode.DOWN）
  String _fmtDown(double v) {
    final isNeg = v < 0;
    final abs = v.abs();
    final str = abs.toStringAsFixed(10);
    final dotIdx = str.indexOf('.');
    final intPart = dotIdx < 0 ? str : str.substring(0, dotIdx);
    final fracPart = dotIdx < 0 ? '00' : (str.substring(dotIdx + 1) + '00').substring(0, 2);
    return '${isNeg ? '-' : ''}$intPart.$fracPart';
  }

  @override
  Widget build(BuildContext context) {
    final acc = widget.account;
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final cs = Theme.of(context).colorScheme;
    final pnlValue = acc.unrealizedPnl as double;
    // 黄色背景上用深绿色以保证对比度
    final pnlColor = pnlValue >= 0 ? const Color(0xFF1A7A4A) : AppColors.fall;
    final pnlSign = pnlValue >= 0 ? '+' : '';
    const iconColor = Colors.black54;

    return Container(
      margin: const EdgeInsets.fromLTRB(16, 12, 16, 4),
      decoration: BoxDecoration(
        color: AppColors.brand,
        borderRadius: BorderRadius.circular(16),
      ),
      child: Padding(
        padding: const EdgeInsets.fromLTRB(16, 10, 16, 16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // 眼睛 + 划转
            Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                GestureDetector(
                  onTap: () => setState(() => _visible = !_visible),
                  child: Icon(
                    _visible ? Icons.visibility_outlined : Icons.visibility_off_outlined,
                    size: 18,
                    color: iconColor,
                  ),
                ),
                const SizedBox(width: 12),
                GestureDetector(
                  onTap: widget.onTransfer ?? () => context.push('/asset/transfer?from=SPOT&to=FOLLOW'),
                  child: const Icon(Icons.sync_alt, size: 18, color: iconColor),
                ),
              ],
            ),
            const SizedBox(height: 8),
            // 三列数据
            Builder(builder: (context) {
              final l10n = AppLocalizations.of(context)!;
              return Row(
                children: [
                  _StatCol(
                    label: l10n.cumCopyProfitUsdt,
                    value: _visible ? _fmtDown(acc.cumulativePnl as double) : '****',
                  ),
                  _StatCol(
                    label: l10n.availableBalanceUsdt,
                    value: _visible ? _fmtDown(acc.availableBalance as double) : '****',
                  ),
                  _StatCol(
                    label: l10n.unrealizedPnlUsdt,
                    value: _visible
                        ? '$pnlSign${_fmtDown(pnlValue.abs())}'
                        : '****',
                    valueColor: _visible ? pnlColor : null,
                  ),
                ],
              );
            }),
          ],
        ),
      ),
    );
  }
}

class _StatCol extends StatelessWidget {
  const _StatCol({required this.label, required this.value, this.valueColor});

  final String label;
  final String value;
  final Color? valueColor;

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            label,
            style: TextStyle(color: Colors.black.withAlpha(140), fontSize: 11),
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
          ),
          const SizedBox(height: 5),
          Text(
            value,
            style: TextStyle(
              color: valueColor ?? Colors.black,
              fontSize: 16,
              fontWeight: FontWeight.w700,
            ),
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
          ),
        ],
      ),
    );
  }
}

// ── 仓位卡片 ────────────────────────────────────────────────

class _PositionCard extends StatelessWidget {
  const _PositionCard({
    required this.position,
    required this.isHistory,
    this.onClose,
  });

  final CopyPosition position;
  final bool isHistory;
  final void Function(String positionId)? onClose;

  static const _avatarColors = [
    Color(0xFFf7931a), Color(0xFF627eea), Color(0xFF9945ff),
    Color(0xFFf3ba2f), Color(0xFF2775ca),
  ];

  Color get _avatarBg =>
      _avatarColors[position.traderName.codeUnitAt(0) % _avatarColors.length];

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final l10n = AppLocalizations.of(context)!;
    final isLong = position.isLong;
    final directionColor = isLong ? AppColors.rise : AppColors.fall;
    final directionLabel = isLong ? l10n.openLongBullish : l10n.openShortBearish;
    final pnlColor = position.unrealizedPnl >= 0 ? AppColors.rise : AppColors.fall;
    final pnlSign = position.unrealizedPnl >= 0 ? '+' : '';
    final roiSign = position.roi >= 0 ? '+' : '';

    return Container(
      margin: const EdgeInsets.fromLTRB(16, 8, 16, 0),
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: isDark ? AppColors.darkBgSecondary : AppColors.lightBg,
        borderRadius: BorderRadius.circular(16),
        boxShadow: [
          BoxShadow(color: Colors.black.withAlpha(18), blurRadius: 12, offset: const Offset(0, 2)),
        ],
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          if (isHistory)
            // 历史跟单：品种在左，交易员头像+名称在右，分享按钮最右
            Row(
              children: [
                Expanded(
                  child: Text(
                    position.symbol,
                    style: TextStyle(color: cs.onSurface, fontSize: 16, fontWeight: FontWeight.w700),
                  ),
                ),
                _TraderAvatar(
                  name: position.traderName,
                  avatarUrl: position.traderAvatar,
                  bgColor: _avatarBg,
                  size: 32,
                ),
                const SizedBox(width: 8),
                Text(position.traderName,
                    style: TextStyle(color: cs.onSurface, fontSize: 14, fontWeight: FontWeight.w600)),
                const SizedBox(width: 10),
                GestureDetector(
                  onTap: () => _showShareSheet(context),
                  child: Icon(Icons.share_outlined, size: 18, color: cs.onSurface.withAlpha(120)),
                ),
              ],
            )
          else
            // 当前跟单：交易员头像+名称在左，平仓按钮在右
            Row(
              children: [
                _TraderAvatar(
                  name: position.traderName,
                  avatarUrl: position.traderAvatar,
                  bgColor: _avatarBg,
                  size: 38,
                ),
                const SizedBox(width: 10),
                Expanded(
                  child: Text(
                    position.traderName,
                    style: TextStyle(color: cs.onSurface, fontSize: 15, fontWeight: FontWeight.w600),
                  ),
                ),
                ElevatedButton(
                    onPressed: () => onClose?.call(position.id),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: AppColors.brand,
                      foregroundColor: Colors.black,
                      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
                      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
                      minimumSize: Size.zero,
                      tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                      elevation: 0,
                    ),
                    child: Text(l10n.closePosition, style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600)),
                  ),
              ],
            ),
          const SizedBox(height: 10),
          // 品种行（当前跟单时显示）
          if (!isHistory)
            Wrap(
              spacing: 6,
              runSpacing: 6,
              crossAxisAlignment: WrapCrossAlignment.center,
              children: [
                Text(position.symbol,
                    maxLines: 1,
                    overflow: TextOverflow.ellipsis,
                    style: TextStyle(color: cs.onSurface, fontSize: 14, fontWeight: FontWeight.w700)),
                _Badge(text: directionLabel, bgColor: directionColor.withValues(alpha: 0.12), textColor: directionColor),
                _Badge(text: l10n.perpetual, bgColor: cs.onSurface.withAlpha(20), textColor: cs.onSurface.withAlpha(153), borderColor: cs.onSurface.withAlpha(60)),
                _Badge(text: position.positionType == '逐仓' ? l10n.isolatedMargin : l10n.crossMargin, bgColor: cs.onSurface.withAlpha(20), textColor: cs.onSurface.withAlpha(153), borderColor: cs.onSurface.withAlpha(60)),
                _Badge(text: '${position.leverage}x', bgColor: cs.onSurface.withAlpha(20), textColor: cs.onSurface.withAlpha(180), borderColor: cs.onSurface.withAlpha(60)),
              ],
            )
          else
            // 历史跟单：direction + 永续 + positionType + leverage
            Wrap(
              spacing: 6,
              runSpacing: 6,
              crossAxisAlignment: WrapCrossAlignment.center,
              children: [
                _Badge(text: directionLabel, bgColor: directionColor.withValues(alpha: 0.12), textColor: directionColor),
                _Badge(text: l10n.perpetual, bgColor: cs.onSurface.withAlpha(20), textColor: cs.onSurface.withAlpha(153), borderColor: cs.onSurface.withAlpha(60)),
                _Badge(text: position.positionType == '逐仓' ? l10n.isolatedMargin : l10n.crossMargin, bgColor: cs.onSurface.withAlpha(20), textColor: cs.onSurface.withAlpha(153), borderColor: cs.onSurface.withAlpha(60)),
                _Badge(text: '${position.leverage}x', bgColor: cs.onSurface.withAlpha(20), textColor: cs.onSurface.withAlpha(180), borderColor: cs.onSurface.withAlpha(60)),
              ],
            ),
          const SizedBox(height: 10),
          if (!isHistory) ...[
            // 当前跟单数据行
            Row(
              children: [
                _DataCell(label: l10n.openAvgPriceUsdt, value: position.openPrice.toStringAsFixed(1)),
                _DataCell(label: l10n.currentPriceUsdt, value: position.currentPrice.toStringAsFixed(1)),
                _DataCell(label: l10n.currentMarginUsdt, value: position.margin.toStringAsFixed(2)),
              ],
            ),
            const SizedBox(height: 8),
            Row(
              children: [
                _DataCell(label: l10n.qtyWithCoin(_baseAsset(position.symbol)), value: position.quantity.toStringAsFixed(4)),
                _DataCell(label: l10n.returnRate, value: '$roiSign${position.roi.toStringAsFixed(2)}%', valueColor: pnlColor),
                _DataCell(label: l10n.profitUsdt, value: '$pnlSign${position.unrealizedPnl.toStringAsFixed(3)}', valueColor: pnlColor),
              ],
            ),
          ] else ...[
            // 历史跟单数据行：数量 / 收益 / 收益率（三列，最后列右对齐）
            Row(
              children: [
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(l10n.qtyWithCoin(_baseAsset(position.symbol)),
                          style: TextStyle(color: cs.onSurface.withAlpha(153), fontSize: 11)),
                      const SizedBox(height: 4),
                      Text(position.quantity.toStringAsFixed(4),
                          style: TextStyle(color: cs.onSurface, fontSize: 15, fontWeight: FontWeight.w700)),
                    ],
                  ),
                ),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(l10n.profitUsdt,
                          style: TextStyle(color: cs.onSurface.withAlpha(153), fontSize: 11)),
                      const SizedBox(height: 4),
                      Text('$pnlSign${position.unrealizedPnl.toStringAsFixed(4)}',
                          style: TextStyle(color: pnlColor, fontSize: 15, fontWeight: FontWeight.w700)),
                    ],
                  ),
                ),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      Text(l10n.returnRate,
                          style: TextStyle(color: cs.onSurface.withAlpha(153), fontSize: 11)),
                      const SizedBox(height: 4),
                      Text('$roiSign${position.roi.toStringAsFixed(2)}%',
                          style: TextStyle(color: pnlColor, fontSize: 15, fontWeight: FontWeight.w700)),
                    ],
                  ),
                ),
              ],
            ),
            const SizedBox(height: 16),
            Divider(height: 1, thickness: 1, color: cs.outlineVariant.withAlpha(60)),
            const SizedBox(height: 12),
            // 底部：开仓均价（左） / 平仓均价（右对齐）
            Row(
              children: [
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(l10n.openAvgPriceUsdt,
                          style: TextStyle(color: cs.onSurface.withAlpha(153), fontSize: 11)),
                      const SizedBox(height: 3),
                      Text(position.openPrice.toStringAsFixed(1),
                          style: TextStyle(color: cs.onSurface, fontSize: 15, fontWeight: FontWeight.w700)),
                      const SizedBox(height: 2),
                      Text(_formatDate(position.openTime),
                          style: TextStyle(color: cs.onSurface.withAlpha(120), fontSize: 11)),
                    ],
                  ),
                ),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: [
                    Text(l10n.closeAvgPriceUsdt,
                        style: TextStyle(color: cs.onSurface.withAlpha(153), fontSize: 11)),
                    const SizedBox(height: 3),
                    Text(
                      position.closePrice != null ? position.closePrice!.toStringAsFixed(1) : '--',
                      style: TextStyle(color: cs.onSurface, fontSize: 15, fontWeight: FontWeight.w700),
                    ),
                    const SizedBox(height: 2),
                    Text(
                      position.closeTime != null ? _formatDate(position.closeTime!) : '--',
                      style: TextStyle(color: cs.onSurface.withAlpha(120), fontSize: 11),
                    ),
                  ],
                ),
              ],
            ),
          ],
          if (!isHistory) ...[
            const SizedBox(height: 10),
            Row(
              children: [
                Text(
                  l10n.openTimeWithValue(_formatDate(position.openTime)),
                  style: TextStyle(color: cs.onSurface.withAlpha(153), fontSize: 11),
                ),
                const Spacer(),
                Text('${l10n.positionIdPrefix}${position.id}',
                    style: TextStyle(color: cs.onSurface.withAlpha(153), fontSize: 11)),
                const SizedBox(width: 4),
                GestureDetector(
                  onTap: () {
                    Clipboard.setData(ClipboardData(text: position.id));
                    showTopToast(context, message: l10n.copyPositionIdSuccess, backgroundColor: AppColors.rise);
                  },
                  child: Icon(Icons.copy_outlined, size: 14, color: cs.onSurface.withAlpha(153)),
                ),
              ],
            ),
          ],
        ],
      ),
    );
  }

  void _showShareSheet(BuildContext context) {
    showModalBottomSheet(
      context: context,
      useRootNavigator: true,
      backgroundColor: Colors.transparent,
      isScrollControlled: true,
      builder: (_) => _FollowShareSheet(position: position),
    );
  }

  String _baseAsset(String symbol) {
    final s = symbol.replaceAll(' 永续', '');
    final parts = s.split('/');
    return parts.isNotEmpty ? parts[0] : s;
  }

  String _formatDate(DateTime dt) =>
      '${dt.year}-${dt.month.toString().padLeft(2, '0')}-${dt.day.toString().padLeft(2, '0')} '
      '${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}:${dt.second.toString().padLeft(2, '0')}';
}

// ── 历史跟单分享 BottomSheet ───────────────────────────────

class _FollowShareSheet extends ConsumerStatefulWidget {
  const _FollowShareSheet({required this.position});
  final CopyPosition position;

  @override
  ConsumerState<_FollowShareSheet> createState() => _FollowShareSheetState();
}

class _FollowShareSheetState extends ConsumerState<_FollowShareSheet> {
  final _cardKey = GlobalKey();
  bool _sharing = false;
  bool _saving = false;
  String? _inviteCode;
  String? _inviteUrl;

  @override
  void initState() {
    super.initState();
    _loadInviteInfo();
  }

  Future<void> _loadInviteInfo() async {
    try {
      final dio = ref.read(dioClientProvider);
      final data = await AuthService(dio).getMyInfo();
      final prefix = data['promotionPrefix']?.toString() ?? '';
      final code = data['promotionCode']?.toString() ?? '';
      final url = (prefix.isNotEmpty || code.isNotEmpty) ? '$prefix$code' : null;
      if (mounted) {
        setState(() {
          _inviteCode = code.isNotEmpty ? code : null;
          _inviteUrl = url;
        });
      }
    } catch (_) {}
  }

  Future<Uint8List?> _renderCard() async {
    final boundary = _cardKey.currentContext?.findRenderObject() as RenderRepaintBoundary?;
    if (boundary == null) return null;
    final image = await boundary.toImage(pixelRatio: 3.0);
    final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    return byteData?.buffer.asUint8List();
  }

  Future<void> _doSave(BuildContext context) async {
    setState(() => _saving = true);
    try {
      final bytes = await _renderCard();
      if (bytes == null) return;
      await Gal.requestAccess();
      await Gal.putImageBytes(
        bytes,
        name: 'follow_share_${DateTime.now().millisecondsSinceEpoch}',
      );
      if (!context.mounted) return;
      showTopToast(context,
          message: AppLocalizations.of(context)!.saveSuccess,
          backgroundColor: AppColors.rise);
    } on GalException catch (e) {
      if (!context.mounted) return;
      final l10n = AppLocalizations.of(context)!;
      if (e.type == GalExceptionType.accessDenied) {
        showTopToast(context, message: l10n.photoPermissionDenied, backgroundColor: AppColors.fall);
      } else {
        showTopToast(context, message: l10n.saveFailed, backgroundColor: AppColors.fall);
      }
    } catch (e) {
      if (context.mounted) {
        showTopToast(context,
            message: AppLocalizations.of(context)!.saveFailed,
            backgroundColor: AppColors.fall);
      }
    } finally {
      if (mounted) setState(() => _saving = false);
    }
  }

  Future<void> _doShare(BuildContext context) async {
    setState(() => _sharing = true);
    try {
      final bytes = await _renderCard();
      if (bytes == null) return;
      final tmpDir = await getTemporaryDirectory();
      final file = File('${tmpDir.path}/follow_share_${DateTime.now().millisecondsSinceEpoch}.png');
      await file.writeAsBytes(bytes);
      if (!context.mounted) return;
      Navigator.of(context).pop();
      await Share.shareXFiles(
        [XFile(file.path, mimeType: 'image/png')],
        subject: AppLocalizations.of(context)!.myCopyTradingProfit,
      );
    } catch (e) {
      if (context.mounted) {
        showTopToast(context, message: AppLocalizations.of(context)!.shareFailed, backgroundColor: AppColors.fall);
      }
    } finally {
      if (mounted) setState(() => _sharing = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final p = widget.position;
    final pnlPositive = p.unrealizedPnl >= 0;
    final l10n = AppLocalizations.of(context)!;

    return Container(
      decoration: BoxDecoration(
        color: isDark ? AppColors.darkBgSecondary : AppColors.lightBgSecondary,
        borderRadius: const BorderRadius.vertical(top: Radius.circular(16)),
      ),
      padding: const EdgeInsets.fromLTRB(16, 16, 16, 32),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          // 拖拽指示条
          Container(
            width: 36,
            height: 4,
            decoration: BoxDecoration(
              color: cs.onSurface.withAlpha(60),
              borderRadius: BorderRadius.circular(2),
            ),
          ),
          const SizedBox(height: 16),

          // 分享卡片预览
          RepaintBoundary(
            key: _cardKey,
            child: _FollowShareCard(
              position: p,
              inviteCode: _inviteCode,
              inviteUrl: _inviteUrl,
            ),
          ),
          const SizedBox(height: 24),

          // 操作按钮行：取消 | 保存海报 | 分享
          Row(
            children: [
              Expanded(
                child: OutlinedButton(
                  onPressed: () => Navigator.of(context).pop(),
                  style: OutlinedButton.styleFrom(
                    padding: const EdgeInsets.symmetric(vertical: 12),
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
                  ),
                  child: Text(l10n.cancelLabel, style: TextStyle(color: cs.onSurface, fontSize: 14)),
                ),
              ),
              const SizedBox(width: 8),
              Expanded(
                child: OutlinedButton(
                  onPressed: _saving ? null : () => _doSave(context),
                  style: OutlinedButton.styleFrom(
                    padding: const EdgeInsets.symmetric(vertical: 12),
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
                  ),
                  child: _saving
                      ? SizedBox(
                          width: 16, height: 16,
                          child: CircularProgressIndicator(strokeWidth: 2, color: cs.onSurface.withAlpha(153)),
                        )
                      : Text(l10n.savePoster, style: TextStyle(color: cs.onSurface, fontSize: 14)),
                ),
              ),
              const SizedBox(width: 8),
              Expanded(
                child: ElevatedButton(
                  onPressed: _sharing ? null : () => _doShare(context),
                  style: ElevatedButton.styleFrom(
                    backgroundColor: pnlPositive ? AppColors.rise : AppColors.fall,
                    padding: const EdgeInsets.symmetric(vertical: 12),
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
                    elevation: 0,
                  ),
                  child: _sharing
                      ? const SizedBox(
                          width: 16, height: 16,
                          child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white),
                        )
                      : Text(l10n.shareLabel,
                          style: const TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w600)),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

// ── 跟单分享卡片内容 ─────────────────────────────────────────

class _FollowShareCard extends StatelessWidget {
  const _FollowShareCard({
    required this.position,
    this.inviteCode,
    this.inviteUrl,
  });
  final CopyPosition position;
  final String? inviteCode;
  final String? inviteUrl;

  String _baseCoin(String sym) {
    if (sym.contains('/')) return sym.split('/').first;
    return sym.toUpperCase().replaceFirst(RegExp(r'USDT$'), '');
  }

  String _fmtDate(DateTime dt) {
    final mo = dt.month.toString().padLeft(2, '0');
    final d = dt.day.toString().padLeft(2, '0');
    final h = dt.hour.toString().padLeft(2, '0');
    final mi = dt.minute.toString().padLeft(2, '0');
    final s = dt.second.toString().padLeft(2, '0');
    return '${dt.year}-$mo-$d $h:$mi:$s';
  }

  @override
  Widget build(BuildContext context) {
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final l10n = AppLocalizations.of(context)!;
    final p = position;
    final isLong = p.isLong;
    final sideColor = isLong ? AppColors.rise : AppColors.fall;
    final pnlPositive = p.unrealizedPnl >= 0;
    final pnlColor = pnlPositive ? AppColors.rise : AppColors.fall;
    final coinSymbol = _baseCoin(p.symbol);
    final roiStr = '${pnlPositive ? '+' : ''}${formatAmount(p.roi)}%';
    final closePrice = p.closePrice;
    final closeTime = p.closeTime;

    // 主题色变量
    final bgColors = isDark
        ? const [Color(0xFF1A1F2E), Color(0xFF0D1117)]
        : const [Color(0xFFF8F9FB), Color(0xFFEEF0F3)];
    final textPrimary = isDark ? Colors.white : const Color(0xFF1A1F2E);
    final textSecondary = isDark
        ? Colors.white.withAlpha(120)
        : const Color(0xFF1A1F2E).withAlpha(120);
    final textMuted = isDark
        ? Colors.white.withAlpha(80)
        : const Color(0xFF1A1F2E).withAlpha(80);
    final borderColor = isDark
        ? Colors.white.withAlpha(40)
        : const Color(0xFF1A1F2E).withAlpha(30);
    final qrFgColor = isDark ? Colors.white : Colors.black;
    final qrBgColor = isDark ? const Color(0xFF1A1F2E) : Colors.white;

    return Container(
      width: double.infinity,
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topLeft,
          end: Alignment.bottomRight,
          colors: bgColors,
        ),
        borderRadius: BorderRadius.circular(16),
      ),
      clipBehavior: Clip.antiAlias,
      child: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // LOGO + 品牌名
            Row(
              children: [
                Image.asset(
                  'assets/images/app_icon.png',
                  height: 28,
                  width: 28,
                  errorBuilder: (_, __, ___) => const SizedBox.shrink(),
                ),
                const SizedBox(width: 8),
                Text(
                  'iBit',
                  style: TextStyle(
                      color: textPrimary,
                      fontSize: 14,
                      fontWeight: FontWeight.w700,
                      letterSpacing: 0.5),
                ),
              ],
            ),
            const SizedBox(height: 14),

            // 币对 + 永续 tag
            Row(
              children: [
                Text(
                  '${coinSymbol}USDT',
                  style: TextStyle(
                      color: textPrimary,
                      fontSize: 22,
                      fontWeight: FontWeight.w800),
                ),
                const SizedBox(width: 8),
                Container(
                  padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 2),
                  decoration: BoxDecoration(
                    color: const Color(0xFFFFAB00),
                    borderRadius: BorderRadius.circular(4),
                  ),
                  child: Text(l10n.perpetual,
                      style: const TextStyle(
                          color: Colors.white,
                          fontSize: 11,
                          fontWeight: FontWeight.w700)),
                ),
              ],
            ),
            const SizedBox(height: 4),

            // 方向 + 杠杆
            Text(
              '${isLong ? l10n.openLong : l10n.openShort} ${p.leverage}X',
              style: TextStyle(
                  color: sideColor,
                  fontSize: 15,
                  fontWeight: FontWeight.w700),
            ),
            const SizedBox(height: 14),

            // 收益率（大字）
            Text(l10n.returnRate,
                style: TextStyle(color: textSecondary, fontSize: 12)),
            const SizedBox(height: 4),
            Text(roiStr,
                style: TextStyle(
                    color: pnlColor,
                    fontSize: 36,
                    fontWeight: FontWeight.w800,
                    letterSpacing: -0.5)),
            const SizedBox(height: 16),

            // 开仓均价 + 平仓均价
            Row(
              children: [
                Expanded(
                  child: _FollowShareDataItem(
                    label: l10n.openAvgPrice,
                    value: formatAmount(p.openPrice),
                    textPrimary: textPrimary,
                    textSecondary: textSecondary,
                  ),
                ),
                Expanded(
                  child: _FollowShareDataItem(
                    label: l10n.avgClosePrice,
                    value: closePrice != null ? formatAmount(closePrice) : '--',
                    align: CrossAxisAlignment.end,
                    textPrimary: textPrimary,
                    textSecondary: textSecondary,
                  ),
                ),
              ],
            ),
            const SizedBox(height: 10),

            // 时间
            Text(closeTime != null ? _fmtDate(closeTime) : _fmtDate(p.openTime),
                style: TextStyle(color: textMuted, fontSize: 11)),
            const SizedBox(height: 14),

            // 分隔线
            Divider(color: borderColor, height: 1),
            const SizedBox(height: 14),

            // 邀请码 + 二维码
            Row(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      if (inviteCode != null)
                        RichText(
                          text: TextSpan(
                            style: const TextStyle(fontSize: 15),
                            children: [
                              TextSpan(
                                text: l10n.inviteCodeLabel,
                                style: TextStyle(color: textSecondary),
                              ),
                              TextSpan(
                                text: inviteCode!,
                                style: const TextStyle(
                                    color: AppColors.brand,
                                    fontWeight: FontWeight.w700),
                              ),
                            ],
                          ),
                        ),
                      const SizedBox(height: 4),
                      Text(l10n.registerAndEarnRebate,
                          style: TextStyle(color: textMuted, fontSize: 12)),
                    ],
                  ),
                ),
                Container(
                  decoration: BoxDecoration(
                    border: Border.all(color: borderColor, width: 1),
                    borderRadius: BorderRadius.circular(6),
                  ),
                  padding: const EdgeInsets.all(4),
                  child: inviteUrl != null
                      ? QrImageView(
                          data: inviteUrl!,
                          version: QrVersions.auto,
                          size: 80,
                          eyeStyle: QrEyeStyle(
                            eyeShape: QrEyeShape.square,
                            color: qrFgColor,
                          ),
                          dataModuleStyle: QrDataModuleStyle(
                            dataModuleShape: QrDataModuleShape.square,
                            color: qrFgColor,
                          ),
                          backgroundColor: qrBgColor,
                          errorCorrectionLevel: QrErrorCorrectLevel.M,
                        )
                      : const SizedBox(width: 80, height: 80),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

class _FollowShareDataItem extends StatelessWidget {
  const _FollowShareDataItem({
    required this.label,
    required this.value,
    required this.textPrimary,
    required this.textSecondary,
    this.align = CrossAxisAlignment.start,
  });
  final String label;
  final String value;
  final Color textPrimary;
  final Color textSecondary;
  final CrossAxisAlignment align;

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: align,
      children: [
        Text(label, style: TextStyle(color: textSecondary, fontSize: 11)),
        const SizedBox(height: 2),
        Text(value,
            style: TextStyle(
                color: textPrimary, fontSize: 13, fontWeight: FontWeight.w600)),
      ],
    );
  }
}

// ── 交易员头像 ────────────────────────────────────────────

class _TraderAvatar extends StatelessWidget {
  const _TraderAvatar({
    required this.name,
    required this.bgColor,
    required this.size,
    this.avatarUrl,
  });

  final String name;
  final String? avatarUrl;
  final Color bgColor;
  final double size;

  @override
  Widget build(BuildContext context) {
    final letter = name.isNotEmpty ? name[0].toUpperCase() : '?';
    if (avatarUrl != null && avatarUrl!.isNotEmpty) {
      return ClipOval(
        child: Image.network(
          avatarUrl!,
          width: size,
          height: size,
          fit: BoxFit.cover,
          errorBuilder: (_, __, ___) => _fallback(letter),
        ),
      );
    }
    return _fallback(letter);
  }

  Widget _fallback(String letter) => Container(
        width: size,
        height: size,
        decoration: BoxDecoration(color: bgColor, shape: BoxShape.circle),
        child: Center(
          child: Text(letter,
              style: TextStyle(
                  color: Colors.white,
                  fontSize: size * 0.42,
                  fontWeight: FontWeight.w700)),
        ),
      );
}

// ── 我的交易员卡片（原型风格） ─────────────────────────────

class _MyTraderCard extends StatelessWidget {
  const _MyTraderCard({required this.trader, required this.onUnfollow});

  final Trader trader;
  final VoidCallback onUnfollow;

  static const _avatarColors = [
    Color(0xFFf7931a), Color(0xFF627eea), Color(0xFF9945ff),
    Color(0xFFf3ba2f), Color(0xFF2775ca),
  ];

  Color get _bg =>
      _avatarColors[trader.avatarLetter.codeUnitAt(0) % _avatarColors.length];

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final isDark = Theme.of(context).brightness == Brightness.dark;

    return Container(
      margin: const EdgeInsets.fromLTRB(16, 8, 16, 0),
      padding: const EdgeInsets.all(14),
      decoration: BoxDecoration(
        color: isDark ? AppColors.darkBgSecondary : AppColors.lightBg,
        borderRadius: BorderRadius.circular(12),
        boxShadow: [
          BoxShadow(color: Colors.black.withAlpha(15), blurRadius: 8, offset: const Offset(0, 2)),
        ],
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // 头部：头像 + 名称+描述 + 取消跟随按钮
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 头像 + 等级角标
              SizedBox(
                width: 52,
                height: 60,
                child: Stack(
                  clipBehavior: Clip.none,
                  children: [
                    _TraderAvatar(
                      name: trader.name,
                      avatarUrl: trader.avatarUrl,
                      bgColor: _bg,
                      size: 52,
                    ),
                    if (trader.levelName != null && trader.levelName!.isNotEmpty)
                      Positioned(
                        bottom: 0,
                        left: 0,
                        right: 0,
                        child: Center(
                          child: Container(
                            padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 1),
                            decoration: BoxDecoration(
                              color: AppColors.darkBadgeBg,
                              borderRadius: BorderRadius.circular(20),
                              border: Border.all(color: AppColors.darkBgMid),
                            ),
                            child: Row(
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                const Icon(Icons.link, size: 8, color: AppColors.rankPurple),
                                const SizedBox(width: 2),
                                Text(trader.levelName!,
                                    style: const TextStyle(
                                        color: AppColors.rankPurple,
                                        fontSize: 9,
                                        fontWeight: FontWeight.w700)),
                              ],
                            ),
                          ),
                        ),
                      ),
                  ],
                ),
              ),
              const SizedBox(width: 12),
              // 名称 + 描述
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(trader.name,
                        style: TextStyle(
                            color: cs.onSurface,
                            fontSize: 15,
                            fontWeight: FontWeight.w600)),
                    if (trader.description != null && trader.description!.isNotEmpty) ...[
                      const SizedBox(height: 2),
                      Text(trader.description!,
                          style: TextStyle(color: cs.onSurface.withAlpha(130), fontSize: 12),
                          maxLines: 1,
                          overflow: TextOverflow.ellipsis),
                    ],
                    if (trader.tags.isNotEmpty) ...[
                      const SizedBox(height: 6),
                      Wrap(
                        spacing: 6,
                        runSpacing: 4,
                        children: trader.tags
                            .map((tag) => Container(
                                  padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 3),
                                  decoration: BoxDecoration(
                                    color: isDark ? AppColors.tagIndigoBgDark : AppColors.tagIndigoBgLight,
                                    borderRadius: BorderRadius.circular(20),
                                    border: Border.all(color: AppColors.tagIndigo.withAlpha(80), width: 0.8),
                                  ),
                                  child: Text(tag,
                                      style: const TextStyle(
                                          color: AppColors.tagIndigo,
                                          fontSize: 11,
                                          fontWeight: FontWeight.w500)),
                                ))
                            .toList(),
                      ),
                    ],
                  ],
                ),
              ),
              const SizedBox(width: 8),
              // 取消跟随按钮
              OutlinedButton(
                onPressed: onUnfollow,
                style: OutlinedButton.styleFrom(
                  backgroundColor: isDark ? AppColors.darkBgSecondary : AppColors.lightBg,
                  side: BorderSide(color: cs.onSurface, width: 1.5),
                  foregroundColor: cs.onSurface,
                  padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 6),
                  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
                  minimumSize: Size.zero,
                  tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                ),
                child: Text(AppLocalizations.of(context)!.unfollow, style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500)),
              ),
            ],
          ),
          const SizedBox(height: 12),
          Divider(height: 1, thickness: 0.5, color: cs.outlineVariant.withAlpha(80)),
          const SizedBox(height: 12),
          // 底部统计行（含竖向分隔线）
          Builder(builder: (context) {
            final l10n = AppLocalizations.of(context)!;
            return IntrinsicHeight(
              child: Row(
                children: [
                  _TraderStatCol(
                    label: l10n.profitUsdt,
                    value: trader.profitAmount == 0
                        ? '--'
                        : '${trader.profitAmount >= 0 ? '+' : ''}${trader.profitAmount.toStringAsFixed(2)}',
                    valueColor: trader.profitAmount >= 0 ? AppColors.rise : AppColors.fall,
                  ),
                  VerticalDivider(width: 1, thickness: 0.8, color: Colors.grey.withAlpha(100)),
                  _TraderStatCol(
                    label: l10n.cumFollowerCount,
                    value: trader.followCustomer == 0 ? '--' : '${trader.followCustomer}',
                    center: true,
                  ),
                  VerticalDivider(width: 1, thickness: 0.8, color: Colors.grey.withAlpha(100)),
                  _TraderStatCol(
                    label: l10n.cumTradingDays,
                    value: trader.tradingDays == 0 ? '--' : '${trader.tradingDays}',
                    alignEnd: true,
                  ),
                ],
              ),
            );
          }),
        ],
      ),
    );
  }
}

class _TraderStatCol extends StatelessWidget {
  const _TraderStatCol({
    required this.label,
    required this.value,
    this.valueColor,
    this.center = false,
    this.alignEnd = false,
  });

  final String label;
  final String value;
  final Color? valueColor;
  final bool center;
  final bool alignEnd;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final align = alignEnd
        ? CrossAxisAlignment.end
        : center
            ? CrossAxisAlignment.center
            : CrossAxisAlignment.start;
    return Expanded(
      child: Column(
        crossAxisAlignment: align,
        children: [
          Text(label, style: TextStyle(color: cs.onSurface.withAlpha(130), fontSize: 11)),
          const SizedBox(height: 3),
          Text(value,
              style: TextStyle(
                  color: valueColor ?? cs.onSurface,
                  fontSize: 14,
                  fontWeight: FontWeight.w700)),
        ],
      ),
    );
  }
}

// ── Badge / DataCell ──────────────────────────────────────

class _Badge extends StatelessWidget {
  const _Badge({required this.text, required this.bgColor, required this.textColor, this.borderColor});
  final String text;
  final Color bgColor;
  final Color textColor;
  final Color? borderColor;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3),
      decoration: BoxDecoration(
        color: bgColor,
        borderRadius: BorderRadius.circular(4),
        border: borderColor != null ? Border.all(color: borderColor!, width: 0.8) : null,
      ),
      child: Text(text, style: TextStyle(color: textColor, fontSize: 11, fontWeight: FontWeight.w500)),
    );
  }
}

class _DataCell extends StatelessWidget {
  const _DataCell({required this.label, required this.value, this.valueColor});

  final String label;
  final String value;
  final Color? valueColor;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    return Expanded(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(label, style: TextStyle(color: cs.onSurface.withAlpha(153), fontSize: 11)),
          const SizedBox(height: 2),
          Text(value,
              style: TextStyle(
                  color: valueColor ?? cs.onSurface,
                  fontSize: 13,
                  fontWeight: FontWeight.w500)),
        ],
      ),
    );
  }
}

// ── 骨架屏 ────────────────────────────────────────────────

/// 「我的跟单」首次加载时的全页骨架
class _MyCopyTradingFullSkeleton extends StatelessWidget {
  const _MyCopyTradingFullSkeleton({required this.cardBg});

  final Color cardBg;

  @override
  Widget build(BuildContext context) {
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final cs = Theme.of(context).colorScheme;
    return Column(
      children: [
        // 统计卡片骨架
        AppShimmer(
          child: Container(
            margin: const EdgeInsets.fromLTRB(16, 12, 16, 4),
            padding: const EdgeInsets.fromLTRB(16, 10, 16, 16),
            decoration: BoxDecoration(
              color: AppColors.brand,
              borderRadius: BorderRadius.circular(16),
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [shimmerBox(18, 18), const SizedBox(width: 10), shimmerBox(18, 18)],
                ),
                const SizedBox(height: 8),
                Row(
                  children: List.generate(3, (i) => Expanded(
                    child: Padding(
                      padding: EdgeInsets.only(right: i < 2 ? 12 : 0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          shimmerBox(70, 10),
                          const SizedBox(height: 6),
                          shimmerBox(55, 16),
                        ],
                      ),
                    ),
                  )),
                ),
              ],
            ),
          ),
        ),
        // Tab 骨架
        Container(
          color: cardBg,
          child: AppShimmer(
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
              child: Row(
                children: List.generate(3, (i) => Expanded(
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: i == 1 ? 8.0 : 0),
                    child: shimmerFill(16, radius: 4),
                  ),
                )),
              ),
            ),
          ),
        ),
        Divider(height: 1, thickness: 0.5, color: cs.outlineVariant.withAlpha(80)),
        // 列表骨架
        Expanded(
          child: ListView.builder(
            padding: const EdgeInsets.fromLTRB(0, 8, 0, 16),
            itemCount: 4,
            itemBuilder: (_, __) => const _PositionCardSkeleton(),
          ),
        ),
      ],
    );
  }
}

/// 仓位卡片骨架（对应 _PositionCard 当前跟单样式）
class _PositionCardSkeleton extends StatelessWidget {
  const _PositionCardSkeleton();

  @override
  Widget build(BuildContext context) {
    final isDark = Theme.of(context).brightness == Brightness.dark;
    return AppShimmer(
      child: Container(
        margin: const EdgeInsets.fromLTRB(16, 8, 16, 0),
        padding: const EdgeInsets.all(16),
        decoration: BoxDecoration(
          color: isDark ? AppColors.darkBgSecondary : AppColors.lightBg,
          borderRadius: BorderRadius.circular(16),
          boxShadow: [
            BoxShadow(color: Colors.black.withAlpha(18), blurRadius: 12, offset: const Offset(0, 2)),
          ],
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // 交易员头部行
            Row(
              children: [
                shimmerCircle(38),
                const SizedBox(width: 10),
                Expanded(child: shimmerBox(100, 15)),
                shimmerBox(60, 32, radius: 8),
              ],
            ),
            const SizedBox(height: 10),
            // 品种行
            Row(children: [
              shimmerBox(80, 14),
              const SizedBox(width: 8),
              shimmerBox(60, 20, radius: 4),
              const SizedBox(width: 6),
              shimmerBox(30, 20, radius: 4),
              const SizedBox(width: 6),
              shimmerBox(36, 20, radius: 4),
            ]),
            const SizedBox(height: 10),
            // 数据行 1
            Row(children: List.generate(3, (i) => Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: i < 2 ? 8 : 0),
                child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                  shimmerBox(70, 11),
                  const SizedBox(height: 4),
                  shimmerBox(55, 13),
                ]),
              ),
            ))),
            const SizedBox(height: 8),
            // 数据行 2
            Row(children: List.generate(3, (i) => Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: i < 2 ? 8 : 0),
                child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                  shimmerBox(70, 11),
                  const SizedBox(height: 4),
                  shimmerBox(55, 13),
                ]),
              ),
            ))),
          ],
        ),
      ),
    );
  }
}

/// 我的交易员卡片骨架（对应 _MyTraderCard 样式）
class _MyTraderCardSkeleton extends StatelessWidget {
  const _MyTraderCardSkeleton();

  @override
  Widget build(BuildContext context) {
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final cs = Theme.of(context).colorScheme;
    return AppShimmer(
      child: Container(
        margin: const EdgeInsets.fromLTRB(16, 8, 16, 0),
        padding: const EdgeInsets.all(14),
        decoration: BoxDecoration(
          color: isDark ? AppColors.darkBgSecondary : AppColors.lightBg,
          borderRadius: BorderRadius.circular(12),
          boxShadow: [
            BoxShadow(color: Colors.black.withAlpha(15), blurRadius: 8, offset: const Offset(0, 2)),
          ],
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                shimmerCircle(52),
                const SizedBox(width: 12),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      shimmerBox(110, 15),
                      const SizedBox(height: 6),
                      shimmerBox(160, 12),
                      const SizedBox(height: 8),
                      Row(children: [shimmerBox(55, 22, radius: 20), const SizedBox(width: 6), shimmerBox(45, 22, radius: 20)]),
                    ],
                  ),
                ),
                shimmerBox(72, 30, radius: 20),
              ],
            ),
            const SizedBox(height: 12),
            Divider(height: 1, thickness: 0.5, color: cs.outlineVariant.withAlpha(80)),
            const SizedBox(height: 12),
            Row(
              children: List.generate(3, (i) => Expanded(
                child: Padding(
                  padding: EdgeInsets.symmetric(horizontal: i == 1 ? 8.0 : 0),
                  child: Column(
                    crossAxisAlignment: i == 0
                        ? CrossAxisAlignment.start
                        : i == 1 ? CrossAxisAlignment.center : CrossAxisAlignment.end,
                    children: [
                      shimmerBox(55, 11),
                      const SizedBox(height: 5),
                      shimmerBox(40, 14),
                    ],
                  ),
                ),
              )),
            ),
          ],
        ),
      ),
    );
  }
}

// ── 空状态 ────────────────────────────────────────────────

class _EmptyState extends StatelessWidget {
  const _EmptyState({this.onGoMarket});

  final VoidCallback? onGoMarket;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(Icons.people_alt_outlined, size: 64, color: cs.onSurface.withAlpha(80)),
          const SizedBox(height: 16),
          Text(AppLocalizations.of(context)!.noData, style: TextStyle(color: cs.onSurface.withAlpha(153), fontSize: 15)),
        ],
      ),
    );
  }
}
