import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';

import '../../../core/l10n/app_localizations.dart';
import '../../../core/network/dio_client.dart';
import '../../../core/theme/app_colors.dart';
import '../../../data/services/futures_service.dart';
import '../../widgets/common/app_refresh_indicator.dart';
import '../../widgets/common/app_shimmer.dart';
import '../../widgets/common/app_tab_bar.dart';

// ── 分页状态 ────────────────────────────────────────────────

class _PageState {
  final List<Map<String, dynamic>> items;
  final bool isLoading;
  final bool hasMore;
  final int page;
  final String? error;

  const _PageState({
    this.items = const [],
    this.isLoading = false,
    this.hasMore = true,
    this.page = 0,
    this.error,
  });

  _PageState copyWith({
    List<Map<String, dynamic>>? items,
    bool? isLoading,
    bool? hasMore,
    int? page,
    String? error,
  }) =>
      _PageState(
        items: items ?? this.items,
        isLoading: isLoading ?? this.isLoading,
        hasMore: hasMore ?? this.hasMore,
        page: page ?? this.page,
        error: error,
      );
}

// ── 历史持仓分页 Notifier ───────────────────────────────────

class _PositionHistoryNotifier
    extends AutoDisposeNotifier<_PageState> {
  static const _pageSize = 10;

  @override
  _PageState build() {
    Future.microtask(loadMore);
    return const _PageState();
  }

  Future<void> loadMore() async {
    final s = state;
    if (s.isLoading || !s.hasMore) return;
    state = s.copyWith(isLoading: true);
    try {
      final svc = FuturesService(ref.read(dioClientProvider));
      final result = await svc.getPositionHistory(
        pageNo: s.page + 1,
        pageSize: _pageSize,
      );
      state = state.copyWith(
        items: [...s.items, ...result.items],
        hasMore: result.hasMore,
        page: s.page + 1,
        isLoading: false,
      );
    } catch (e) {
      state = state.copyWith(isLoading: false, error: e.toString());
    }
  }

  Future<void> refresh() async {
    state = const _PageState();
    await loadMore();
  }
}

final _positionHistoryProvider =
    NotifierProvider.autoDispose<_PositionHistoryNotifier, _PageState>(
  _PositionHistoryNotifier.new,
);

// ── 历史委托分页 Notifier ───────────────────────────────────
// 使用 history-all 接口，一次返回所有历史委托（ContractOrderEntrust）
// 包含：开仓委托（含撤销/失败）+ 平仓委托（成功）

class _OrderHistoryNotifier
    extends AutoDisposeNotifier<_PageState> {
  static const _pageSize = 10;

  @override
  _PageState build() {
    Future.microtask(loadMore);
    return const _PageState();
  }

  Future<void> loadMore() async {
    final s = state;
    if (s.isLoading || !s.hasMore) return;
    state = s.copyWith(isLoading: true);
    try {
      final svc = FuturesService(ref.read(dioClientProvider));
      final nextPage = s.page + 1;
      final result = await svc.getOrderHistoryAll(
        pageNo: nextPage,
        pageSize: _pageSize,
      );
      state = state.copyWith(
        items: [...s.items, ...result.items],
        hasMore: result.hasMore,
        page: nextPage,
        isLoading: false,
      );
    } catch (e) {
      state = state.copyWith(isLoading: false, error: e.toString());
    }
  }

  Future<void> refresh() async {
    state = const _PageState();
    await loadMore();
  }
}

final _orderHistoryProvider =
    NotifierProvider.autoDispose<_OrderHistoryNotifier, _PageState>(
  _OrderHistoryNotifier.new,
);

// ── Screen ─────────────────────────────────────────────────

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

  @override
  ConsumerState<FuturesHistoryScreen> createState() =>
      _FuturesHistoryScreenState();
}

class _FuturesHistoryScreenState extends ConsumerState<FuturesHistoryScreen>
    with SingleTickerProviderStateMixin {
  late final TabController _tabCtrl;
  late final PageController _pageCtrl;

  @override
  void initState() {
    super.initState();
    _tabCtrl = TabController(length: 2, vsync: this);
    _pageCtrl = PageController();
    // Tab 点击 → 驱动 PageView 动画
    _tabCtrl.addListener(() {
      if (!_tabCtrl.indexIsChanging) return;
      _pageCtrl.animateToPage(
        _tabCtrl.index,
        duration: const Duration(milliseconds: 280),
        curve: Curves.easeOut,
      );
    });
    // 拖动 PageView → 实时更新指示器 offset（平滑插值）
    _pageCtrl.addListener(() {
      if (!_pageCtrl.hasClients) return;
      if (_tabCtrl.indexIsChanging) return;
      final page = _pageCtrl.page!;
      final offset = page - _tabCtrl.index;
      if (offset.abs() <= 1.0) {
        _tabCtrl.offset = offset.clamp(-1.0, 1.0);
      }
    });
  }

  @override
  void dispose() {
    _tabCtrl.dispose();
    _pageCtrl.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final isDark = Theme.of(context).brightness == Brightness.dark;
    return Scaffold(
      backgroundColor:
          isDark ? AppColors.darkBg : AppColors.lightBgSecondary,
      appBar: AppBar(
        backgroundColor: isDark ? AppColors.darkBgSecondary : Colors.white,
        elevation: 0,
        leading: IconButton(
          icon: Icon(Icons.chevron_left, color: cs.onSurface, size: 28),
          onPressed: () => Navigator.pop(context),
        ),
        title: TabBar(
          controller: _tabCtrl,
          tabs: [
            Tab(text: AppLocalizations.of(context)!.historicalPositions),
            Tab(text: AppLocalizations.of(context)!.historicalOrders),
          ],
          indicator: StretchTabIndicator(
            controller: _tabCtrl,
            color: AppColors.brand,
          ),
          indicatorSize: TabBarIndicatorSize.label,
          dividerColor: Colors.transparent,
        ),
        titleSpacing: 0,
        bottom: PreferredSize(
          preferredSize: const Size.fromHeight(1),
          child: Divider(
            height: 1,
            color: isDark ? AppColors.darkDivider : AppColors.lightDivider,
          ),
        ),
      ),
      body: PageView(
        controller: _pageCtrl,
        physics: const BouncingScrollPhysics(
          parent: AlwaysScrollableScrollPhysics(),
        ),
        onPageChanged: (index) {
          if (_tabCtrl.indexIsChanging) return;
          _tabCtrl.index = index;
        },
        children: const [
          _PositionHistoryTab(),
          _OrderHistoryTab(),
        ],
      ),
    );
  }
}

// ── 历史持仓 Tab ──────────────────────────────────────────

