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

import '../../../core/constants/market_list_layout.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 '../../../providers/market_provider.dart';
import '../../widgets/common/app_refresh_indicator.dart';
import '../../widgets/common/app_shimmer.dart';
import '../../widgets/common/coin_icon.dart';
import '../../widgets/market_list_row_layout.dart';

/// 行情页列表点击：按当前选中的「永续 / 现货」Tab 跳转对应 K 线详情。
void _pushMarketQuoteDetail(
  BuildContext context,
  WidgetRef ref,
  String rawSymbol,
) {
  final mode = ref.read(marketProvider).mode;
  final sym = rawSymbol.replaceAll('/', '').replaceAll('-', '').toUpperCase();
  if (sym.isEmpty) return;
  final path =
      mode == MarketMode.futures ? '/market/futures/$sym' : '/market/spot/$sym';
  context.push(path);
}

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

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final mode = ref.watch(marketProvider.select((s) => s.mode));
    final isLoading = ref.watch(marketProvider.select(
        (s) => mode == MarketMode.futures ? s.isLoading : s.spotLoading));
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            _SearchBar(
              onChanged: ref.read(marketProvider.notifier).setSearch,
            ),
            // ── 现货 / 合约 Tab 切换 ──────────────────────
            _MarketTabBar(
              mode: mode,
              onChanged: ref.read(marketProvider.notifier).setMode,
            ),
            Expanded(
              child: isLoading
                  ? const _MarketShimmer()
                  : mode == MarketMode.futures
                      ? const _MarketList()
                      : const _SpotMarketList(),
            ),
          ],
        ),
      ),
    );
  }
}

// ── 现货/合约 Tab 栏 ──────────────────────────────────────
class _MarketTabBar extends StatelessWidget {
  const _MarketTabBar({required this.mode, required this.onChanged});
  final MarketMode mode;
  final ValueChanged<MarketMode> onChanged;

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

    Widget tab(String label, MarketMode value) {
      final active = mode == 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(
                color: active ? cs.onSurface : cs.onSurface.withAlpha(140),
                fontSize: 14,
                fontWeight: active ? FontWeight.w600 : FontWeight.w400,
              ),
            ),
          ),
        ),
      );
    }

    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16),
      child: Row(
        children: [
          tab(l10n.perpetualFutures, MarketMode.futures),
          tab(l10n.spotTab, MarketMode.spot),
        ],
      ),
    );
  }
}

// ── 搜索框 ────────────────────────────────────────────────

class _SearchBar extends StatelessWidget {
  const _SearchBar({required this.onChanged});

