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

import '../../../core/l10n/app_localizations.dart';
import '../../../core/theme/app_colors.dart';
import '../../../core/utils/number_format.dart';
import '../../../core/utils/symbol_display.dart';
import '../../../data/models/home/market_ticker.dart';
import '../../../providers/market_provider.dart';

/// 交易对选择器中的 Tab 类型
enum SymbolPickerTab { futures, spot }

/// 通用币对选择底部弹窗（合约 / 现货双 Tab）
///
/// 数据直接来源于 [marketProvider]（已批量订阅所有 WS ticker），
/// 打开时无需额外 API 请求，实时价格自动刷新。
///
/// 用法：
/// ```dart
/// showModalBottomSheet(
///   isScrollControlled: true,
///   builder: (_) => SymbolPickerSheet(
///     currentSymbol: 'BTCUSDT',
///     initialTab: SymbolPickerTab.spot,
///     onSelected: (sym) { /* 合约选中 */ },
///     onSpotSelected: (sym) { /* 现货选中 */ },
///   ),
/// );
/// ```
class SymbolPickerSheet extends ConsumerStatefulWidget {
  const SymbolPickerSheet({
    super.key,
    required this.onSelected,
    this.onSpotSelected,
    this.currentSymbol,
    this.initialTab = SymbolPickerTab.futures,
    this.visibleTabs,
    this.title,
  });

  /// 当前选中的 symbol（大写无斜线，如 "BTCUSDT"），用于高亮当前行
  final String? currentSymbol;

  /// 合约 tab 选中回调，返回大写无斜线格式的 symbol
  final ValueChanged<String> onSelected;

  /// 现货 tab 选中回调；若为 null 则复用 [onSelected]
  final ValueChanged<String>? onSpotSelected;

  /// 初始展示的 Tab，默认合约
  final SymbolPickerTab initialTab;

  /// 允许展示的 Tab 列表；null 或空表示全部展示
  final List<SymbolPickerTab>? visibleTabs;

  /// 弹窗标题（已废弃，Tab 本身即标题，保留为可选兼容参数）
  final String? title;

  @override
  ConsumerState<SymbolPickerSheet> createState() => _SymbolPickerSheetState();
}

class _SymbolPickerSheetState extends ConsumerState<SymbolPickerSheet> {
  final _searchCtrl = TextEditingController();
  String _query = '';
  late SymbolPickerTab _tab;

  // 本地 ticker 快照，通过节流 setState 刷新，保证所有 Riverpod
  // 读取发生在 build 阶段（而非 layout 阶段），避免 layout/semantics 断言崩溃。
  Map<String, MarketTicker> _futuresTickerBySymbol = {};
  Map<String, MarketTicker> _spotTickerBySymbol = {};

  bool _pendingRefresh = false;