class _PositionHistoryTab extends ConsumerStatefulWidget {
  const _PositionHistoryTab();

  @override
  ConsumerState<_PositionHistoryTab> createState() =>
      _PositionHistoryTabState();
}

class _PositionHistoryTabState extends ConsumerState<_PositionHistoryTab> {
  final _scroll = ScrollController();

  @override
  void initState() {
    super.initState();
    _scroll.addListener(_onScroll);
  }

  @override
  void dispose() {
    _scroll.removeListener(_onScroll);
    _scroll.dispose();
    super.dispose();
  }

  void _onScroll() {
    if (_scroll.position.pixels >=
        _scroll.position.maxScrollExtent - 200) {
      ref.read(_positionHistoryProvider.notifier).loadMore();
    }
  }

  @override
  Widget build(BuildContext context) {
    final s = ref.watch(_positionHistoryProvider);
    if (s.items.isEmpty && s.isLoading) {
      return const _HistoryListShimmer(isPosition: true);
    }
    if (s.items.isEmpty && !s.isLoading) {
      return _EmptyHint(message: s.error != null ? AppLocalizations.of(context)!.loadFailedRetry : null);
    }
    return AppRefreshIndicator(
      onRefresh: () =>
          ref.read(_positionHistoryProvider.notifier).refresh(),
      child: ListView.separated(
        controller: _scroll,
        padding: const EdgeInsets.fromLTRB(12, 12, 12, 24),
        itemCount: s.items.length + 1,
        separatorBuilder: (_, __) => const SizedBox(height: 12),
        itemBuilder: (ctx, i) {
          if (i == s.items.length) {
            return _LoadMoreFooter(isLoading: s.isLoading, hasMore: s.hasMore);
          }
          return _PositionHistoryCard(data: s.items[i]);
        },
      ),
    );
  }
}

// ── 历史委托 Tab ──────────────────────────────────────────

class _OrderHistoryTab extends ConsumerStatefulWidget {
  const _OrderHistoryTab();

  @override
  ConsumerState<_OrderHistoryTab> createState() => _OrderHistoryTabState();
}

class _OrderHistoryTabState extends ConsumerState<_OrderHistoryTab> {
  final _scroll = ScrollController();

  @override
  void initState() {
    super.initState();
    _scroll.addListener(_onScroll);
  }

  @override
  void dispose() {
    _scroll.removeListener(_onScroll);
    _scroll.dispose();
    super.dispose();
  }

  void _onScroll() {
    if (_scroll.position.pixels >=
        _scroll.position.maxScrollExtent - 200) {
      ref.read(_orderHistoryProvider.notifier).loadMore();
    }
  }

  @override
  Widget build(BuildContext context) {
    final s = ref.watch(_orderHistoryProvider);
    if (s.items.isEmpty && s.isLoading) {
      return const _HistoryListShimmer(isPosition: false);
    }
    if (s.items.isEmpty && !s.isLoading) {
      return _EmptyHint(message: s.error != null ? AppLocalizations.of(context)!.loadFailedRetry : null);
    }
    return AppRefreshIndicator(
      onRefresh: () =>
          ref.read(_orderHistoryProvider.notifier).refresh(),
      child: ListView.separated(
        controller: _scroll,
        padding: const EdgeInsets.fromLTRB(12, 12, 12, 24),
        itemCount: s.items.length + 1,
        separatorBuilder: (_, __) => const SizedBox(height: 12),
        itemBuilder: (ctx, i) {
          if (i == s.items.length) {
            return _LoadMoreFooter(isLoading: s.isLoading, hasMore: s.hasMore);
          }
          return _OrderHistoryCard(data: s.items[i]);
        },
      ),
    );
  }
}

// ── 持仓历史卡片 ──────────────────────────────────────────

class _PositionHistoryCard extends StatelessWidget {
  const _PositionHistoryCard({required this.data});
  final Map<String, dynamic> data;

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

    // symbol 优先读嵌套 coin 对象（持仓历史结构），兼容委托历史平铺字段
    final coinObj = data['coin'] as Map<String, dynamic>?;
    final symbol = _str(coinObj?['symbol'] ?? data['symbol'] ?? data['coinSymbol'] ?? '');
    final dirInfo = _directionInfo(data['direction'], null, l10n);
    final dirColor = dirInfo.isGreen ? AppColors.rise : AppColors.fall;
    final openTypeLabel = _mapOrderType(data['openType'], l10n);
    final closeTypeLabel = _mapCloseType(data['closeType'], l10n);
    final leverage = (_toDouble(data['leverage'] ?? 0)).toInt();
    final positionTypeLabel = _mapPositionType(
        data['type'] ?? data['positionType'], data['patterns'], l10n);
    final positionTypeTagColor = _positionTypeColor(
        data['type'] ?? data['positionType'], data['patterns']);
    final status = _str(data['status'] ?? '');
    final statusLabel = _mapStatus(status, l10n, isPosition: true);
    final statusColor = _statusColor(status);

    final coinLabel = symbol.contains('/')
        ? symbol.split('/').first
        : symbol.replaceAll(RegExp(r'USDT$|BUSD$|BTC$|ETH$'), '').isNotEmpty
            ? symbol.replaceAll(RegExp(r'USDT$|BUSD$'), '')
            : coinObj?['coinSymbol']?.toString() ?? 'BTC';
    final totalVolume = _toDouble(data['totalPosition'] ?? data['volume'] ?? 0);
    final dealVolume = _toDouble(data['closedPosition'] ?? data['tradedVolume'] ?? data['dealVolume'] ?? 0);
    final openAvgPrice = _toDouble(data['openPrice'] ?? data['usdtOpenPrice'] ?? 0);
    final closeAvgPrice = _toDouble(data['closePrice'] ?? data['tradedPrice'] ?? 0);
    final profitLoss = _toDouble(data['usdtProfit'] ?? data['profitAndLoss'] ?? 0);
    final totalPrincipal = _toDouble(data['totalPrincipalAmount'] ?? data['principalAmount'] ?? 0);
    final profitRate =
        totalPrincipal > 0 ? (profitLoss / totalPrincipal * 100) : 0.0;

    final openTime = _formatTime(data['openTime'] ?? data['usdtOpenTime'] ?? data['createTime']);
    final closeTime = _formatTime(data['closeTime'] ?? data['dealTime']);

    final cardBg = isDark ? AppColors.darkBgSecondary : Colors.white;
    final dividerColor =
        isDark ? AppColors.darkDivider : AppColors.lightDivider;