  final ValueChanged<String> onChanged;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    return Padding(
      padding: const EdgeInsets.fromLTRB(16, 8, 16, 6),
      child: SizedBox(
        height: 38,
        child: Semantics(
          label: 'market_search_input',
          textField: true,
          child: TextField(
            onChanged: onChanged,
            style: TextStyle(color: cs.onSurface, fontSize: 13),
            textAlignVertical: TextAlignVertical.center,
            decoration: InputDecoration(
              hintText: AppLocalizations.of(context)!.searchMarket,
              hintStyle:
                  TextStyle(color: cs.onSurface.withAlpha(100), fontSize: 13),
              prefixIcon: Icon(Icons.search,
                  color: cs.onSurface.withAlpha(100), size: 18),
              prefixIconConstraints: const BoxConstraints(minWidth: 40),
              isDense: true,
              filled: true,
              fillColor: cs.surface,
              contentPadding:
                  const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
              border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(24),
                borderSide: BorderSide.none,
              ),
              enabledBorder: OutlineInputBorder(
                borderRadius: BorderRadius.circular(24),
                borderSide: BorderSide.none,
              ),
              focusedBorder: OutlineInputBorder(
                borderRadius: BorderRadius.circular(24),
                borderSide: BorderSide.none,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

// ── 行情列表主体 ──────────────────────────────────────────

// 只 select displaySymbols（symbol 列表），价格变化不触发列表重建。
// 各行通过 tickerProvider(symbol) 独立订阅自己的 ticker 数据。
class _MarketList extends ConsumerWidget {
  const _MarketList();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final symbols = ref.watch(marketProvider.select((s) => s.displaySymbols));

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // "永续合约" 标题
        Padding(
          padding: const EdgeInsets.fromLTRB(16, 4, 16, 0),
          child: Text(
            AppLocalizations.of(context)!.perpetualFutures,
            style: TextStyle(
              fontSize: 16,
              fontWeight: FontWeight.w700,
              color: Theme.of(context).colorScheme.onSurface,
            ),
          ),
        ),
        // 列表表头
        const _ListHeader(),
        // 行情行列表
        Expanded(
          child: AppRefreshIndicator(
            onRefresh: () => ref.read(marketProvider.notifier).refresh(),
            child: ListView.builder(
              itemCount: symbols.length,
              itemBuilder: (context, index) {
                // 只传 symbol，不传 ticker 对象
                return _TickerRow(symbol: symbols[index]);
              },
            ),
          ),
        ),
      ],
    );
  }
}

// ── 现货行情列表 ──────────────────────────────────────────

class _SpotMarketList extends ConsumerWidget {
  const _SpotMarketList();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final symbols =
        ref.watch(marketProvider.select((s) => s.spotDisplaySymbols));

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(16, 4, 16, 0),
          child: Text(
            AppLocalizations.of(context)!.spotTab,
            style: TextStyle(
              fontSize: 16,
              fontWeight: FontWeight.w700,
              color: Theme.of(context).colorScheme.onSurface,
            ),
          ),
        ),
        const _SpotListHeader(),
        Expanded(
          child: AppRefreshIndicator(
            onRefresh: () => ref.read(marketProvider.notifier).refresh(),
            child: symbols.isEmpty
                ? Center(
                    child: Text(
                      AppLocalizations.of(context)!.noOrders,
                      style: TextStyle(
                        color: Theme.of(context)
                            .colorScheme
                            .onSurface
                            .withAlpha(140),
                        fontSize: 14,
                      ),
                    ),
                  )
                : ListView.builder(
                    itemCount: symbols.length,
                    itemBuilder: (context, index) =>
                        _SpotTickerRow(symbol: symbols[index]),
                  ),
          ),
        ),
      ],
    );
  }
}

// ── 现货列表表头 ──────────────────────────────────────────

class _SpotListHeader extends ConsumerWidget {
  const _SpotListHeader();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final cs = Theme.of(context).colorScheme;
    final sortField = ref.watch(marketProvider.select((s) => s.spotSortField));
    final sortAsc = ref.watch(marketProvider.select((s) => s.spotSortAsc));

    Widget sortCell({
      required String label,
      required MarketSortField field,
      MainAxisAlignment align = MainAxisAlignment.start,
    }) {
      final active = sortField == field;
      final color = active ? cs.onSurface : cs.onSurface.withAlpha(120);
      return GestureDetector(
        onTap: () => ref.read(marketProvider.notifier).toggleSpotSort(field),
        behavior: HitTestBehavior.opaque,
        child: Row(
          mainAxisAlignment: align,
          children: [
            Flexible(
              child: Text(
                label,
                style: TextStyle(color: color, fontSize: 12),
                maxLines: 1,
                overflow: TextOverflow.ellipsis,
                textAlign: align == MainAxisAlignment.end
                    ? TextAlign.right
                    : TextAlign.left,
              ),
            ),
            const SizedBox(width: 2),
            _SortIcon(active: active, asc: sortAsc, color: color),
          ],
        ),
      );
    }

