import 'dart:math' as math;

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

import '../../../core/l10n/app_localizations.dart';
import '../../../core/theme/app_colors.dart';
import '../../../core/utils/top_toast.dart';
import '../../../data/models/asset/asset_statement.dart';
import '../../../providers/statement_provider.dart';
import '../../widgets/common/app_refresh_indicator.dart';

class AssetHistoryScreen extends ConsumerWidget {
  const AssetHistoryScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final state = ref.watch(statementProvider);
    final notifier = ref.read(statementProvider.notifier);
    final filterCache = ref.watch(statementFilterCacheProvider);

    ref.listen<StatementState>(statementProvider, (prev, next) {
      if (next.errorMessage != null && next.errorMessage != prev?.errorMessage) {
        final l10n = AppLocalizations.of(context)!;
        showTopToast(context,
            message: resolveProviderError(next.errorMessage!, l10n) ?? next.errorMessage!,
            backgroundColor: AppColors.fall);
      }
    });

    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: const Icon(Icons.chevron_left, size: 28),
          onPressed: () => context.pop(),
        ),
        title: Text(AppLocalizations.of(context)!.fundRecord,
            style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600)),
        centerTitle: true,
      ),
      body: Column(
        children: [
          _FilterSection(
            state: state,
            notifier: notifier,
            coins: filterCache.coins,
            types: filterCache.types,
          ),
          Expanded(
            child: _buildList(context, state, notifier, filterCache.types),
          ),
        ],
      ),
    );
  }

  Widget _buildList(
    BuildContext context,
    StatementState state,
    StatementNotifier notifier,
    List<StatementType> types,
  ) {
    final cs = Theme.of(context).colorScheme;

    if (state.isLoading && state.records.isEmpty) {
      return const Center(child: CircularProgressIndicator());
    }

    if (state.records.isEmpty) {
      return Center(
        child: Text(AppLocalizations.of(context)!.noRecord,
            style:
                TextStyle(color: cs.onSurface.withAlpha(120), fontSize: 15)),
      );
    }

    return AppRefreshIndicator(
      onRefresh: notifier.refresh,
      child: NotificationListener<ScrollNotification>(
        onNotification: (notification) {
          if (notification is ScrollEndNotification &&
              notification.metrics.pixels >=
                  notification.metrics.maxScrollExtent - 100) {
            notifier.loadMore();
          }
          return false;
        },
        child: ListView.separated(
          padding: const EdgeInsets.fromLTRB(16, 12, 16, 32),
          itemCount: state.records.length + (state.hasMore ? 1 : 0),
          separatorBuilder: (_, __) => const SizedBox(height: 10),
          itemBuilder: (_, i) {
            if (i >= state.records.length) {
              return const Padding(
                padding: EdgeInsets.symmetric(vertical: 16),
                child:
                    Center(child: CircularProgressIndicator(strokeWidth: 2)),
              );
            }
            return _RecordCard(
              record: state.records[i],
              types: types,
              coinCode: state.selectedCoinCode,
            );
          },
        ),
      ),
    );
  }
}

Map<String, String> _buildLocalTypeNames(AppLocalizations l10n) => {
  '0': l10n.txType0, '1': l10n.txType1, '2': l10n.txType2, '3': l10n.txType3, '4': l10n.txType4,
  '5': l10n.txType5, '6': l10n.txType6, '7': l10n.txType7, '8': l10n.txType8, '9': l10n.txType9,
  '10': l10n.txType10, '11': l10n.txType11, '13': l10n.txType13, '14': l10n.txType14,
  '15': l10n.txType15, '16': l10n.txType16, '17': l10n.txType17, '18': l10n.txType18,
  '19': l10n.txType19, '20': l10n.txType20, '21': l10n.txType21, '22': l10n.txType22,
  '23': l10n.txType23, '24': l10n.txType24, '25': l10n.txType25, '26': l10n.txType26,
  '27': l10n.txType27, '28': l10n.txType28, '29': l10n.txType29,
  '30': l10n.txType30, '31': l10n.txType31, '32': l10n.txType32, '33': l10n.txType33,
  '34': l10n.txType34, '35': l10n.txType35, '36': l10n.txType36,
  '37': l10n.txType37, '38': l10n.txType38, '39': l10n.txType39,
  '40': l10n.txType40, '41': l10n.txType41, '42': l10n.txType42,
  '43': l10n.txType43, '44': l10n.txType44, '45': l10n.txType45, '46': l10n.txType46,
  '47': l10n.txType47, '48': l10n.txType48, '49': l10n.txType49, '50': l10n.txType50, '51': l10n.txType51,
};