    return GestureDetector(
      onTap: () {
        final uri = GoRouterState.of(context).uri.toString();
        context.push('$uri/position-detail', extra: data);
      },
      child: Container(
      decoration: BoxDecoration(
        color: cardBg,
        borderRadius: BorderRadius.circular(12),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withAlpha(isDark ? 40 : 15),
            blurRadius: 6,
            offset: const Offset(0, 1),
          ),
        ],
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // ── 头部：币对名 + 状态 ─────────────────────────
          Padding(
            padding: const EdgeInsets.fromLTRB(14, 14, 14, 10),
            child: Row(
              children: [
                Expanded(
                  child: Row(
                    children: [
                      Text(
                        symbol.isNotEmpty ? '$symbol ${AppLocalizations.of(context)!.perpetual}' : '--',
                        style: TextStyle(
                          color: cs.onSurface,
                          fontSize: 15,
                          fontWeight: FontWeight.w700,
                        ),
                      ),
                      const SizedBox(width: 2),
                      Icon(Icons.chevron_right,
                          color: cs.onSurface.withAlpha(100), size: 16),
                    ],
                  ),
                ),
                Text(
                  statusLabel,
                  style: TextStyle(
                    color: statusColor,
                    fontSize: 13,
                    fontWeight: FontWeight.w600,
                  ),
                ),
              ],
            ),
          ),
          // ── 标签行 ─────────────────────────────────────
          Padding(
            padding: const EdgeInsets.fromLTRB(14, 0, 14, 12),
            child: Wrap(
              spacing: 6,
              runSpacing: 6,
              children: [
                _Tag(label: dirInfo.label, tagStyle: _TagStyle.direction, color: dirColor),
                if (openTypeLabel.isNotEmpty)
                  _Tag(label: openTypeLabel, tagStyle: _TagStyle.orderType),
                if (closeTypeLabel.isNotEmpty)
                  _Tag(label: closeTypeLabel, tagStyle: _TagStyle.closeType),
                _Tag(label: positionTypeLabel, tagStyle: _TagStyle.positionType, color: positionTypeTagColor),
                if (leverage > 0)
                  _Tag(label: '${leverage}x', tagStyle: _TagStyle.gray),
              ],
            ),
          ),
          Divider(height: 1, color: dividerColor),
          // ── 数据行 1：委托总量 | 开仓均价 | 收益 ──────────
          Padding(
            padding: const EdgeInsets.fromLTRB(14, 10, 14, 6),
            child: Row(
              children: [
                _DataField(
                  label: '${l10n.entrustTotal}($coinLabel)',
                  value: _rawNum(totalVolume),
                  align: CrossAxisAlignment.start,
                ),
                _DataField(
                  label: '${l10n.openAvgPrice}(USDT)',
                  value: openAvgPrice > 0 ? _rawNum(openAvgPrice) : '--',
                  align: CrossAxisAlignment.center,
                ),
                _DataField(
                  label: '${l10n.profitLabel}(USDT)',
                  value: profitLoss != 0
                      ? '${profitLoss >= 0 ? '+' : ''}${_rawNum(profitLoss)}'
                      : '--',
                  valueColor: profitLoss != 0
                      ? AppColors.changeColor(profitLoss)
                      : null,
                  align: CrossAxisAlignment.end,
                ),
              ],
            ),
          ),
          // ── 数据行 2：已成交量 | 平仓均价 | 收益率 ─────────
          Padding(
            padding: const EdgeInsets.fromLTRB(14, 0, 14, 12),
            child: Row(
              children: [
                _DataField(
                  label: '${l10n.filledVolume}($coinLabel)',
                  value: _rawNum(dealVolume),
                  align: CrossAxisAlignment.start,
                ),
                _DataField(
                  label: '${l10n.closeAvgPrice}(USDT)',
                  value: closeAvgPrice > 0 ? _rawNum(closeAvgPrice) : '--',
                  align: CrossAxisAlignment.center,
                ),
                _DataField(
                  label: l10n.profitRateLabel,
                  value: profitRate != 0
                      ? '${profitRate >= 0 ? '+' : ''}${profitRate.toStringAsFixed(2)}%'
                      : '--',
                  valueColor: profitRate != 0
                      ? AppColors.changeColor(profitRate)
                      : null,
                  align: CrossAxisAlignment.end,
                ),
              ],
            ),
          ),
          Divider(height: 1, color: dividerColor),
          // ── 时间行 ─────────────────────────────────────
          Padding(
            padding: const EdgeInsets.fromLTRB(14, 10, 14, 12),
            child: Row(
              children: [
                Expanded(
                  child: _TimeBlock(
                    label: l10n.openTime,
                    time: openTime,
                    align: CrossAxisAlignment.start,
                  ),
                ),
                _TimeBlock(
                  label: l10n.closeTime,
                  time: closeTime,
                  align: CrossAxisAlignment.end,
                ),
              ],
            ),
          ),
        ],
      ),
    ),
    );
  }
}

// ── 委托历史卡片 ──────────────────────────────────────────

class _OrderHistoryCard extends StatelessWidget {
  const _OrderHistoryCard({required this.data});
  final Map<String, dynamic> data;

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

    final l10n = AppLocalizations.of(context)!;
    // history-all 返回 ContractOrderEntrust，symbol 直接在顶层
    final symbol = _str(data['symbol'] ?? data['coinSymbol'] ?? '');
    final dirInfo = _directionInfo(data['direction'], data['entrustType'], l10n);
    final dirColor = dirInfo.isGreen ? AppColors.rise : AppColors.fall;
    final openTypeLabel = _mapOrderType(data['type'], l10n);
    final leverage = (_toDouble(data['leverage'] ?? 0)).toInt();
    final positionTypeLabel = _mapPositionType(
        data['positionType'], data['patterns'], l10n);
    final positionTypeTagColor = _positionTypeColor(
        data['positionType'], data['patterns']);
    final status = _str(data['status'] ?? '');
    final statusLabel = _mapStatus(status, l10n);
    final statusColor = _statusColor(status);

    final coinLabel = symbol.contains('/')
        ? symbol.split('/').first
        : symbol.replaceAll(RegExp(r'USDT$|BUSD$'), '').isNotEmpty
            ? symbol.replaceAll(RegExp(r'USDT$|BUSD$'), '')
            : _str(data['coinSymbol'] ?? 'BTC');
    final volume = _toDouble(data['volume'] ?? 0);
    final dealVolume = _toDouble(data['tradedVolume'] ?? 0);
    final entrustPrice = _toDouble(data['entrustPrice'] ?? 0);
    // 开仓均价：开仓单用 tradedPrice（成交均价）；平仓单用 usdtOpenPrice（原仓位开仓均价）
    final entrustTypeRaw = (data['entrustType']?.toString() ?? '').toUpperCase();
    final isCloseOrd = entrustTypeRaw == '1' || entrustTypeRaw == 'CLOSE';
    final openAvgPrice = isCloseOrd
        ? _toDouble(data['usdtOpenPrice'] ?? data['openPrice'] ?? 0)
        : _toDouble(data['tradedPrice'] ?? data['usdtOpenPrice'] ?? 0);
    final createTime = _formatTime(data['createTime']);
    final dealTime = _formatTime(data['dealTime']);