    Widget trailingSortCol({
      required String label,
      required MarketSortField field,
    }) {
      final active = sortField == field;
      final color = active ? cs.onSurface : cs.onSurface.withAlpha(120);
      return GestureDetector(
        onTap: () => ref.read(marketProvider.notifier).toggleSpotSort(field),
        behavior: HitTestBehavior.opaque,
        child: FittedBox(
          fit: BoxFit.scaleDown,
          alignment: Alignment.center,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            mainAxisSize: MainAxisSize.min,
            children: [
              Text(label, style: TextStyle(color: color, fontSize: 12)),
              const SizedBox(width: 2),
              _SortIcon(active: active, asc: sortAsc, color: color),
            ],
          ),
        ),
      );
    }

    return Padding(
      padding: const EdgeInsets.fromLTRB(16, 8, 16, 4),
      child: MarketListHeaderRow(
        leading: const SizedBox(width: 30),
        leadingGap: 8,
        name: sortCell(
          label: AppLocalizations.of(context)!.nameVolume,
          field: MarketSortField.volume,
        ),
        price: sortCell(
          label: AppLocalizations.of(context)!.latestPriceFull,
          field: MarketSortField.price,
          align: MainAxisAlignment.end,
        ),
        change: trailingSortCol(
          label: AppLocalizations.of(context)!.change24hFull,
          field: MarketSortField.change,
        ),
      ),
    );
  }
}

// ── 现货行情行 ────────────────────────────────────────────

class _SpotTickerRow extends ConsumerWidget {
  const _SpotTickerRow({required this.symbol});
  final String symbol;

  static String _formatVolume(double v) {
    if (v >= 1e9) return '${(v / 1e9).toStringAsFixed(2)}B';
    if (v >= 1e6) return '${(v / 1e6).toStringAsFixed(2)}M';
    if (v >= 1e3) return '${(v / 1e3).toStringAsFixed(2)}K';
    return v.toStringAsFixed(2);
  }

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final cs = Theme.of(context).colorScheme;
    final ticker = ref.watch(spotTickerProvider(symbol));
    if (ticker == null) return const SizedBox.shrink();

    final volumeStr = _formatVolume(ticker.volume24h);
    final changeColor = AppColors.changeColor(ticker.change24h);
    final changeStr = formatChange(ticker.change24h);

    return InkWell(
      onTap: () => _pushMarketQuoteDetail(context, ref, ticker.symbol),
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
        child: MarketListDataRow(
          leading: CoinIcon(
            symbol: ticker.baseAsset,
            iconUrl: ticker.icon,
            size: 30,
          ),
          leadingGap: 8,
          name: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                formatUsdtPairDisplay(ticker.symbol),
                style: TextStyle(
                  color: cs.onSurface,
                  fontSize: 14,
                  fontWeight: FontWeight.w600,
                ),
                maxLines: 1,
                overflow: TextOverflow.ellipsis,
              ),
              Text(
                '${AppLocalizations.of(context)!.spot} · $volumeStr',
                style: TextStyle(
                  color: cs.onSurface.withAlpha(120),
                  fontSize: 11,
                ),
                maxLines: 1,
                overflow: TextOverflow.ellipsis,
              ),
            ],
          ),
          price: Column(
            crossAxisAlignment: CrossAxisAlignment.end,
            mainAxisSize: MainAxisSize.min,
            children: [
              Text(
                ticker.lastPrice > 0
                    ? (ticker.lastPriceStr != null
                        ? formatRawPrice(ticker.lastPriceStr!)
                        : formatPrice(ticker.lastPrice))
                    : '--',
                style: TextStyle(
                  color: cs.onSurface,
                  fontSize: 13,
                  fontWeight: FontWeight.w500,
                  fontFeatures: const [FontFeature.tabularFigures()],
                ),
                maxLines: 1,
                overflow: TextOverflow.ellipsis,
              ),
              Text(
                ticker.lastPrice > 0
                    ? formatFiatPrice(ticker.lastPrice,
                        pricePrecision: ticker.pricePrecision)
                    : '--',
                style: TextStyle(
                  color: cs.onSurface.withAlpha(120),
                  fontSize: 11,
                  fontFeatures: const [FontFeature.tabularFigures()],
                ),
                maxLines: 1,
                overflow: TextOverflow.ellipsis,
              ),
            ],
          ),
          change: Container(
            height: 34,
            decoration: BoxDecoration(
              color: changeColor,
              borderRadius: BorderRadius.circular(6),
            ),
            alignment: Alignment.center,
            child: Text(
              ticker.lastPrice > 0 ? changeStr : '--',
              style: const TextStyle(
                color: Colors.white,
                fontSize: 13,
                fontWeight: FontWeight.w600,
                fontFeatures: [FontFeature.tabularFigures()],
              ),
              textAlign: TextAlign.center,
            ),
          ),
        ),
      ),
    );
  }
}