// ══════════════════════════════════════════════════════════════
// 筛选区
// ══════════════════════════════════════════════════════════════

class _FilterSection extends StatelessWidget {
  const _FilterSection({
    required this.state,
    required this.notifier,
    required this.coins,
    required this.types,
  });
  final StatementState state;
  final StatementNotifier notifier;
  final List<StatementCoin> coins;
  final List<StatementType> types;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final dateFmt = DateFormat('yyyy-MM-dd');

    final l10n = AppLocalizations.of(context)!;
    // 构建选项列表：(value, label)
    final coinOptions = <(String, String)>[
      ('', l10n.all),
      ...coins.map((c) => (c.code, c.code)),
    ];
    final localTypeNames = _buildLocalTypeNames(l10n);
    final typeOptions = <(String, String)>[
      ('', l10n.all),
      ...types.map((t) => (t.typeId, localTypeNames[t.typeId] ?? t.name)),
    ];

    final coinLabel = coinOptions
        .firstWhere((e) => e.$1 == state.selectedCoinCode,
            orElse: () => ('', l10n.all))
        .$2;
    final typeLabel = typeOptions
        .firstWhere((e) => e.$1 == state.selectedTypeId,
            orElse: () => ('', l10n.all))
        .$2;

    return Padding(
      padding: const EdgeInsets.fromLTRB(16, 12, 16, 12),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // 币种 + 类型
          Row(
            children: [
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    Text(l10n.coinLabel,
                        style: TextStyle(
                            color: cs.onSurface.withAlpha(120), fontSize: 12)),
                    const SizedBox(height: 6),
                    _PickerField(
                      label: coinLabel,
                      items: coinOptions,
                      value: state.selectedCoinCode,
                      title: l10n.selectCoin,
                      onChanged: (v) => notifier.selectCoin(v),
                    ),
                  ],
                ),
              ),
              const SizedBox(width: 12),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    Text(l10n.typeLabel,
                        style: TextStyle(
                            color: cs.onSurface.withAlpha(120), fontSize: 12)),
                    const SizedBox(height: 6),
                    _PickerField(
                      label: typeLabel,
                      items: typeOptions,
                      value: state.selectedTypeId,
                      title: l10n.selectType,
                      onChanged: (v) => notifier.selectType(v),
                    ),
                  ],
                ),
              ),
            ],
          ),
          const SizedBox(height: 12),

          // 起止时间 + 重置/搜索
          Text(l10n.timeRange,
              style: TextStyle(
                  color: cs.onSurface.withAlpha(120), fontSize: 12)),
          const SizedBox(height: 6),
          Row(
            children: [
              Expanded(
                child: Container(
                  padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 4),
                  decoration: BoxDecoration(
                    color: isDark ? AppColors.darkBgTertiary : AppColors.lightBgSecondary,
                    border: Border.all(
                        color: isDark
                            ? AppColors.darkCardBorder.withAlpha(180)
                            : AppColors.lightBorder),
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: Row(
                    children: [
                      Flexible(
                        child: _TimeChip(
                          label: state.startDate != null
                              ? dateFmt.format(state.startDate!)
                              : l10n.startTime,
                          onTap: () async {
                            final date = await _showDrumDatePicker(
                              context: context,
                              initialDate: state.startDate ?? DateTime.now(),
                              firstDate: DateTime(2017),
                              lastDate: DateTime.now(),
                              title: l10n.startTime,
                            );
                            if (date != null) notifier.selectStartDate(date);
                          },
                        ),
                      ),
                      Text('~',
                          style: TextStyle(
                              color: cs.onSurface.withAlpha(120))),
                      Flexible(
                        child: _TimeChip(
                          label: state.endDate != null
                              ? dateFmt.format(state.endDate!)
                              : l10n.endTime,
                          onTap: () async {
                            final date = await _showDrumDatePicker(
                              context: context,
                              initialDate: state.endDate ?? DateTime.now(),
                              firstDate: DateTime(2017),
                              lastDate: DateTime.now(),
                              title: l10n.endTime,
                            );
                            if (date != null) notifier.selectEndDate(date);
                          },
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              const SizedBox(width: 8),
              GestureDetector(
                onTap: notifier.reset,
                child: Container(
                  padding:
                      const EdgeInsets.symmetric(horizontal: 16, vertical: 9),
                  decoration: BoxDecoration(
                    border: Border.all(
                        color: isDark
                            ? AppColors.darkCardBorder.withAlpha(180)
                            : AppColors.lightBorder),
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: Text(l10n.reset,
                      style:
                          TextStyle(color: cs.onSurface, fontSize: 13)),
                ),
              ),
              const SizedBox(width: 8),
              GestureDetector(
                onTap: notifier.search,
                child: Container(
                  padding:
                      const EdgeInsets.symmetric(horizontal: 20, vertical: 9),
                  decoration: BoxDecoration(
                    color: AppColors.brand,
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: Text(l10n.search,
                      style: const TextStyle(
                          color: Colors.black,
                          fontSize: 13,
                          fontWeight: FontWeight.w600)),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

// ══════════════════════════════════════════════════════════════
// 自定义选择器字段（替代 DropdownButtonFormField）
// ══════════════════════════════════════════════════════════════

class _PickerField extends StatelessWidget {
  const _PickerField({
    required this.label,
    required this.items,
    required this.value,
    required this.title,
    required this.onChanged,
  });
  final String label;
  final List<(String, String)> items; // (value, displayLabel)
  final String value;
  final String title;
  final ValueChanged<String> onChanged;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final fieldBg = isDark ? AppColors.darkBgTertiary : AppColors.lightBgSecondary;
    final borderColor = isDark ? AppColors.darkCardBorder.withAlpha(180) : AppColors.lightBorder;
    return LayoutBuilder(
      builder: (_, constraints) => GestureDetector(
        onTap: () => _showSheet(context),
        child: Container(
          width: constraints.maxWidth,
          padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 11),
          decoration: BoxDecoration(
            color: fieldBg,
            border: Border.all(color: borderColor),
            borderRadius: BorderRadius.circular(8),
          ),
          child: Row(
            children: [
              Expanded(
                child: Text(
                  label,
                  style: TextStyle(color: cs.onSurface, fontSize: 14),
                  overflow: TextOverflow.ellipsis,
                ),
              ),
              Icon(Icons.keyboard_arrow_down,
                  size: 18, color: cs.onSurface.withAlpha(120)),
            ],
          ),
        ),
      ),
    );
  }

  void _showSheet(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final isDark = Theme.of(context).brightness == Brightness.dark;
    showModalBottomSheet<void>(
      context: context,
      useRootNavigator: true,
      backgroundColor:
          isDark ? AppColors.darkBgSecondary : AppColors.lightBg,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
      ),
      builder: (ctx) {
        final mq = MediaQuery.of(ctx);
        return LayoutBuilder(
          builder: (ctx, constraints) {
            // 把手 + 标题 + 分隔线 + 底安全区，与下方列表分离避免超出 BottomSheet 高度
            const topReserve = 100.0;
            final bottomGap = mq.padding.bottom + 8;
            final parentH = constraints.maxHeight;
            final listMax = parentH.isFinite
                ? math.min(
                    mq.size.height * 0.45,
                    math.max(120.0, parentH - topReserve - bottomGap),
                  )
                : mq.size.height * 0.45;

            return Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Padding(
                  padding: const EdgeInsets.only(top: 12, bottom: 4),
                  child: Container(
                    width: 36,
                    height: 4,
                    decoration: BoxDecoration(
                      color: cs.onSurface.withAlpha(40),
                      borderRadius: BorderRadius.circular(2),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(16, 8, 16, 12),
                  child: Text(title,
                      style: TextStyle(
                          color: cs.onSurface,
                          fontSize: 15,
                          fontWeight: FontWeight.w600)),
                ),
                Divider(height: 1, color: cs.outline.withAlpha(40)),
                ConstrainedBox(
                  constraints: BoxConstraints(maxHeight: listMax),
                  child: ListView.separated(
                    shrinkWrap: true,
                    itemCount: items.length,
                    separatorBuilder: (_, __) =>
                        Divider(height: 1, color: cs.outline.withAlpha(25)),
                    itemBuilder: (_, i) {
                      final (val, lbl) = items[i];
                      final isSelected = val == value;
                      return GestureDetector(
                        onTap: () {
                          Navigator.pop(ctx);
                          onChanged(val);
                        },
                        child: Padding(
                          padding: const EdgeInsets.symmetric(
                              horizontal: 20, vertical: 14),
                          child: Row(
                            children: [
                              Expanded(
                                child: Text(
                                  lbl,
                                  style: TextStyle(
                                    color: isSelected
                                        ? AppColors.brand
                                        : cs.onSurface,
                                    fontSize: 15,
                                    fontWeight: isSelected
                                        ? FontWeight.w600
                                        : FontWeight.w400,
                                  ),
                                ),
                              ),
                              if (isSelected)
                                const Icon(Icons.check,
                                    size: 18, color: AppColors.brand),
                            ],
                          ),
                        ),
                      );
                    },
                  ),
                ),
                SizedBox(height: bottomGap),
              ],
            );
          },
        );
      },
    );
  }
}

// ══════════════════════════════════════════════════════════════
// 流水记录卡片
// ══════════════════════════════════════════════════════════════

/// 类别行展示：去掉服务端固定的中文「永续」或英文 perpetual，改为 [AppLocalizations.perpetual]。
String localizedStatementCategorySymbol(String raw, AppLocalizations l10n) {
  final s = raw.trim();
  if (s.isEmpty) {
    return s;
  }
  final zh = RegExp(r'\s*永续\s*$');
  if (zh.hasMatch(s)) {
    final base = s.replaceFirst(zh, '').trim();
    if (base.isEmpty) {
      return l10n.perpetual;
    }
    return '$base ${l10n.perpetual}';
  }
  final en = RegExp(r'\s+perpetual\s*$', caseSensitive: false);
  if (en.hasMatch(s)) {
    final base = s.replaceFirst(en, '').trim();
    if (base.isEmpty) {
      return l10n.perpetual;
    }
    return '$base ${l10n.perpetual}';
  }
  return s;
}

/// 现货成交（type=48）类别不与永续挂钩：去掉尾部永续表述，仅保留标的（与 Web 一致）。
String localizedStatementCategoryForRecord(
  AssetStatement record,
  AppLocalizations l10n,
) {
  if (record.type == '48') {
    return _stripPerpetualSuffixRaw(record.displaySymbol);
  }
  return localizedStatementCategorySymbol(record.displaySymbol, l10n);
}

String _stripPerpetualSuffixRaw(String raw) {
  final s = raw.trim();
  if (s.isEmpty) {
    return s;
  }
  var t = s.replaceFirst(RegExp(r'\s*永续\s*$'), '').trim();
  t = t.replaceFirst(RegExp(r'\s+perpetual\s*$', caseSensitive: false), '').trim();
  t = t.replaceFirst(RegExp(r'\s*無期限\s*$'), '').trim();
  if (t.isEmpty) {
    return s.split(RegExp(r'\s+')).first;
  }
  return t;
}

class _RecordCard extends StatelessWidget {
  const _RecordCard({
    required this.record,
    required this.types,
    this.coinCode = '',
  });
  final AssetStatement record;
  final List<StatementType> types;
  final String coinCode;

  String _localizedExtraTitle(AppLocalizations l10n) {
    switch (record.type) {
      case '1':  return l10n.feeUsdt;
      case '19': return l10n.openCloseLabel;
      case '25': return l10n.rebateId;
      default:   return '';
    }
  }

  String _localizedExtraValue(AppLocalizations l10n) {
    switch (record.type) {
      case '1':  return record.fee;
      case '19': return record.direction == '0' ? l10n.openPosition : l10n.closePosition;
      case '25': return record.rebateId;
      default:   return '';
    }
  }

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final amount = double.tryParse(record.amount) ?? 0;
    final isPositive = amount >= 0;
    final amountColor = isPositive ? AppColors.rise : AppColors.fall;
    final amountStr =
        isPositive ? '+${_formatAmount(amount)}' : _formatAmount(amount);
    final l10n = AppLocalizations.of(context)!;
    final typeName = _findTypeName(record.type, l10n);
    final coin = coinCode.isNotEmpty ? coinCode : 'USDT';
    // 数量标签用记录本身的币种（取 symbol 第一个词，如 "BTC 永续" → "BTC"）
    final amountCoin = record.symbol.isNotEmpty
        ? record.symbol.split(' ').first
        : coin;

    final timeParts = record.createTime.split(' ');
    final datePart = timeParts.isNotEmpty ? timeParts[0] : record.createTime;
    final timePart = timeParts.length > 1 ? timeParts[1] : '';
    final hasExtra = record.showExtraField || record.symbol.isNotEmpty;

    // 颜色分层：header背景 vs body背景
    final headerBg =
        isDark ? AppColors.brand.withAlpha(90) : AppColors.tagIndigoBgLight;
    final bodyBg = isDark ? AppColors.darkBgSecondary : AppColors.lightBg;
    final borderColor =
        isDark ? AppColors.darkCardBorder : AppColors.lightBorder;

    return Container(
      clipBehavior: Clip.antiAlias,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: borderColor, width: 0.5),
        color: bodyBg, // 封住底部 + 为 Divider 提供背景色
      ),
      child: Column(
          children: [
            // ── Header：币种 + 已完成（带背景色）──────────
            Container(
              color: headerBg,
              padding:
                  const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
              child: Row(
                children: [
                  Text(
                    'USDT',
                    style: TextStyle(
                      color: cs.onSurface,
                      fontSize: 14,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                  const Spacer(),
                  Text(
                    AppLocalizations.of(context)!.completed,
                    style: TextStyle(
                      color: cs.onSurface.withAlpha(100),
                      fontSize: 12,
                    ),
                  ),
                ],
              ),
            ),

            // ── Body ────────────────────────────────────
            Padding(
              padding: const EdgeInsets.fromLTRB(14, 12, 14, 12),
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  // 类型
                  Expanded(
                    flex: 4,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(AppLocalizations.of(context)!.typeLabel,
                            style: TextStyle(
                                color: cs.onSurface.withAlpha(100),
                                fontSize: 11)),
                        const SizedBox(height: 5),
                        Text(
                          typeName,
                          style: TextStyle(
                            color: cs.onSurface,
                            fontSize: 13,
                            fontWeight: FontWeight.w500,
                          ),
                        ),
                      ],
                    ),
                  ),
                  // 时间
                  Expanded(
                    flex: 4,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(AppLocalizations.of(context)!.timeLabel,
                            style: TextStyle(
                                color: cs.onSurface.withAlpha(100),
                                fontSize: 11)),
                        const SizedBox(height: 5),
                        Text(datePart,
                            style: TextStyle(
                                color: cs.onSurface, fontSize: 12)),
                        if (timePart.isNotEmpty)
                          Text(timePart,
                              style: TextStyle(
                                  color: cs.onSurface.withAlpha(153),
                                  fontSize: 12)),
                      ],
                    ),
                  ),
                  // 数量（右对齐）
                  Expanded(
                    flex: 4,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.end,
                      children: [
                        Text('${AppLocalizations.of(context)!.amountLabel}($amountCoin)',
                            overflow: TextOverflow.ellipsis,
                            style: TextStyle(
                                color: cs.onSurface.withAlpha(100),
                                fontSize: 11)),
                        const SizedBox(height: 5),
                        Text(
                          amountStr,
                          overflow: TextOverflow.ellipsis,
                          style: TextStyle(
                            color: amountColor,
                            fontSize: 14,
                            fontWeight: FontWeight.w600,
                            fontFeatures: const [FontFeature.tabularFigures()],
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),

            // ── 额外字段行（类别 / 开平仓）──────────────
            if (hasExtra) ...[
              Divider(
                height: 1,
                thickness: 0.5,
                color: borderColor,
                indent: 14,
                endIndent: 14,
              ),
              Padding(
                padding: const EdgeInsets.fromLTRB(14, 10, 14, 12),
                child: Row(
                  children: [
                    if (record.symbol.isNotEmpty)
                      Expanded(
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(AppLocalizations.of(context)!.categoryLabel,
                                style: TextStyle(
                                    color: cs.onSurface.withAlpha(100),
                                    fontSize: 11)),
                            const SizedBox(height: 5),
                            Text(localizedStatementCategoryForRecord(record, l10n),
                                style: TextStyle(
                                    color: cs.onSurface, fontSize: 13)),
                          ],
                        ),
                      ),
                    if (record.showExtraField)
                      Expanded(
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(_localizedExtraTitle(l10n),
                                style: TextStyle(
                                    color: cs.onSurface.withAlpha(100),
                                    fontSize: 11)),
                            const SizedBox(height: 5),
                            Text(_localizedExtraValue(l10n),
                                style: TextStyle(
                                    color: cs.onSurface, fontSize: 13)),
                          ],
                        ),
                      ),
                  ],
                ),
              ),
            ],
          ],
        ),
    );
  }

  Map<String, String> _localTypeNames(AppLocalizations l10n) => _buildLocalTypeNames(l10n);

  String _findTypeName(String typeId, AppLocalizations l10n) {
    final localName = _localTypeNames(l10n)[typeId];
    if (localName != null) return localName;
    for (final t in types) {
      if (t.typeId == typeId) return t.name;
    }
    return typeId;
  }

  String _formatAmount(double value) {
    final abs = value.abs();
    int decimals;
    if (abs < 0.0001) {
      decimals = 8;
    } else if (abs < 0.001) {
      decimals = 7;
    } else if (abs < 0.01) {
      decimals = 6;
    } else if (abs < 0.1) {
      decimals = 5;
    } else if (abs < 1) {
      decimals = 4;
    } else {
      decimals = 2;
    }
    final factor = _pow10(decimals);
    final truncated = (value * factor).truncateToDouble() / factor;
    var str = truncated.toStringAsFixed(decimals);
    if (str.contains('.')) {
      str = str.replaceAll(RegExp(r'0+$'), '');
      str = str.replaceAll(RegExp(r'\.$'), '');
    }
    return str;
  }

  double _pow10(int n) {
    double result = 1;
    for (int i = 0; i < n; i++) result *= 10;
    return result;
  }
}

// ══════════════════════════════════════════════════════════════
// 时间选择 Chip
// ══════════════════════════════════════════════════════════════

class _TimeChip extends StatelessWidget {
  const _TimeChip({required this.label, required this.onTap});
  final String label;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    return GestureDetector(
      onTap: onTap,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 5),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(Icons.access_time_outlined,
                size: 13, color: cs.onSurface.withAlpha(100)),
            const SizedBox(width: 4),
            Flexible(
              child: Text(
                label,
                style: TextStyle(
                    color: cs.onSurface.withAlpha(153), fontSize: 12),
                overflow: TextOverflow.ellipsis,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// ══════════════════════════════════════════════════════════════
// 滚筒日期选择器
// ══════════════════════════════════════════════════════════════

Future<DateTime?> _showDrumDatePicker({
  required BuildContext context,
  required DateTime initialDate,
  required DateTime firstDate,
  required DateTime lastDate,
  String? title,
}) {
  final isDark = Theme.of(context).brightness == Brightness.dark;
  final resolvedTitle = title ?? AppLocalizations.of(context)!.selectDate;
  return showModalBottomSheet<DateTime>(
    context: context,
    useRootNavigator: true,
    backgroundColor: Colors.transparent,
    isScrollControlled: true,
    builder: (ctx) => _DrumDatePickerSheet(
      initialDate: initialDate,
      firstDate: firstDate,
      lastDate: lastDate,
      title: resolvedTitle,
      isDark: isDark,
    ),
  );
}

class _DrumDatePickerSheet extends StatefulWidget {
  const _DrumDatePickerSheet({
    required this.initialDate,
    required this.firstDate,
    required this.lastDate,
    required this.title,
    required this.isDark,
  });
  final DateTime initialDate;
  final DateTime firstDate;
  final DateTime lastDate;
  final String title;
  final bool isDark;

  @override
  State<_DrumDatePickerSheet> createState() => _DrumDatePickerSheetState();
}

class _DrumDatePickerSheetState extends State<_DrumDatePickerSheet> {
  late int _year;
  late int _month;
  late int _day;
  late List<int> _years;
  late FixedExtentScrollController _yearCtrl;
  late FixedExtentScrollController _monthCtrl;
  late FixedExtentScrollController _dayCtrl;

  @override
  void initState() {
    super.initState();
    _years = List.generate(
      widget.lastDate.year - widget.firstDate.year + 1,
      (i) => widget.firstDate.year + i,
    );
    _year = widget.initialDate.year.clamp(widget.firstDate.year, widget.lastDate.year);
    _month = widget.initialDate.month;
    _day = widget.initialDate.day.clamp(1, _daysInMonth);

    _yearCtrl = FixedExtentScrollController(initialItem: _year - widget.firstDate.year);
    _monthCtrl = FixedExtentScrollController(initialItem: _month - 1);
    _dayCtrl = FixedExtentScrollController(initialItem: _day - 1);
  }

  @override
  void dispose() {
    _yearCtrl.dispose();
    _monthCtrl.dispose();
    _dayCtrl.dispose();
    super.dispose();
  }

  int get _daysInMonth => DateTime(_year, _month + 1, 0).day;

  void _onYearChanged(int index) {
    setState(() {
      _year = _years[index];
      _clampDay();
    });
  }

  void _onMonthChanged(int index) {
    setState(() {
      _month = index + 1;
      _clampDay();
    });
  }

  void _onDayChanged(int index) {
    setState(() {
      _day = (index + 1).clamp(1, _daysInMonth);
    });
  }

  void _clampDay() {
    final maxDay = _daysInMonth;
    if (_day > maxDay) {
      _day = maxDay;
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (_dayCtrl.hasClients) _dayCtrl.jumpToItem(_day - 1);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final sheetBg = widget.isDark ? const Color(0xFF1C2128) : Colors.white;
    final highlightBg = widget.isDark ? AppColors.darkBgTertiary : AppColors.lightBgSecondary;
    final gradientColor = widget.isDark ? const Color(0xFF1C2128) : Colors.white;
    final dividerColor = widget.isDark ? Colors.white.withAlpha(20) : const Color(0xFFF0F0F0);
    final textStyle = TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: cs.onSurface);

    final preview =
        '$_year-${_month.toString().padLeft(2, '0')}-${_day.toString().padLeft(2, '0')}';

    return Container(
      decoration: BoxDecoration(
        color: sheetBg,
        borderRadius: const BorderRadius.vertical(top: Radius.circular(16)),
      ),
      child: SafeArea(
        child: LayoutBuilder(
          builder: (context, constraints) {
            final mq = MediaQuery.of(context);
            // SafeArea 已处理底部；此处为工具栏 + 预览 + 分隔线 + 底留白
            const fixedToolbar = 50.0 + 44.0 + 2.0 + 8.0;
            final maxH = constraints.maxHeight.isFinite
                ? constraints.maxHeight
                : mq.size.height * 0.42;
            final wheelH =
                (maxH - fixedToolbar).clamp(160.0, 240.0);

            return Column(
              mainAxisSize: MainAxisSize.min,
              children: [
            SizedBox(
              height: 50,
              child: Row(
                children: [
                  TextButton(
                    onPressed: () => Navigator.pop(context),
                    child: Text(AppLocalizations.of(context)!.cancel,
                        style: TextStyle(
                            fontSize: 15,
                            fontWeight: FontWeight.w500,
                            color: cs.onSurface.withAlpha(153))),
                  ),
                  Expanded(
                    child: Text(widget.title,
                        textAlign: TextAlign.center,
                        style: TextStyle(
                            fontSize: 16,
                            fontWeight: FontWeight.w600,
                            color: cs.onSurface)),
                  ),
                  TextButton(
                    onPressed: () => Navigator.pop(context, DateTime(_year, _month, _day)),
                    child: Text(AppLocalizations.of(context)!.confirm,
                        style: const TextStyle(
                            fontSize: 15,
                            fontWeight: FontWeight.w600,
                            color: AppColors.brand)),
                  ),
                ],
              ),
            ),
            Divider(height: 1, color: dividerColor),

            // ── 预览行 ──────────────────────────────────────
            SizedBox(
              height: 44,
              child: Center(
                child: Text(preview,
                    style: const TextStyle(
                        fontSize: 15,
                        fontWeight: FontWeight.w600,
                        color: AppColors.brand)),
              ),
            ),
            Divider(height: 1, color: dividerColor),

            SizedBox(
              height: wheelH,
              child: Stack(
                children: [
                  // 选中行高亮背景
                  Positioned.fill(
                    child: Center(
                      child: Container(
                        height: 44,
                        margin: const EdgeInsets.symmetric(horizontal: 8),
                        decoration: BoxDecoration(
                          color: highlightBg,
                          borderRadius: BorderRadius.circular(8),
                        ),
                      ),
                    ),
                  ),
                  // 三列
                  Row(
                    children: [
                      // 年份列
                      Expanded(
                        flex: 5,
                        child: ListWheelScrollView.useDelegate(
                          controller: _yearCtrl,
                          itemExtent: 44,
                          physics: const FixedExtentScrollPhysics(),
                          onSelectedItemChanged: _onYearChanged,
                          childDelegate: ListWheelChildBuilderDelegate(
                            childCount: _years.length,
                            builder: (_, i) => Center(
                              child: Text('${_years[i]}${AppLocalizations.of(context)!.yearSuffix}', style: textStyle),
                            ),
                          ),
                        ),
                      ),
                      // 月份列
                      Expanded(
                        flex: 3,
                        child: ListWheelScrollView.useDelegate(
                          controller: _monthCtrl,
                          itemExtent: 44,
                          physics: const FixedExtentScrollPhysics(),
                          onSelectedItemChanged: _onMonthChanged,
                          childDelegate: ListWheelChildBuilderDelegate(
                            childCount: 12,
                            builder: (_, i) => Center(
                              child: Text('${i + 1}${AppLocalizations.of(context)!.monthSuffix}', style: textStyle),
                            ),
                          ),
                        ),
                      ),
                      // 日期列
                      Expanded(
                        flex: 3,
                        child: ListWheelScrollView.useDelegate(
                          controller: _dayCtrl,
                          itemExtent: 44,
                          physics: const FixedExtentScrollPhysics(),
                          onSelectedItemChanged: _onDayChanged,
                          childDelegate: ListWheelChildBuilderDelegate(
                            childCount: _daysInMonth,
                            builder: (_, i) => Center(
                              child: Text('${i + 1}${AppLocalizations.of(context)!.daySuffix}', style: textStyle),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  // 上渐变遮罩
                  Positioned(
                    top: 0, left: 0, right: 0, height: 88,
                    child: IgnorePointer(
                      child: Container(
                        decoration: BoxDecoration(
                          gradient: LinearGradient(
                            begin: Alignment.topCenter,
                            end: Alignment.bottomCenter,
                            colors: [gradientColor, gradientColor.withAlpha(0)],
                          ),
                        ),
                      ),
                    ),
                  ),
                  // 下渐变遮罩
                  Positioned(
                    bottom: 0, left: 0, right: 0, height: 88,
                    child: IgnorePointer(
                      child: Container(
                        decoration: BoxDecoration(
                          gradient: LinearGradient(
                            begin: Alignment.bottomCenter,
                            end: Alignment.topCenter,
                            colors: [gradientColor, gradientColor.withAlpha(0)],
                          ),
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            const SizedBox(height: 8),
          ],
            );
          },
        ),
      ),
    );
  }
}