    // 委托价格：市价/计划市价→"市价"，限价/计划限价→显示原始委托价
    final typeRaw = data['type'];
    final entrustPriceStr = _showMarketPrice(typeRaw, entrustPrice)
        ? l10n.marketOrderType
        : (entrustPrice > 0 ? _rawNum(entrustPrice) : '--');

    final cardBg = isDark ? AppColors.darkBgSecondary : Colors.white;
    final dividerColor =
        isDark ? AppColors.darkDivider : AppColors.lightDivider;

    return GestureDetector(
      onTap: () {
        final uri = GoRouterState.of(context).uri.toString();
        context.push('$uri/order-detail', extra: data);
      },
      child: Container(
      decoration: BoxDecoration(
        color: cardBg,
        borderRadius: BorderRadius.circular(12),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withAlpha(isDark ? 40 : 15),
            blurRadius: 6,
            offset: const Offset(0, 1),
          ),
        ],
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // ── 头部：币对名 + 状态 ─────────────────────────
          Padding(
            padding: const EdgeInsets.fromLTRB(14, 14, 14, 10),
            child: Row(
              children: [
                Expanded(
                  child: Row(
                    children: [
                      Text(
                        symbol.isNotEmpty ? '$symbol ${AppLocalizations.of(context)!.perpetual}' : '--',
                        style: TextStyle(
                          color: cs.onSurface,
                          fontSize: 15,
                          fontWeight: FontWeight.w700,
                        ),
                      ),
                      const SizedBox(width: 2),
                      Icon(Icons.chevron_right,
                          color: cs.onSurface.withAlpha(100), size: 16),
                    ],
                  ),
                ),
                Text(
                  statusLabel,
                  style: TextStyle(
                    color: statusColor,
                    fontSize: 13,
                    fontWeight: FontWeight.w600,
                  ),
                ),
              ],
            ),
          ),
          // ── 标签行 ─────────────────────────────────────
          Padding(
            padding: const EdgeInsets.fromLTRB(14, 0, 14, 12),
            child: Wrap(
              spacing: 6,
              runSpacing: 6,
              children: [
                _Tag(label: dirInfo.label, tagStyle: _TagStyle.direction, color: dirColor),
                if (openTypeLabel.isNotEmpty)
                  _Tag(label: openTypeLabel, tagStyle: _TagStyle.orderType),
                _Tag(label: positionTypeLabel, tagStyle: _TagStyle.positionType, color: positionTypeTagColor),
                if (leverage > 0)
                  _Tag(label: '${leverage}x', tagStyle: _TagStyle.gray),
              ],
            ),
          ),
          Divider(height: 1, color: dividerColor),
          // ── 数据行 1：委托总量 | 开仓均价 ──────────────────
          Padding(
            padding: const EdgeInsets.fromLTRB(14, 10, 14, 6),
            child: Row(
              children: [
                _DataField(
                  label: '${l10n.entrustTotal}($coinLabel)',
                  value: _rawNum(volume),
                  align: CrossAxisAlignment.start,
                ),
                _DataField(
                  label: '${l10n.openAvgPrice}(USDT)',
                  value: openAvgPrice > 0 ? _rawNum(openAvgPrice) : '--',
                  align: CrossAxisAlignment.end,
                ),
              ],
            ),
          ),
          // ── 数据行 2：已成交量 | 委托价格 ──────────────────
          Padding(
            padding: const EdgeInsets.fromLTRB(14, 0, 14, 12),
            child: Row(
              children: [
                _DataField(
                  label: '${l10n.filledVolume}($coinLabel)',
                  value: _rawNum(dealVolume),
                  align: CrossAxisAlignment.start,
                ),
                _DataField(
                  label: '${l10n.orderPriceLabel}(USDT)',
                  value: entrustPriceStr,
                  align: CrossAxisAlignment.end,
                ),
              ],
            ),
          ),
          Divider(height: 1, color: dividerColor),
          // ── 时间行 ─────────────────────────────────────
          Padding(
            padding: const EdgeInsets.fromLTRB(14, 10, 14, 12),
            child: Row(
              children: [
                Expanded(
                  child: _TimeBlock(
                    label: l10n.orderTime,
                    time: createTime,
                    align: CrossAxisAlignment.start,
                  ),
                ),
                _TimeBlock(
                  label: l10n.closeTime,
                  time: dealTime,
                  align: CrossAxisAlignment.end,
                ),
              ],
            ),
          ),
        ],
      ),
    ),
    );
  }
}

// ── 加载更多底部组件 ───────────────────────────────────────

class _LoadMoreFooter extends StatelessWidget {
  const _LoadMoreFooter({required this.isLoading, required this.hasMore});
  final bool isLoading;
  final bool hasMore;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    if (isLoading) {
      return const Padding(
        padding: EdgeInsets.symmetric(vertical: 16),
        child: Center(child: CircularProgressIndicator(strokeWidth: 2)),
      );
    }
    if (!hasMore) {
      return Padding(
        padding: const EdgeInsets.symmetric(vertical: 16),
        child: Center(
          child: Text(AppLocalizations.of(context)!.allLoaded,
              style: TextStyle(
                  color: cs.onSurface.withAlpha(100), fontSize: 12)),
        ),
      );
    }
    return const SizedBox(height: 16);
  }
}

// ── Tag 样式枚举 ───────────────────────────────────────────

enum _TagStyle { direction, orderType, closeType, gray, positionType }

// ── 通用辅助 Widgets ──────────────────────────────────────

class _Tag extends StatelessWidget {
  const _Tag({
    required this.label,
    required this.tagStyle,
    this.color,
  });
  final String label;
  final _TagStyle tagStyle;
  final Color? color; // 仅 direction 使用

  static const _blue = AppColors.tagBlue;

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

    Color bgColor;
    Color textColor;