// ── 列表表头（合约） ──────────────────────────────────────────

class _ListHeader extends ConsumerWidget {
  const _ListHeader();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final cs = Theme.of(context).colorScheme;
    final sortField = ref.watch(marketProvider.select((s) => s.sortField));
    final sortAsc = ref.watch(marketProvider.select((s) => s.sortAsc));

    Widget buildSortCell({
      required String label,
      required MarketSortField field,
      MainAxisAlignment align = MainAxisAlignment.start,
      required String semanticsLabel,
    }) {
      final active = sortField == field;
      final color = active ? cs.onSurface : cs.onSurface.withAlpha(120);
      return Semantics(
        label: semanticsLabel,
        button: true,
        onTap: () => ref.read(marketProvider.notifier).toggleSort(field),
        child: GestureDetector(
          onTap: () => ref.read(marketProvider.notifier).toggleSort(field),
          behavior: HitTestBehavior.opaque,
          child: Row(
            mainAxisAlignment: align,
            children: [
              Flexible(
                child: Text(
                  label,
                  style: TextStyle(color: color, fontSize: 12),
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  textAlign: align == MainAxisAlignment.end
                      ? TextAlign.right
                      : TextAlign.left,
                ),
              ),
              const SizedBox(width: 2),
              _SortIcon(active: active, asc: sortAsc, color: color),
            ],
          ),
        ),
      );
    }

    Widget buildTrailingSortCol({
      required String label,
      required MarketSortField field,
      required String semanticsLabel,
    }) {
      final active = sortField == field;
      final color = active ? cs.onSurface : cs.onSurface.withAlpha(120);
      return Semantics(
        label: semanticsLabel,
        button: true,
        onTap: () => ref.read(marketProvider.notifier).toggleSort(field),
        child: GestureDetector(
          onTap: () => ref.read(marketProvider.notifier).toggleSort(field),
          behavior: HitTestBehavior.opaque,
          child: FittedBox(
            fit: BoxFit.scaleDown,
            alignment: Alignment.center,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              mainAxisSize: MainAxisSize.min,
              children: [
                Text(label, style: TextStyle(color: color, fontSize: 12)),
                const SizedBox(width: 2),
                _SortIcon(active: active, asc: sortAsc, color: color),
              ],
            ),
          ),
        ),
      );
    }

    return Padding(
      padding: const EdgeInsets.fromLTRB(16, 8, 16, 4),
      child: MarketListHeaderRow(
        leading: const SizedBox(width: 40),
        name: buildSortCell(
            label: AppLocalizations.of(context)!.nameVolume,
            field: MarketSortField.volume,
            semanticsLabel: 'market_sort_volume'),
        price: buildSortCell(
            label: AppLocalizations.of(context)!.latestPriceFull,
            field: MarketSortField.price,
            align: MainAxisAlignment.end,
            semanticsLabel: 'market_sort_price'),
        change: buildTrailingSortCol(
            label: AppLocalizations.of(context)!.change24hFull,
            field: MarketSortField.change,
            semanticsLabel: 'market_sort_change'),
      ),
    );
  }
}

/// 排序箭头图标：上下双三角，激活时高亮当前方向
class _SortIcon extends StatelessWidget {
  const _SortIcon(
      {required this.active, required this.asc, required this.color});
  final bool active;
  final bool asc;
  final Color color;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final dim = cs.onSurface.withAlpha(50);
    return SizedBox(
      width: 12,
      height: 16,
      child: Stack(
        children: [
          Positioned(
            top: 0,
            left: 0,
            right: 0,
            child: Icon(Icons.arrow_drop_up,
                size: 14, color: active && asc ? color : dim),
          ),
          Positioned(
            bottom: 0,
            left: 0,
            right: 0,
            child: Icon(Icons.arrow_drop_down,
                size: 14, color: active && !asc ? color : dim),
          ),
        ],
      ),
    );
  }
}

// ── 行情行 ────────────────────────────────────────────────