  @override
  void initState() {
    super.initState();
    _tab = widget.initialTab;
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _syncSnapshot();
      // 预加载现货数据
      if (_tab == SymbolPickerTab.spot) {
        ref.read(marketProvider.notifier).loadSpotIfNeeded();
      }
    });
  }

  void _syncSnapshot() {
    if (!mounted) return;
    final mkt = ref.read(marketProvider);
    setState(() {
      _futuresTickerBySymbol = {for (final t in mkt.tickers) t.symbol: t};
      _spotTickerBySymbol = {for (final t in mkt.spotTickers) t.symbol: t};
    });
  }

  void _scheduleRefresh() {
    if (_pendingRefresh) return;
    _pendingRefresh = true;
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _pendingRefresh = false;
      _syncSnapshot();
    });
  }

  @override
  void dispose() {
    _searchCtrl.dispose();
    super.dispose();
  }

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

    // 只 watch displayOrder（币对列表结构），价格更新不触发重建
    final futuresSymbols = ref.watch(
      marketProvider.select((s) => s.displayOrder),
    );
    final spotSymbols = ref.watch(
      marketProvider.select((s) => s.spotDisplayOrder),
    );

    // 监听价格变化，节流刷新本地快照
    ref.listen<List<MarketTicker>>(
      marketProvider.select((s) => s.tickers),
      (_, __) => _scheduleRefresh(),
    );
    ref.listen<List<MarketTicker>>(
      marketProvider.select((s) => s.spotTickers),
      (_, __) => _scheduleRefresh(),
    );

    // 当前 tab 的数据
    final allSymbols =
        _tab == SymbolPickerTab.futures ? futuresSymbols : spotSymbols;
    final tickerBySymbol = _tab == SymbolPickerTab.futures
        ? _futuresTickerBySymbol
        : _spotTickerBySymbol;

    List<String> filtered;
    if (_query.isEmpty) {
      filtered = allSymbols;
    } else {
      final q = _query.toLowerCase();
      filtered = allSymbols.where((sym) {
        final t = tickerBySymbol[sym];
        return sym.toLowerCase().contains(q) ||
            (t?.baseAsset.toLowerCase().contains(q) ?? false);
      }).toList();
    }

    return DraggableScrollableSheet(
      initialChildSize: 0.85,
      minChildSize: 0.5,
      maxChildSize: 0.95,
      expand: false,
      builder: (_, scrollCtrl) => Column(
        children: [
          // ── 标题栏 ───────────────────────────────────────
          Padding(
            padding: const EdgeInsets.fromLTRB(16, 16, 16, 0),
            child: Row(
              children: [
                Text(
                  l10n.selectTradingPair,
                  style: TextStyle(
                    color: cs.onSurface,
                    fontSize: 16,
                    fontWeight: FontWeight.w600,
                  ),
                ),
                const Spacer(),
                GestureDetector(
                  onTap: () => Navigator.pop(context),
                  child: Icon(
                    Icons.close,
                    color: cs.onSurface.withAlpha(153),
                    size: 20,
                  ),
                ),
              ],
            ),
          ),

          // ── 合约 / 现货 Tab 切换 ────────────────────────
          _TabBar(
            current: _tab,
            visibleTabs: widget.visibleTabs,
            onChanged: (t) => setState(() {
              _tab = t;
              _query = '';
              _searchCtrl.clear();
            }),
          ),

          // ── 搜索框 ───────────────────────────────────────
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
            child: Container(
              height: 36,
              decoration: BoxDecoration(
                color: cs.surfaceContainerHighest.withAlpha(80),
                borderRadius: BorderRadius.circular(8),
              ),
              child: TextField(
                controller: _searchCtrl,
                style: TextStyle(color: cs.onSurface, fontSize: 14),
                onChanged: (v) => setState(() => _query = v.trim()),
                decoration: InputDecoration(
                  hintText: l10n.searchHint,
                  hintStyle: TextStyle(
                      color: cs.onSurface.withAlpha(100), fontSize: 14),
                  prefixIcon: Icon(
                    Icons.search,
                    color: cs.onSurface.withAlpha(100),
                    size: 18,
                  ),
                  border: InputBorder.none,
                  contentPadding: const EdgeInsets.symmetric(vertical: 8),
                ),
              ),
            ),
          ),

          // ── 列表头 ───────────────────────────────────────
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
            child: Row(
              children: [
                Expanded(
                  child: Text(
                    l10n.nameAndVolume,
                    style: TextStyle(
                      color: cs.onSurface.withAlpha(120),
                      fontSize: 11,
                    ),
                  ),
                ),
                Text(
                  l10n.latestPriceChange,
                  style: TextStyle(
                    color: cs.onSurface.withAlpha(120),
                    fontSize: 11,
                  ),
                ),
              ],
            ),
          ),
          const Divider(height: 1),

          // ── 币对列表 ─────────────────────────────────────
          Expanded(
            child: allSymbols.isEmpty
                ? Center(
                    child: _tab == SymbolPickerTab.spot
                        ? Text(
                            l10n.noOrders,
                            style: TextStyle(
                              color: cs.onSurface.withAlpha(120),
                              fontSize: 14,
                            ),
                          )
                        : const CircularProgressIndicator(),
                  )
                : ListView.builder(
                    controller: scrollCtrl,
                    itemCount: filtered.length,
                    itemBuilder: (ctx, i) {
                      final sym = filtered[i];
                      final ticker = tickerBySymbol[sym];
                      if (ticker == null) return const SizedBox.shrink();
                      return _TickerRow(
                        ticker: ticker,
                        isSelected: sym == widget.currentSymbol,
                        isSpot: _tab == SymbolPickerTab.spot,
                        onTap: () {
                          if (_tab == SymbolPickerTab.spot) {
                            (widget.onSpotSelected ?? widget.onSelected)(sym);
                          } else {
                            widget.onSelected(sym);
                          }
                        },
                      );
                    },
                  ),
          ),
        ],
      ),
    );
  }
}

// ── Tab 切换栏 ────────────────────────────────────────────

class _TabBar extends StatelessWidget {
  const _TabBar({
    required this.current,
    required this.onChanged,
    this.visibleTabs,
  });
  final SymbolPickerTab current;
  final ValueChanged<SymbolPickerTab> onChanged;
  final List<SymbolPickerTab>? visibleTabs;

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

    Widget tab(String label, SymbolPickerTab value) {
      final active = current == value;
      return Expanded(
        child: GestureDetector(
          onTap: () => onChanged(value),
          behavior: HitTestBehavior.opaque,
          child: Container(
            padding: const EdgeInsets.symmetric(vertical: 10),
            decoration: BoxDecoration(
              border: Border(
                bottom: BorderSide(
                  color: active ? AppColors.brand : Colors.transparent,
                  width: 2,
                ),
              ),
            ),
            alignment: Alignment.center,
            child: Text(
              label,
              style: TextStyle(
                fontSize: 14,
                fontWeight: active ? FontWeight.w600 : FontWeight.w400,
                color: active ? cs.onSurface : cs.onSurface.withAlpha(140),
              ),
            ),
          ),
        ),
      );
    }