    switch (tagStyle) {
      case _TagStyle.direction:
        final c = color ?? AppColors.rise;
        bgColor = c.withAlpha(30);
        textColor = c;
      case _TagStyle.orderType:
        bgColor = _blue.withAlpha(isDark ? 50 : 30);
        textColor = _blue;
      case _TagStyle.closeType:
        bgColor = isDark ? AppColors.darkBgTertiary : AppColors.darkBgMid;
        textColor = isDark ? AppColors.darkTextSecondary : Colors.white;
      case _TagStyle.gray:
        bgColor = isDark
            ? AppColors.darkBgTertiary
            : AppColors.lightBgTertiary;
        textColor = isDark
            ? AppColors.darkTextSecondary
            : AppColors.lightTextSecondary;
      case _TagStyle.positionType:
        final c = color ?? AppColors.tagBlue;
        bgColor = c.withAlpha(isDark ? 45 : 25);
        textColor = c;
    }

    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
      decoration: BoxDecoration(
        color: bgColor,
        borderRadius: BorderRadius.circular(4),
      ),
      child: Text(
        label,
        style: TextStyle(
          color: textColor,
          fontSize: 11,
          fontWeight: FontWeight.w500,
        ),
      ),
    );
  }
}

/// 数据字段（标签 + 值），支持左/中/右对齐
class _DataField extends StatelessWidget {
  const _DataField({
    required this.label,
    required this.value,
    this.valueColor,
    this.align = CrossAxisAlignment.start,
  });
  final String label;
  final String value;
  final Color? valueColor;
  final CrossAxisAlignment align;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final secondaryText =
        isDark ? AppColors.darkTextSecondary : AppColors.lightTextSecondary;

    TextAlign textAlign;
    if (align == CrossAxisAlignment.center) {
      textAlign = TextAlign.center;
    } else if (align == CrossAxisAlignment.end) {
      textAlign = TextAlign.right;
    } else {
      textAlign = TextAlign.left;
    }

    return Expanded(
      child: Column(
        crossAxisAlignment: align,
        children: [
          Text(
            label,
            style: TextStyle(color: secondaryText, fontSize: 11),
            textAlign: textAlign,
          ),
          const SizedBox(height: 3),
          Text(
            value,
            style: TextStyle(
              color: valueColor ?? cs.onSurface,
              fontSize: 13,
              fontWeight: FontWeight.w600,
            ),
            textAlign: textAlign,
          ),
        ],
      ),
    );
  }
}

/// 时间块（标签 + 时间值加粗）
class _TimeBlock extends StatelessWidget {
  const _TimeBlock({
    required this.label,
    required this.time,
    this.align = CrossAxisAlignment.start,
  });
  final String label;
  final String time;
  final CrossAxisAlignment align;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final secondaryText =
        isDark ? AppColors.darkTextSecondary : AppColors.lightTextSecondary;

    final textAlign = align == CrossAxisAlignment.end
        ? TextAlign.right
        : TextAlign.left;

    return Column(
      crossAxisAlignment: align,
      children: [
        Text(
          label,
          style: TextStyle(color: secondaryText, fontSize: 11),
          textAlign: textAlign,
        ),
        const SizedBox(height: 3),
        Text(
          time,
          style: TextStyle(
            color: cs.onSurface,
            fontSize: 12,
            fontWeight: FontWeight.w700,
          ),
          textAlign: textAlign,
        ),
      ],
    );
  }
}

class _EmptyHint extends StatelessWidget {
  const _EmptyHint({this.message});
  final String? message;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(Icons.history_outlined,
              color: cs.onSurface.withAlpha(80), size: 48),
          const SizedBox(height: 8),
          Text(message ?? AppLocalizations.of(context)!.noRecord,
              style: TextStyle(
                  color: cs.onSurface.withAlpha(120), fontSize: 13)),
        ],
      ),
    );
  }
}

// ── 工具函数 ───────────────────────────────────────────────

String _str(dynamic v) => v?.toString() ?? '';

double _toDouble(dynamic v) {
  if (v == null) return 0.0;
  if (v is num) return v.toDouble();
  return double.tryParse(v.toString()) ?? 0.0;
}

/// 去除多余的尾零，整数不带小数点
String _rawNum(double v) {
  if (v == v.truncateToDouble()) return v.toInt().toString();
  return v.toString();
}

({String label, bool isGreen}) _directionInfo(
    dynamic direction, dynamic entrustType, AppLocalizations l10n) {
  // direction: 0/"BUY" = 买；1/"SELL" = 卖
  final dirRaw = direction?.toString() ?? '';
  final isBuy = dirRaw == '0' || dirRaw.toUpperCase() == 'BUY';
  // entrustType: null/0/"OPEN" = 开仓；1/"CLOSE" = 平仓
  final etRaw = entrustType?.toString() ?? '';
  final isClose = etRaw == '1' || etRaw.toUpperCase() == 'CLOSE';

  if (!isClose) {
    return isBuy
        ? (label: l10n.longBull, isGreen: true)
        : (label: l10n.shortBear, isGreen: false);
  } else {
    // 平仓委托方向与仓位方向相反：BUY+CLOSE=平空(绿)，SELL+CLOSE=平多(红)
    return isBuy
        ? (label: l10n.closeBull, isGreen: true)
        : (label: l10n.closeBear, isGreen: false);
  }
}

String _mapOrderType(dynamic raw, AppLocalizations l10n) {
  if (raw == null) return '';
  final s = raw.toString();
  switch (s) {
    case '0':
    case 'MARKET_PRICE':
    case 'MARKET':
      return l10n.marketOrderLabel;
    case '1':
    case 'LIMIT_PRICE':
    case 'LIMIT':
      return l10n.limitOrderLabel;
    case '2':
    case 'STOP':
    case 'PLAN':
    case 'SPOT_LIMIT':
      return l10n.planOrderLabel;
    case '3':
      return l10n.mergeOrderLabel;
    default:
      return s.isNotEmpty ? s : '';
  }
}

String _mapCloseType(dynamic raw, AppLocalizations l10n) {
  if (raw == null) return '';
  final s = raw.toString();
  switch (s) {
    case '0':
    case 'CLOSE':          return l10n.closePosition;
    case '1':
    case 'MARKET_CLOSE':   return l10n.closePositionMarket;
    case '2':
    case 'ONE_KEY_CLOSE':  return l10n.closeAll;
    case '3':
    case 'REVERSE_OPEN':   return l10n.reverseOpen;
    case '4':
    case 'CUT':            return l10n.stopProfitLoss;
    case '5':
    case 'BLAST':          return l10n.liquidationLabel;
    case '6':
    case 'ADMIN_CLOSE':    return l10n.adminForceClose;
    default: return s.isNotEmpty ? s : '';
  }
}

String _mapPositionType(
    dynamic positionType, dynamic patterns, AppLocalizations l10n) {
  final pt = (positionType?.toString() ?? '').toUpperCase();
  // 0/INTEGRAL=全仓，1/SEPARATE=分仓
  if (pt == '0' || pt == 'INTEGRAL') return l10n.crossMargin;
  if (pt == '1' || pt == 'SEPARATE') return l10n.splitMargin;
  final p = (patterns?.toString() ?? '').toUpperCase();
  if (p == 'CROSSED') return l10n.crossMargin;
  if (p == 'ISOLATED' || p == 'SEPARATE') return l10n.splitMargin;
  return l10n.crossMargin;
}