// 每行通过 tickerProvider(symbol) 独立订阅，
// BTC 价格变化只重建 BTC 行，不影响其他行。
class _TickerRow extends ConsumerWidget {
  const _TickerRow({required this.symbol});

  final String symbol;

  static String _formatVolume(double v) {
    if (v >= 1e9) return '${(v / 1e9).toStringAsFixed(2)}B';
    if (v >= 1e6) return '${(v / 1e6).toStringAsFixed(2)}M';
    if (v >= 1e3) return '${(v / 1e3).toStringAsFixed(2)}K';
    return v.toStringAsFixed(2);
  }

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final cs = Theme.of(context).colorScheme;
    final ticker = ref.watch(tickerProvider(symbol));
    if (ticker == null) return const SizedBox.shrink();

    final volumeStr = _formatVolume(ticker.volume24h);
    final changeColor = AppColors.changeColor(ticker.change24h);
    final changeStr = formatChange(ticker.change24h);

    return Semantics(
      label: 'market_item_${ticker.symbol}',
      button: true,
      onTap: () => _pushMarketQuoteDetail(context, ref, ticker.symbol),
      child: InkWell(
        onTap: () => _pushMarketQuoteDetail(context, ref, ticker.symbol),
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 11),
          child: MarketListDataRow(
            leading: CoinIcon(
              symbol: ticker.baseAsset,
              iconUrl: ticker.icon,
              size: 40,
              borderRadius: 12,
            ),
            name: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  formatUsdtPairDisplay(ticker.symbol),
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  style: TextStyle(
                    color: cs.onSurface,
                    fontSize: 13,
                    fontWeight: FontWeight.w500,
                  ),
                ),
                Text(
                  '${AppLocalizations.of(context)!.perpetual} · $volumeStr',
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  style: TextStyle(
                    color: cs.onSurface.withAlpha(153),
                    fontSize: 12,
                  ),
                ),
              ],
            ),
            price: Column(
              crossAxisAlignment: CrossAxisAlignment.end,
              mainAxisSize: MainAxisSize.min,
              children: [
                Text(
                  ticker.lastPriceStr != null
                      ? formatRawPrice(ticker.lastPriceStr!)
                      : formatPrice(ticker.lastPrice),
                  style: TextStyle(
                    color: cs.onSurface,
                    fontSize: 14,
                    fontWeight: FontWeight.w500,
                    fontFeatures: const [FontFeature.tabularFigures()],
                  ),
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                ),
                Text(
                  formatFiatPrice(ticker.lastPrice,
                      pricePrecision: ticker.pricePrecision),
                  style: TextStyle(
                    color: cs.onSurface.withAlpha(153),
                    fontSize: 11,
                    fontFeatures: const [FontFeature.tabularFigures()],
                  ),
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                ),
              ],
            ),
            change: Container(
              height: 34,
              decoration: BoxDecoration(
                color: changeColor,
                borderRadius: BorderRadius.circular(6),
              ),
              alignment: Alignment.center,
              child: Text(
                changeStr,
                style: const TextStyle(
                  color: Colors.white,
                  fontSize: 13,
                  fontWeight: FontWeight.w600,
                  fontFeatures: [FontFeature.tabularFigures()],
                ),
                textAlign: TextAlign.center,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

// ── 行情骨架屏 ──────────────────────────────────────────────
class _MarketShimmer extends StatelessWidget {
  const _MarketShimmer();

  @override
  Widget build(BuildContext context) {
    return AppShimmer(
      child: ListView.builder(
        physics: const NeverScrollableScrollPhysics(),
        itemCount: 10,
        itemBuilder: (_, __) => Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
          child: MarketListDataRow(
            leading: shimmerCircle(40),
            name: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                shimmerBox(70, 14),
                const SizedBox(height: 6),
                shimmerBox(50, 11),
              ],
            ),
            price: Column(
              crossAxisAlignment: CrossAxisAlignment.end,
              children: [
                shimmerBox(80, 14),
                const SizedBox(height: 6),
                shimmerBox(50, 11),
              ],
            ),
            change: shimmerBox(kMarketListChangeBadgeWidth, 30, radius: 6),
          ),
        ),
      ),
    );
  }
}