    final tabs = visibleTabs != null && visibleTabs!.isNotEmpty
        ? visibleTabs!
        : const [SymbolPickerTab.futures, SymbolPickerTab.spot];
    if (tabs.length <= 1) return const SizedBox.shrink();

    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16),
      child: Row(
        children: tabs.map((t) {
          final label = t == SymbolPickerTab.futures
              ? l10n.perpetualFutures
              : l10n.spotTab;
          return tab(label, t);
        }).toList(),
      ),
    );
  }
}

// ── 单行 Widget（纯 StatelessWidget，无 Riverpod 订阅）──────────

class _TickerRow extends StatelessWidget {
  const _TickerRow({
    required this.ticker,
    required this.isSelected,
    required this.isSpot,
    required this.onTap,
  });

  final MarketTicker ticker;
  final bool isSelected;
  final bool isSpot;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final l10n = AppLocalizations.of(context)!;
    final isUp = ticker.change24h >= 0;
    final changeColor = AppColors.changeColor(ticker.change24h);

    return Material(
      color: Colors.transparent,
      child: InkWell(
        onTap: onTap,
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
          child: Row(
            children: [
              // ── 左侧：图标 + 币对名 + 成交量 ──────────────
              Expanded(
                child: Row(
                  children: [
                    _CoinIcon(icon: ticker.icon, baseAsset: ticker.baseAsset),
                    const SizedBox(width: 10),
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Row(
                            children: [
                              Flexible(
                                child: Text(
                                  formatUsdtPairDisplay(ticker.symbol),
                                  maxLines: 1,
                                  overflow: TextOverflow.ellipsis,
                                  style: TextStyle(
                                    color: isSelected
                                        ? AppColors.brand
                                        : cs.onSurface,
                                    fontSize: 13,
                                    fontWeight: FontWeight.w600,
                                  ),
                                ),
                              ),
                              const SizedBox(width: 4),
                              Container(
                                padding: const EdgeInsets.symmetric(
                                    horizontal: 4, vertical: 1),
                                decoration: BoxDecoration(
                                  color: cs.outline.withAlpha(40),
                                  borderRadius: BorderRadius.circular(3),
                                ),
                                child: Text(
                                  isSpot ? l10n.spotTab : l10n.perpetual,
                                  style: TextStyle(
                                    color: cs.onSurface.withAlpha(153),
                                    fontSize: 9,
                                  ),
                                ),
                              ),
                              if (isSelected)
                                Padding(
                                  padding: const EdgeInsets.only(left: 6),
                                  child: Icon(Icons.check,
                                      size: 14, color: AppColors.brand),
                                ),
                            ],
                          ),
                          const SizedBox(height: 2),
                          Text(
                            ticker.volume24h > 0
                                ? l10n.volumeWithValue(
                                    formatVolume(ticker.volume24h))
                                : l10n.volumeEmpty,
                            style: TextStyle(
                              color: cs.onSurface.withAlpha(120),
                              fontSize: 10,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),

              // ── 右侧：价格 + 涨跌幅 ───────────────────────
              Column(
                crossAxisAlignment: CrossAxisAlignment.end,
                children: [
                  Text(
                    ticker.lastPrice > 0
                        ? (ticker.lastPriceStr != null
                            ? formatRawPrice(ticker.lastPriceStr!)
                            : formatPrice(ticker.lastPrice))
                        : '--',
                    style: TextStyle(
                      color: ticker.lastPrice > 0
                          ? changeColor
                          : cs.onSurface.withAlpha(153),
                      fontSize: 13,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                  const SizedBox(height: 2),
                  Text(
                    ticker.lastPrice > 0
                        ? '${isUp ? '+' : ''}${ticker.change24h.toStringAsFixed(2)}%'
                        : '--',
                    style: TextStyle(
                      color: ticker.lastPrice > 0
                          ? changeColor
                          : cs.onSurface.withAlpha(100),
                      fontSize: 10,
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

// ── 圆形图标（网络图片 / 首字母回退）──────────────────────────

class _CoinIcon extends StatelessWidget {
  const _CoinIcon({required this.icon, required this.baseAsset});

  final String icon;
  final String baseAsset;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    return Container(
      width: 32,
      height: 32,
      decoration: BoxDecoration(
        color: cs.surfaceContainerHighest.withAlpha(80),
        shape: BoxShape.circle,
      ),
      child: ClipOval(
        child: icon.isNotEmpty
            ? CachedNetworkImage(
                imageUrl: icon,
                width: 32,
                height: 32,
                fit: BoxFit.cover,
                placeholder: (_, __) => _Fallback(baseAsset: baseAsset),
                errorWidget: (_, __, ___) => _Fallback(baseAsset: baseAsset),
              )
            : _Fallback(baseAsset: baseAsset),
      ),
    );
  }
}

class _Fallback extends StatelessWidget {
  const _Fallback({required this.baseAsset});
  final String baseAsset;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(
        baseAsset.isNotEmpty ? baseAsset[0] : '?',
        style: TextStyle(
          color: AppColors.brand,
          fontWeight: FontWeight.w700,
          fontSize: 13,
        ),
      ),
    );
  }
}