/// 根据原始 positionType / patterns 返回标签颜色
Color _positionTypeColor(dynamic positionType, dynamic patterns) {
  final pt = (positionType?.toString() ?? '').toUpperCase();
  if (pt == '1' || pt == 'SEPARATE') return AppColors.rankPurple; // 分仓
  final p = (patterns?.toString() ?? '').toUpperCase();
  if (p == 'ISOLATED' || p == 'SEPARATE') return AppColors.rankPurple; // 分仓
  return AppColors.tagBlue; // 全仓
}

String _mapStatus(String status, AppLocalizations l10n, {bool isPosition = false}) {
  switch (status.toUpperCase()) {
    case 'ENTRUST_ING':
    case 'OPEN':
    case 'STARTED':
      return l10n.orderPending;
    case 'ENTRUST_SUCCESS':
    case 'FILLED':
    case 'DONE':        // MemberContractPosition: 全部平仓
    case 'PARTLYDONE':  // MemberContractPosition: 部分平仓
      return isPosition ? l10n.tradingSuccess : l10n.orderFilled;
    case 'ENTRUST_CANCEL':
    case 'CANCELLED':
      return l10n.orderCancelledLabel;
    case 'ENTRUST_FAILURE':
    case 'FAILED':
      return l10n.orderFailedLabel;
    default:
      return status.isNotEmpty
          ? status
          : (isPosition ? l10n.tradingSuccess : l10n.orderFilled);
  }
}

Color _statusColor(String status) {
  switch (status.toUpperCase()) {
    // 成功/进行中 → 绿色
    case 'ENTRUST_SUCCESS':
    case 'FILLED':
    case 'DONE':
    case 'PARTLYDONE':
    case 'ENTRUST_ING':
    case 'OPEN':
    case 'STARTED':
      return AppColors.rise;
    // 撤销/失败 → 红色
    case 'ENTRUST_CANCEL':
    case 'CANCELLED':
    case 'ENTRUST_FAILURE':
    case 'FAILED':
      return AppColors.fall;
    default:
      return AppColors.fall;
  }
}

/// 判断是否为市价单（type=0/MARKET）
bool _isMarketType(dynamic raw) {
  if (raw == null) return false;
  final s = raw.toString();
  return s == '0' || s == 'MARKET_PRICE' || s == 'MARKET';
}

/// 是否展示"市价"：普通市价，或计划委托 entrustPrice=0（计划市价）
bool _showMarketPrice(dynamic type, double entrustPrice) {
  if (_isMarketType(type)) return true;
  final s = (type?.toString() ?? '').toUpperCase();
  final isPlan = s == '2' || s == 'SPOT_LIMIT' || s == 'PLAN';
  return isPlan && entrustPrice == 0;
}

String _formatTime(dynamic raw) {
  if (raw == null) return '--';
  final ts = raw is num ? raw.toInt() : int.tryParse(raw.toString());
  if (ts == null || ts == 0) return '--';
  final dt = DateTime.fromMillisecondsSinceEpoch(ts);
  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 se = dt.second.toString().padLeft(2, '0');
  return '${dt.year}-$mo-$d $h:$mi:$se';
}

// ═══════════════════════════════════════════════════════════
// 历史持仓详情页
// ═══════════════════════════════════════════════════════════

class PositionHistoryDetailScreen extends StatelessWidget {
  const PositionHistoryDetailScreen({super.key, required this.data});
  final Map<String, dynamic> data;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final l10n = AppLocalizations.of(context)!;

    final coinObj = data['coin'] as Map<String, dynamic>?;
    final rawSym = _str(coinObj?['symbol'] ?? data['symbol'] ?? data['coinSymbol'] ?? '');
    final coinLabel = rawSym.contains('/')
        ? rawSym.split('/').first
        : rawSym.replaceAll(RegExp(r'USDT$|BUSD$'), '').isNotEmpty
            ? rawSym.replaceAll(RegExp(r'USDT$|BUSD$'), '')
            : coinObj?['coinSymbol']?.toString() ?? 'BTC';
    final posType = _mapPositionType(
        data['type'] ?? data['positionType'], data['patterns'], l10n);
    // 持仓详情无 entrustType，按仓位方向显示
    final dirInfo = _directionInfo(data['direction'], null, l10n);
    final dirColor = dirInfo.isGreen ? AppColors.rise : AppColors.fall;
    final orderType = _mapOrderType(data['openType'] ?? data['type'], l10n);
    final leverage = (_toDouble(data['leverage'])).toInt();
    final openTime = _formatTime(data['openTime'] ?? data['usdtOpenTime'] ?? data['createTime']);
    final closeTime = _formatTime(data['closeTime'] ?? data['dealTime']);

    final triggerPrice = _toDouble(data['triggerPrice']);
    final entrustPrice = _toDouble(data['entrustPrice']);
    final openAvgPrice = _toDouble(data['openPrice'] ?? data['usdtOpenPrice']);
    final closeAvgPrice = _toDouble(data['closePrice'] ?? data['tradedPrice']);
    final profitPrice = _toDouble(data['profitPrice']);
    final lossPrice = _toDouble(data['lossPrice']);
    final margin = _toDouble(data['totalPrincipalAmount'] ?? data['principalAmount']);
    final volume = _toDouble(data['totalPosition'] ?? data['volume'] ?? data['tradedVolume']);
    final profitLoss = _toDouble(data['usdtProfit'] ?? data['profitAndLoss'] ?? data['profit'] ?? 0);
    // 手续费 = 开仓手续费 + 平仓手续费（后端字段 openFee / closeFee）
    final fee = _toDouble(data['openFee']) + _toDouble(data['closeFee']) + _toDouble(data['commissionFee']);
    final profitRate = margin > 0 ? profitLoss / margin * 100 : 0.0;
    final profitColor = AppColors.changeColor(profitLoss);

    // 委托价格：市价/计划市价显示"市价"，限价/计划限价显示原始价格
    final entrustPriceStr = _showMarketPrice(data['type'], entrustPrice)
        ? l10n.marketOrderType
        : (entrustPrice > 0 ? _rawNum(entrustPrice) : '--');

    final status = _str(data['status'] ?? '');
    final statusLabel = _mapStatus(status, l10n, isPosition: true);

    return Scaffold(
      backgroundColor: cs.surface,
      appBar: AppBar(
        elevation: 0,
        centerTitle: true,
        backgroundColor: cs.surface,
        title: Text(
          l10n.positionDetail,
          style: TextStyle(
              color: cs.onSurface, fontSize: 16, fontWeight: FontWeight.w700),
        ),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            _HistoryDetailStatus(label: statusLabel),
            _HistorySection(rows: [
              _HistoryRow(l10n.crossIsolatedLabel, posType),
              _HistoryRow(l10n.direction, dirInfo.label, valueColor: dirColor),
              _HistoryRow(l10n.orderType, orderType),
              _HistoryRow(l10n.leverage, '${leverage}x'),
              _HistoryRow(l10n.openTime, openTime),
              _HistoryRow(l10n.closeTime, closeTime, isLast: true),
            ]),
            const _HistorySectionGap(),
            _HistorySection(rows: [
              _HistoryRow('${l10n.triggerPrice}(USDT)', triggerPrice > 0 ? _rawNum(triggerPrice) : '--'),
              _HistoryRow('${l10n.orderPriceLabel}(USDT)', entrustPriceStr),
              _HistoryRow('${l10n.openAvgPrice}(USDT)', openAvgPrice > 0 ? _rawNum(openAvgPrice) : '--'),
              _HistoryRow('${l10n.closeAvgPrice}(USDT)', closeAvgPrice > 0 ? _rawNum(closeAvgPrice) : '--'),
              _HistoryRow('${l10n.takeProfitTriggerPrice}(USDT)', profitPrice > 0 ? _rawNum(profitPrice) : '--'),
              _HistoryRow('${l10n.stopLossTriggerPrice}(USDT)', lossPrice > 0 ? _rawNum(lossPrice) : '--'),
              _HistoryRow('${l10n.marginLabel}(USDT)', margin > 0 ? margin.toStringAsFixed(2) : '--', isLast: true),
            ]),
            const _HistorySectionGap(),
            _HistorySection(rows: [
              _HistoryRow('${l10n.entrustAmount}($coinLabel)', _rawNum(volume)),
              _HistoryRow('${l10n.profitLabel}(USDT)', profitLoss != 0 ? profitLoss.toStringAsFixed(4) : '--', valueColor: profitLoss != 0 ? profitColor : null),
              _HistoryRow(l10n.profitRateLabel, profitRate != 0 ? '${profitRate.toStringAsFixed(2)}%' : '--', valueColor: profitRate != 0 ? profitColor : null),
              _HistoryRow('${l10n.fee}(USDT)', fee > 0 ? fee.toStringAsFixed(4) : '--', isLast: true),
            ]),
            const SizedBox(height: 24),
          ],
        ),
      ),
    );
  }
}

// ═══════════════════════════════════════════════════════════
// 历史委托详情页
// ═══════════════════════════════════════════════════════════

class OrderHistoryDetailScreen extends StatelessWidget {
  const OrderHistoryDetailScreen({super.key, required this.data});
  final Map<String, dynamic> data;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final l10n = AppLocalizations.of(context)!;

    final rawSym = _str(data['symbol'] ?? data['coinSymbol'] ?? '');
    final coinLabel = rawSym.contains('/')
        ? rawSym.split('/').first
        : rawSym.replaceAll(RegExp(r'USDT$|BUSD$'), '').isNotEmpty
            ? rawSym.replaceAll(RegExp(r'USDT$|BUSD$'), '')
            : 'BTC';
    final posType = _mapPositionType(
        data['positionType'], data['patterns'], l10n);
    final dirInfo = _directionInfo(data['direction'], data['entrustType'], l10n);
    final dirColor = dirInfo.isGreen ? AppColors.rise : AppColors.fall;
    final orderType = _mapOrderType(data['type'], l10n);
    final leverage = (_toDouble(data['leverage'])).toInt();
    final openTime = _formatTime(data['createTime'] ?? data['usdtOpenTime']);
    final closeTime = _formatTime(data['dealTime']);

    final triggerPrice = _toDouble(data['triggerPrice']);
    final entrustPrice = _toDouble(data['entrustPrice']);
    // 判断是否为平仓单（entrustType=1/CLOSE）
    final entrustTypeRaw = (data['entrustType']?.toString() ?? '').toUpperCase();
    final isCloseOrder = entrustTypeRaw == '1' || entrustTypeRaw == 'CLOSE';
    // 开仓单：tradedPrice = 开仓成交均价，无平仓均价
    // 平仓单：usdtOpenPrice/openPrice = 原仓位开仓均价，tradedPrice = 平仓成交均价
    final openAvgPrice = isCloseOrder
        ? _toDouble(data['usdtOpenPrice'] ?? data['openPrice'] ?? 0)
        : _toDouble(data['tradedPrice']);
    final closeAvgPrice = isCloseOrder ? _toDouble(data['tradedPrice']) : 0.0;
    final profitPrice = _toDouble(data['profitPrice'] ?? data['stopProfitPrice']);
    final lossPrice = _toDouble(data['lossPrice'] ?? data['stopLossPrice']);
    final margin = _toDouble(data['principalAmount']);
    final volume = _toDouble(data['volume'] ?? data['size']);
    // 手续费 = 开仓手续费 + 平仓手续费（后端字段 openFee / closeFee）
    final fee = _toDouble(data['openFee']) + _toDouble(data['closeFee']);

    // 委托价格：市价/计划市价显示"市价"，限价/计划限价显示原始价格
    final entrustPriceStr = _showMarketPrice(data['type'], entrustPrice)
        ? l10n.marketOrderType
        : (entrustPrice > 0 ? _rawNum(entrustPrice) : '--');

    final status = _str(data['status'] ?? '');
    final statusLabel = _mapStatus(status, l10n);

    return Scaffold(
      backgroundColor: cs.surface,
      appBar: AppBar(
        elevation: 0,
        centerTitle: true,
        backgroundColor: cs.surface,
        title: Text(
          l10n.orderDetail,
          style: TextStyle(
              color: cs.onSurface, fontSize: 16, fontWeight: FontWeight.w700),
        ),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            _HistoryDetailStatus(label: statusLabel),
            _HistorySection(rows: [
              _HistoryRow(l10n.crossIsolatedLabel, posType),
              _HistoryRow(l10n.direction, dirInfo.label, valueColor: dirColor),
              _HistoryRow(l10n.orderType, orderType),
              _HistoryRow(l10n.leverage, '${leverage}x'),
              _HistoryRow(l10n.openTime, openTime),
              _HistoryRow(l10n.closeTime, closeTime, isLast: true),
            ]),
            const _HistorySectionGap(),
            _HistorySection(rows: [
              _HistoryRow('${l10n.triggerPrice}(USDT)', triggerPrice > 0 ? _rawNum(triggerPrice) : '--'),
              _HistoryRow('${l10n.orderPriceLabel}(USDT)', entrustPriceStr),
              _HistoryRow('${l10n.openAvgPrice}(USDT)', openAvgPrice > 0 ? _rawNum(openAvgPrice) : '--'),
              _HistoryRow('${l10n.closeAvgPrice}(USDT)', closeAvgPrice > 0 ? _rawNum(closeAvgPrice) : '--'),
              _HistoryRow('${l10n.takeProfitTriggerPrice}(USDT)', profitPrice > 0 ? _rawNum(profitPrice) : '--'),
              _HistoryRow('${l10n.stopLossTriggerPrice}(USDT)', lossPrice > 0 ? _rawNum(lossPrice) : '--'),
              _HistoryRow('${l10n.marginLabel}(USDT)', margin > 0 ? margin.toStringAsFixed(2) : '--'),
              _HistoryRow('${l10n.entrustAmount}($coinLabel)', _rawNum(volume)),
              _HistoryRow('${l10n.fee}(USDT)', fee > 0 ? fee.toStringAsFixed(4) : '--', isLast: true),
            ]),
            const SizedBox(height: 24),
          ],
        ),
      ),
    );
  }
}

// ─── 共用辅助 widgets ──────────────────────────────────────

class _HistoryDetailStatus extends StatelessWidget {
  const _HistoryDetailStatus({required this.label});
  final String label;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    return Padding(
      padding: const EdgeInsets.fromLTRB(0, 32, 0, 24),
      child: Column(
        children: [
          Stack(
            clipBehavior: Clip.none,
            children: [
              Container(
                width: 56,
                height: 56,
                decoration: BoxDecoration(
                  color: const Color(0xFF3B82F6).withAlpha(25),
                  borderRadius: BorderRadius.circular(14),
                ),
                child: const Icon(Icons.receipt_long,
                    color: Color(0xFF3B82F6), size: 28),
              ),
              Positioned(
                right: -4,
                bottom: -4,
                child: Container(
                  width: 20,
                  height: 20,
                  decoration: const BoxDecoration(
                    color: AppColors.rise,
                    shape: BoxShape.circle,
                  ),
                  child: const Icon(Icons.check,
                      color: Colors.white, size: 13),
                ),
              ),
            ],
          ),
          const SizedBox(height: 14),
          Text(
            label,
            style: TextStyle(
                color: cs.onSurface,
                fontSize: 16,
                fontWeight: FontWeight.w600),
          ),
        ],
      ),
    );
  }
}

class _HistoryRow {
  const _HistoryRow(this.label, this.value,
      {this.valueColor, this.isLast = false});
  final String label;
  final String value;
  final Color? valueColor;
  final bool isLast;
}

class _HistorySection extends StatelessWidget {
  const _HistorySection({required this.rows});
  final List<_HistoryRow> rows;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    return Column(
      children: rows.map((r) {
        return Column(
          children: [
            Padding(
              padding:
                  const EdgeInsets.symmetric(horizontal: 16, vertical: 13),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text(r.label,
                      style: TextStyle(
                          color: cs.onSurface.withAlpha(153), fontSize: 13)),
                  Text(r.value,
                      style: TextStyle(
                          color: r.valueColor ?? cs.onSurface,
                          fontSize: 13,
                          fontWeight: FontWeight.w500)),
                ],
              ),
            ),
            if (!r.isLast)
              Divider(
                  height: 1,
                  thickness: 0.5,
                  indent: 16,
                  endIndent: 16,
                  color: cs.outline.withAlpha(60)),
          ],
        );
      }).toList(),
    );
  }
}

class _HistorySectionGap extends StatelessWidget {
  const _HistorySectionGap();

  @override
  Widget build(BuildContext context) {
    final isDark = Theme.of(context).brightness == Brightness.dark;
    return Container(height: 8, color: isDark ? AppColors.darkBg : AppColors.lightBgSecondary);
  }
}

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

/// 历史列表骨架：模拟 3 张卡片占位
class _HistoryListShimmer extends StatelessWidget {
  const _HistoryListShimmer({required this.isPosition});
  final bool isPosition; // 持仓卡片 vs 委托卡片（行数略有差异）

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

    Widget card() {
      return Container(
        decoration: BoxDecoration(
          color: cardBg,
          borderRadius: BorderRadius.circular(12),
        ),
        padding: const EdgeInsets.all(14),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // 标题行：币对名 + 状态
            Row(
              children: [
                shimmerBox(90, 15),
                const Spacer(),
                shimmerBox(52, 13),
              ],
            ),
            const SizedBox(height: 10),
            // 标签行
            Row(children: [
              shimmerBox(52, 20, radius: 4),
              const SizedBox(width: 6),
              shimmerBox(44, 20, radius: 4),
              const SizedBox(width: 6),
              shimmerBox(32, 20, radius: 4),
              const SizedBox(width: 6),
              shimmerBox(28, 20, radius: 4),
            ]),
            const SizedBox(height: 12),
            // 分割线
            shimmerBox(double.infinity, 0.5),
            const SizedBox(height: 10),
            // 数据行 1
            Row(children: [
              _ShimmerField(),
              _ShimmerField(),
              if (isPosition) _ShimmerField(),
            ]),
            const SizedBox(height: 8),
            // 数据行 2
            Row(children: [
              _ShimmerField(),
              _ShimmerField(),
              if (isPosition) _ShimmerField(),
            ]),
            const SizedBox(height: 10),
            shimmerBox(double.infinity, 0.5),
            const SizedBox(height: 10),
            // 时间行
            Row(
              children: [
                Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                  shimmerBox(44, 10),
                  const SizedBox(height: 4),
                  shimmerBox(110, 12),
                ]),
                const Spacer(),
                Column(crossAxisAlignment: CrossAxisAlignment.end, children: [
                  shimmerBox(44, 10),
                  const SizedBox(height: 4),
                  shimmerBox(110, 12),
                ]),
              ],
            ),
          ],
        ),
      );
    }

    return AppShimmer(
      child: ListView.separated(
        physics: const NeverScrollableScrollPhysics(),
        padding: const EdgeInsets.fromLTRB(12, 12, 12, 24),
        itemCount: 4,
        separatorBuilder: (_, __) => const SizedBox(height: 12),
        itemBuilder: (_, __) => card(),
      ),
    );
  }
}

/// 数据字段占位（标签 + 值，竖向排列）
class _ShimmerField extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          shimmerBox(40, 10),
          const SizedBox(height: 5),
          shimmerBox(60, 13),
        ],
      ),
    );
  }
}
