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

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:gal/gal.dart';
import 'package:go_router/go_router.dart';
import 'package:path_provider/path_provider.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'package:reown_appkit/modal/services/coinbase_service/utils/coinbase_utils.dart';
import 'package:reown_appkit/reown_appkit.dart';

import '../../../core/config/app_config.dart';
import '../../../core/l10n/app_localizations.dart';
import '../../../core/theme/app_colors.dart';
import '../../../core/utils/top_toast.dart';
import '../../../core/wallet/evm_recharge.dart';
import '../../../core/wallet/tron_recharge.dart';
import '../../../core/wallet/wallet_connect_recharge_helper.dart';
import '../../../core/wallet/wallet_connect_tron_recharge.dart';
import '../../../data/models/asset/recharge_order.dart';
import '../../../providers/deposit_provider.dart';

/// AppKit 默认只为 eip155/solana 填 methods；`tron` 会为 `[]`，钱包不会授权 `tron_signTransaction`。
Map<String, RequiredNamespace> _depositAppKitOptionalNamespaces() {
  final map = <String, RequiredNamespace>{};
  for (final ns in ReownAppKitModalNetworks.getAllSupportedNamespaces()) {
    final networks =
        ReownAppKitModalNetworks.getAllSupportedNetworks(namespace: ns);
    final methods = ns == 'tron'
        ? <String>['tron_signTransaction', 'tron_signMessage']
        : (NetworkUtils.defaultNetworkMethods[ns] ?? <String>[]);
    map[ns] = RequiredNamespace(
      chains: networks.map((e) => e.chainId).toList(),
      methods: methods,
      events: NetworkUtils.defaultNetworkEvents[ns] ?? <String>[],
    );
  }
  return map;
}

/// 充币：与 Web `DepositView.vue` + `useWalletConnectDeposit` 对齐（订单 + WalletConnect / 手动 Hash）。
class DepositScreen extends ConsumerStatefulWidget {
  const DepositScreen({super.key});

  @override
  ConsumerState<DepositScreen> createState() => _DepositScreenState();
}

class _DepositScreenState extends ConsumerState<DepositScreen>
    with SingleTickerProviderStateMixin {
  static const int _tabManual = 0;
  static const int _tabOnChain = 1;

  late final TabController _depositModeTab;
  final _qrKey = GlobalKey();
  final _amountCtrl = TextEditingController();
  final _hashCtrl = TextEditingController();
  bool _savingQr = false;
  ReownAppKitModal? _appKitModal;
  bool _appKitInitializing = false;

  @override
  void initState() {
    super.initState();
    _depositModeTab = TabController(length: 2, vsync: this);
  }

  @override
  void dispose() {
    _depositModeTab.dispose();
    _amountCtrl.dispose();
    _hashCtrl.dispose();
    _appKitModal?.disconnect();
    _appKitModal?.dispose();
    super.dispose();
  }

  Future<void> _ensureAppKitModal() async {
    final projectId = AppConfig.walletConnectProjectId;
    if (projectId.isEmpty) {
      return;
    }
    if (_appKitModal != null) {
      return;
    }
    if (_appKitInitializing) {
      return;
    }
    _appKitInitializing = true;
    try {
      ReownAppKitModalNetworks.removeSupportedNetworks('solana');
      ReownAppKitModalNetworks.addSupportedNetworks('tron', [
        ReownAppKitModalNetworkInfo(
          name: 'Tron',
          chainId: kTronMainnetChainIdHex,
          chainIcon:
              'https://pbs.twimg.com/profile_images/1761904730668675072/v98T7vRL_400x400.jpg',
          currency: 'TRX',
          rpcUrl: AppConfig.tronFullHost,
          explorerUrl: 'https://tronscan.org',
        ),
      ]);
      final m = ReownAppKitModal(
        context: context,
        projectId: projectId,
        logLevel: kDebugMode ? LogLevel.error : LogLevel.nothing,
        disconnectOnDispose: true,
        /// 跳过 Coinbase Wallet 的 Explorer 单钱包拉取，避免弱网环境下访问 api.web3modal.com 被 RST 时阻塞/报错（充币不需 Coinbase）。
        excludedWalletIds: {CoinbaseUtils.walletId},
        metadata: PairingMetadata(
          name: 'iBit',
          description:
              AppLocalizations.of(context)!.walletConnectPairingDescription,
          url: 'https://ibit123.com',
          icons: const [
            'https://raw.githubusercontent.com/reown-com/reown_flutter/refs/heads/develop/assets/appkit_logo.png',
          ],
          redirect: Redirect(
            native: 'ibit://',
            universal: 'https://ibit123.com',
            linkMode: false,
          ),
        ),
        optionalNamespaces: _depositAppKitOptionalNamespaces(),
        featuresConfig: FeaturesConfig(socials: const []),
      );
      await m.init();
      if (mounted) {
        setState(() {
          _appKitModal = m;
        });
      }
    } finally {
      _appKitInitializing = false;
    }
  }

  Future<void> _saveQr(String address) async {
    if (_savingQr || address.isEmpty) {
      return;
    }
    setState(() => _savingQr = true);
    try {
      final hasAccess = await Gal.hasAccess(toAlbum: true);
      if (!hasAccess) {
        final granted = await Gal.requestAccess(toAlbum: true);
        if (!granted) {
          if (mounted) {
            showTopToast(context,
                message: AppLocalizations.of(context)!.saveFailed);
          }
          return;
        }
      }
      await WidgetsBinding.instance.endOfFrame;
      final boundary =
          _qrKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
      final image = await boundary.toImage(pixelRatio: 3.0);
      final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
      final bytes = byteData!.buffer.asUint8List();
      final tempDir = await getTemporaryDirectory();
      final file = File(
          '${tempDir.path}/deposit_qr_${DateTime.now().millisecondsSinceEpoch}.png');
      await file.writeAsBytes(bytes);
      await Gal.putImage(file.path);
      if (mounted) {
        showTopToast(context,
            message: AppLocalizations.of(context)!.saveSuccess);
      }
    } catch (e) {
      if (mounted) {
        showTopToast(context,
            message: AppLocalizations.of(context)!.saveFailed);
      }
    } finally {
      if (mounted) {
        setState(() => _savingQr = false);
      }
    }
  }

  bool _validateAmount(AppLocalizations l10n) {
    final s = _amountCtrl.text.trim();
    if (s.isEmpty) {
      showTopToast(context, message: l10n.depositEnterAmount);
      return false;
    }
    final n = num.tryParse(s.replaceAll(',', ''));
    if (n == null || n <= 0) {
      showTopToast(context, message: l10n.depositAmountPositive);
      return false;
    }
    return true;
  }

  Future<void> _onCreateOrder() async {
    final l10n = AppLocalizations.of(context)!;
    if (!_validateAmount(l10n)) {
      return;
    }
    await ref.read(depositProvider.notifier).createRechargeOrder(_amountCtrl.text);
    final err = ref.read(depositProvider).errorMessage;
    if (!mounted) {
      return;
    }
    if (err != null) {
      showTopToast(context, message: err);
    } else {
      _hashCtrl.clear();
      showTopToast(context, message: l10n.depositOrderCreated);
    }
  }

  Future<void> _onSubmitHash() async {
    final l10n = AppLocalizations.of(context)!;
    final h = _hashCtrl.text.trim();
    if (h.isEmpty) {
      showTopToast(context, message: l10n.depositTxHashPlaceholder);
      return;
    }
    await ref.read(depositProvider.notifier).submitTxHash(h);
    final err = ref.read(depositProvider).errorMessage;
    if (!mounted) {
      return;
    }
    if (err != null) {
      showTopToast(context, message: err);
    } else {
      showTopToast(context, message: l10n.confirm);
    }
  }

  Future<void> _onWalletPay(
    RechargeFlatNetworkOption net,
    RechargeOrderDetail order,
  ) async {
    final l10n = AppLocalizations.of(context)!;
    if (AppConfig.walletConnectProjectId.isEmpty) {
      showTopToast(context, message: l10n.depositWalletConnectNotConfigured);
      return;
    }
    ref.read(depositProvider.notifier).setWalletPayBusy(true);
    try {
      await _ensureAppKitModal();
      final modal = _appKitModal;
      if (modal == null) {
        return;
      }
      final hash = _isTronLike(net)
          ? await WalletConnectTronRecharge.connectAndPayTron(
              appKitModal: modal,
              network: net,
              order: order,
            )
          : await WalletConnectRechargeHelper.connectAndPay(
              appKitModal: modal,
              network: net,
              order: order,
            );
      if (!mounted) {
        return;
      }
      _hashCtrl.text = hash;
      await ref.read(depositProvider.notifier).submitTxHash(hash);
      final err = ref.read(depositProvider).errorMessage;
      if (!mounted) {
        return;
      }
      if (err != null) {
        showTopToast(context, message: err);
      } else {
        showTopToast(context, message: l10n.confirm);
      }
    } catch (e) {
      if (mounted) {
        showTopToast(context, message: e.toString());
      }
    } finally {
      ref.read(depositProvider.notifier).setWalletPayBusy(false);
    }
  }

  String _statusLabel(AppLocalizations l10n, int status) {
    switch (status) {
      case 0:
        return l10n.rechargeStatus0;
      case 1:
        return l10n.rechargeStatus1;
      case 2:
        return l10n.rechargeStatus2;
      case 3:
        return l10n.rechargeStatus3;
      case 4:
        return l10n.rechargeStatus4;
      default:
        return '$status';
    }
  }

  bool _canWalletConnect(
    RechargeFlatNetworkOption? net,
    RechargeOrderDetail? order,
  ) {
    if (net == null || order == null || !order.isPendingPayment) {
      return false;
    }
    if (resolveEvmChainId(net.protocol, net.networkName) != null) {
      return true;
    }
    return isTronDepositNetwork(net.protocol, net.networkName);
  }

  bool _isTronLike(RechargeFlatNetworkOption? net) {
    if (net == null) {
      return false;
    }
    if (resolveEvmChainId(net.protocol, net.networkName) != null) {
      return false;
    }
    return isTronDepositNetwork(net.protocol, net.networkName);
  }

  String _networkProtocolLabel(RechargeFlatNetworkOption net) {
    final protocol = net.protocol.trim();
    final name = net.networkName.trim();
    if (protocol.isEmpty) {
      return name;
    }
    if (name.isEmpty) {
      return protocol;
    }
    return '$protocol·$name';
  }

  String _subCoinLabel(RechargeFlatNetworkOption net) {
    final cn = net.coinNameCn.trim();
    if (cn.isNotEmpty && cn != net.coinName) {
      return '${net.coinName} ($cn)';
    }
    return net.coinName;
  }

  String _walletPayButtonLabel(
    AppLocalizations l10n,
    RechargeFlatNetworkOption? net,
  ) {
    if (net != null && resolveEvmChainId(net.protocol, net.networkName) != null) {
      return '${l10n.depositWalletConnectPay}(EVM)';
    }
    return l10n.depositWalletConnectPay;
  }

  BoxDecoration _panelDecoration(ColorScheme cs, bool isDark) {
    return BoxDecoration(
      color: isDark ? AppColors.darkBgSecondary : AppColors.lightBgSecondary,
      borderRadius: BorderRadius.circular(12),
      border: Border.all(color: cs.outline.withAlpha(40)),
    );
  }

  Widget _buildModeTabSwitcher(
    ColorScheme cs,
    AppLocalizations l10n,
    bool isDark,
  ) {
    return Container(
      height: 44,
      padding: const EdgeInsets.all(4),
      decoration: BoxDecoration(
        color: isDark ? AppColors.darkBgSecondary : AppColors.lightBgSecondary,
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: cs.outline.withAlpha(50)),
      ),
      child: TabBar(
        controller: _depositModeTab,
        indicator: BoxDecoration(
          color: AppColors.brand,
          borderRadius: BorderRadius.circular(8),
        ),
        indicatorSize: TabBarIndicatorSize.tab,
        dividerColor: Colors.transparent,
        labelColor: Colors.black,
        unselectedLabelColor: cs.onSurface.withAlpha(180),
        labelStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
        unselectedLabelStyle:
            const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
        tabs: [
          Tab(text: l10n.depositTabManual),
          Tab(text: l10n.depositTabOnChain),
        ],
      ),
    );
  }

  void _resetToNewRecharge(DepositNotifier notifier) {
    notifier.clearCurrentOrder();
    _amountCtrl.clear();
    _hashCtrl.clear();
  }

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final l10n = AppLocalizations.of(context)!;
    final state = ref.watch(depositProvider);
    final notifier = ref.read(depositProvider.notifier);
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final wcConfigured = AppConfig.walletConnectProjectId.isNotEmpty;
    final hasOrder = state.currentOrder != null;

    return ReownAppKitModalTheme(
      isDarkMode: isDark,
      child: Scaffold(
        appBar: AppBar(
          leading: IconButton(
            icon: const Icon(Icons.chevron_left, size: 28),
            onPressed: () => context.pop(),
          ),
          title: Text(
            hasOrder ? l10n.depositOrderInfo : l10n.depositCoin,
            style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
          ),
          centerTitle: true,
          actions: [
            TextButton(
              onPressed: hasOrder
                  ? () => _resetToNewRecharge(notifier)
                  : () => context.push('/asset/deposit/history'),
              child: Text(
                hasOrder ? l10n.depositNewRecharge : l10n.depositRecord,
                style: TextStyle(
                  color: hasOrder ? AppColors.brand : cs.onSurface,
                  fontSize: 14,
                  fontWeight: FontWeight.w500,
                ),
              ),
            ),
          ],
        ),
        body: _buildBody(context, state, notifier, cs, l10n, isDark,
            wcConfigured: wcConfigured),
      ),
    );
  }

  Widget _buildBody(
    BuildContext context,
    DepositState state,
    DepositNotifier notifier,
    ColorScheme cs,
    AppLocalizations l10n,
    bool isDark, {
    required bool wcConfigured,
  }) {
    if (state.loadingParents) {
      return const Center(child: CircularProgressIndicator());
    }
    if (state.errorMessage != null &&
        state.parentCoins.isEmpty &&
        !state.loadingParents) {
      return Center(
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Text(state.errorMessage!, textAlign: TextAlign.center),
              const SizedBox(height: 16),
              FilledButton(
                onPressed: () => notifier.refresh(),
                child: Text(l10n.retry),
              ),
            ],
          ),
        ),
      );
    }

    final order = state.currentOrder;

    return SingleChildScrollView(
      padding: const EdgeInsets.fromLTRB(16, 16, 16, 32),
      child: order == null
          ? _buildOrderForm(context, state, notifier, cs, l10n, isDark)
          : _buildOrderDetail(
              context,
              state,
              notifier,
              cs,
              l10n,
              isDark,
              order,
              wcConfigured: wcConfigured,
            ),
    );
  }

  Widget _buildOrderForm(
    BuildContext context,
    DepositState state,
    DepositNotifier notifier,
    ColorScheme cs,
    AppLocalizations l10n,
    bool isDark,
  ) {
    final net = state.selectedNetwork;
    final flatIndex = state.flatNetworks.isEmpty
        ? null
        : state.selectedFlatIndex.clamp(0, state.flatNetworks.length - 1);

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _buildModeTabSwitcher(cs, l10n, isDark),
        const SizedBox(height: 20),
        Text(
          l10n.depositMainnetProtocol,
          style: TextStyle(color: cs.onSurface.withAlpha(153), fontSize: 13),
        ),
        const SizedBox(height: 8),
        Container(
          padding: const EdgeInsets.symmetric(horizontal: 12),
          decoration: _panelDecoration(cs, isDark),
          child: DropdownButtonHideUnderline(
            child: DropdownButton<int>(
              isExpanded: true,
              value: flatIndex,
              hint: Text(
                state.childrenLoading
                    ? l10n.loading
                    : l10n.depositSelectNetworkFirst,
                style: TextStyle(color: cs.onSurface.withAlpha(140)),
              ),
              icon: Icon(Icons.keyboard_arrow_down,
                  color: cs.onSurface.withAlpha(153)),
              items: [
                for (var i = 0; i < state.flatNetworks.length; i++)
                  DropdownMenuItem(
                    value: i,
                    child: Text(
                      _networkProtocolLabel(state.flatNetworks[i]),
                      style: TextStyle(color: cs.onSurface, fontSize: 15),
                    ),
                  ),
              ],
              onChanged: state.childrenLoading
                  ? null
                  : (v) {
                      if (v != null) {
                        notifier.selectFlatNetwork(v);
                      }
                    },
            ),
          ),
        ),
        if (state.parentCoins.length > 1) ...[
          const SizedBox(height: 12),
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 12),
            decoration: _panelDecoration(cs, isDark),
            child: DropdownButtonHideUnderline(
              child: DropdownButton<int>(
                isExpanded: true,
                value: state.parentCoins.isEmpty
                    ? null
                    : state.selectedParentIndex.clamp(
                        0, state.parentCoins.length - 1),
                items: [
                  for (var i = 0; i < state.parentCoins.length; i++)
                    DropdownMenuItem(
                      value: i,
                      child: Text(
                        state.parentCoins[i].nameCn.isNotEmpty
                            ? state.parentCoins[i].nameCn
                            : state.parentCoins[i].name,
                        style: TextStyle(color: cs.onSurface, fontSize: 15),
                      ),
                    ),
                ],
                onChanged: state.childrenLoading
                    ? null
                    : (v) {
                        if (v != null) {
                          notifier.selectParent(v);
                        }
                      },
              ),
            ),
          ),
        ],
        if (state.childrenLoading) ...[
          const SizedBox(height: 12),
          const LinearProgressIndicator(),
        ],
        if (net != null) ...[
          const SizedBox(height: 12),
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(14),
            decoration: _panelDecoration(cs, isDark),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  l10n.depositSubCoin,
                  style:
                      TextStyle(color: cs.onSurface.withAlpha(140), fontSize: 12),
                ),
                const SizedBox(height: 4),
                Text(
                  _subCoinLabel(net),
                  style: TextStyle(color: cs.onSurface, fontSize: 14),
                ),
                if (net.hasTokenContract) ...[
                  const SizedBox(height: 12),
                  Text(
                    l10n.depositContractAddress,
                    style: TextStyle(
                        color: cs.onSurface.withAlpha(140), fontSize: 12),
                  ),
                  const SizedBox(height: 4),
                  SelectableText(
                    net.contractAddress,
                    style: TextStyle(
                      color: cs.onSurface,
                      fontSize: 12,
                      fontFamily: 'monospace',
                    ),
                  ),
                ],
              ],
            ),
          ),
        ],
        const SizedBox(height: 20),
        Text(
          l10n.depositEnterAmount,
          style: TextStyle(color: cs.onSurface.withAlpha(153), fontSize: 13),
        ),
        const SizedBox(height: 8),
        TextField(
          controller: _amountCtrl,
          keyboardType: const TextInputType.numberWithOptions(decimal: true),
          decoration: InputDecoration(
            filled: true,
            fillColor:
                isDark ? AppColors.darkBgSecondary : AppColors.lightBgSecondary,
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(10),
              borderSide: BorderSide(color: cs.outline.withAlpha(50)),
            ),
            enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(10),
              borderSide: BorderSide(color: cs.outline.withAlpha(50)),
            ),
            hintText: l10n.depositEnterAmount,
          ),
        ),
        const SizedBox(height: 20),
        SizedBox(
          width: double.infinity,
          height: 48,
          child: FilledButton(
            style: FilledButton.styleFrom(
              backgroundColor: AppColors.brand,
              foregroundColor: Colors.black,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(10),
              ),
            ),
            onPressed: state.orderSubmitting || state.flatNetworks.isEmpty
                ? null
                : _onCreateOrder,
            child: state.orderSubmitting
                ? const SizedBox(
                    height: 20,
                    width: 20,
                    child: CircularProgressIndicator(
                      strokeWidth: 2,
                      color: Colors.black,
                    ),
                  )
                : Text(
                    l10n.depositCreateOrder,
                    style: const TextStyle(fontWeight: FontWeight.w600),
                  ),
          ),
        ),
        const SizedBox(height: 20),
        _buildRulesCard(context, cs, l10n, isDark, net?.coinName ?? ''),
      ],
    );
  }

  Widget _buildRulesCard(
    BuildContext context,
    ColorScheme cs,
    AppLocalizations l10n,
    bool isDark,
    String currentCoin,
  ) {
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.all(14),
      decoration: _panelDecoration(cs, isDark),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            l10n.depositRules,
            style: TextStyle(
              color: cs.onSurface.withAlpha(153),
              fontSize: 13,
              fontWeight: FontWeight.w600,
            ),
          ),
          const SizedBox(height: 8),
          Text(
            l10n.depositRulesBody,
            style: TextStyle(
              color: cs.onSurface.withAlpha(140),
              fontSize: 12,
              height: 1.45,
            ),
          ),
          if (currentCoin.isNotEmpty) ...[
            const SizedBox(height: 10),
            Text(
              l10n.depositCurrentCoin(currentCoin),
              style: TextStyle(color: cs.onSurface.withAlpha(120), fontSize: 12),
            ),
          ],
        ],
      ),
    );
  }

  Widget _buildOrderDetail(
    BuildContext context,
    DepositState state,
    DepositNotifier notifier,
    ColorScheme cs,
    AppLocalizations l10n,
    bool isDark,
    RechargeOrderDetail order, {
    required bool wcConfigured,
  }) {
    final addr = order.rechargeAddress;
    final net = state.selectedNetwork;
    final canWc = _canWalletConnect(net, order);

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Container(
          width: double.infinity,
          padding: const EdgeInsets.all(14),
          decoration: _panelDecoration(cs, isDark),
          child: Column(
            children: [
              _orderMetaRow(
                context,
                l10n.depositOrderNo,
                order.orderNo,
                cs,
                copyable: true,
              ),
              _orderMetaRow(
                context,
                l10n.depositOrderStatus,
                _statusLabel(l10n, order.status),
                cs,
                valueColor: order.isPendingPayment ? AppColors.brand : null,
              ),
              _orderMetaRow(context, l10n.depositCurrency, order.coinName, cs),
              _orderMetaRow(context, l10n.depositNetwork, order.networkName, cs),
              _orderMetaRow(
                  context, l10n.depositOrderAmount, order.amount, cs),
            ],
          ),
        ),
        if (order.isPendingPayment) ...[
          const SizedBox(height: 16),
          _buildModeTabSwitcher(cs, l10n, isDark),
          const SizedBox(height: 16),
          AnimatedBuilder(
            animation: _depositModeTab,
            builder: (context, _) {
              if (_depositModeTab.index == _tabManual) {
                return _buildManualContent(
                  context,
                  state,
                  cs,
                  l10n,
                  isDark,
                  addr,
                  net,
                  order: order,
                );
              } else if (_depositModeTab.index == _tabOnChain) {
                return _buildOnChainContent(
                  context,
                  state,
                  cs,
                  l10n,
                  isDark,
                  addr,
                  net,
                  canWc,
                  wcConfigured: wcConfigured,
                  order: order,
                );
              } else {
                return const SizedBox.shrink();
              }
            },
          ),
        ] else ...[
          const SizedBox(height: 16),
          _buildManualContent(
            context,
            state,
            cs,
            l10n,
            isDark,
            addr,
            net,
            order: order,
            readOnly: true,
          ),
        ],
      ],
    );
  }

  Widget _orderMetaRow(
    BuildContext context,
    String label,
    String value,
    ColorScheme cs, {
    Color? valueColor,
    bool copyable = false,
  }) {
    final l10n = AppLocalizations.of(context)!;
    return Padding(
      padding: const EdgeInsets.only(bottom: 10),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(
            width: 72,
            child: Text(
              label,
              style: TextStyle(color: cs.onSurface.withAlpha(140), fontSize: 13),
            ),
          ),
          Expanded(
            child: Text(
              value,
              style: TextStyle(
                color: valueColor ?? cs.onSurface,
                fontSize: 13,
                fontWeight:
                    valueColor != null ? FontWeight.w600 : FontWeight.w400,
              ),
            ),
          ),
          if (copyable && value.isNotEmpty)
            TextButton(
              onPressed: () {
                Clipboard.setData(ClipboardData(text: value));
                showTopToast(context, message: l10n.copied);
              },
              style: TextButton.styleFrom(
                padding: const EdgeInsets.symmetric(horizontal: 8),
                minimumSize: Size.zero,
                tapTargetSize: MaterialTapTargetSize.shrinkWrap,
              ),
              child: Text(
                l10n.depositCopy,
                style: const TextStyle(
                  color: AppColors.brand,
                  fontSize: 12,
                  fontWeight: FontWeight.w600,
                ),
              ),
            ),
        ],
      ),
    );
  }

  Widget _buildAddressBlock(
    BuildContext context,
    ColorScheme cs,
    AppLocalizations l10n,
    bool isDark,
    String addr, {
    bool showQr = false,
  }) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          l10n.depositReceivingAddress,
          style: TextStyle(
            color: cs.onSurface.withAlpha(153),
            fontSize: 13,
            fontWeight: FontWeight.w600,
          ),
        ),
        const SizedBox(height: 6),
        Text(
          l10n.depositPayToHint,
          style: TextStyle(color: cs.onSurface.withAlpha(120), fontSize: 12),
        ),
        const SizedBox(height: 10),
        Container(
          width: double.infinity,
          padding: const EdgeInsets.all(12),
          decoration: _panelDecoration(cs, isDark),
          child: SelectableText(
            addr,
            style: TextStyle(color: cs.onSurface, fontSize: 13),
          ),
        ),
        if (showQr && addr.isNotEmpty) ...[
          const SizedBox(height: 16),
          Text(
            l10n.depositQrReceive,
            style: TextStyle(
              color: cs.onSurface.withAlpha(153),
              fontSize: 13,
              fontWeight: FontWeight.w600,
            ),
          ),
          const SizedBox(height: 10),
          Center(
            child: RepaintBoundary(
              key: _qrKey,
              child: Container(
                width: 200,
                height: 200,
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(12),
                ),
                child: QrImageView(
                  data: addr,
                  version: QrVersions.auto,
                  size: 180,
                  backgroundColor: Colors.white,
                ),
              ),
            ),
          ),
          const SizedBox(height: 8),
          Text(
            l10n.depositQrHint,
            textAlign: TextAlign.center,
            style: TextStyle(color: cs.onSurface.withAlpha(120), fontSize: 12),
          ),
          const SizedBox(height: 8),
          Center(
            child: TextButton.icon(
              onPressed:
                  addr.isNotEmpty && !_savingQr ? () => _saveQr(addr) : null,
              icon: _savingQr
                  ? const SizedBox(
                      width: 16,
                      height: 16,
                      child: CircularProgressIndicator(strokeWidth: 2),
                    )
                  : Icon(Icons.download_outlined,
                      size: 16, color: cs.onSurface.withAlpha(153)),
              label: Text(
                l10n.saveQrCode,
                style: TextStyle(
                    color: cs.onSurface.withAlpha(153), fontSize: 13),
              ),
            ),
          ),
        ],
      ],
    );
  }

  Widget _buildContractBlock(
    ColorScheme cs,
    AppLocalizations l10n,
    bool isDark,
    RechargeFlatNetworkOption? net,
  ) {
    if (net == null || !net.hasTokenContract) {
      return const SizedBox.shrink();
    }
    return Padding(
      padding: const EdgeInsets.only(top: 12),
      child: Container(
        width: double.infinity,
        padding: const EdgeInsets.all(12),
        decoration: _panelDecoration(cs, isDark),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              l10n.depositContractAddress,
              style: TextStyle(color: cs.onSurface.withAlpha(140), fontSize: 12),
            ),
            const SizedBox(height: 6),
            SelectableText(
              net.contractAddress,
              style: TextStyle(
                color: cs.onSurface,
                fontSize: 12,
                fontFamily: 'monospace',
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildTxHashSection(
    BuildContext context,
    DepositState state,
    ColorScheme cs,
    AppLocalizations l10n,
    bool isDark, {
    bool enabled = true,
  }) {
    if (!enabled) {
      return const SizedBox.shrink();
    }
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const SizedBox(height: 20),
        Text(
          l10n.depositSubmitHashHint,
          style: TextStyle(color: cs.onSurface.withAlpha(153), fontSize: 13),
        ),
        const SizedBox(height: 8),
        TextField(
          controller: _hashCtrl,
          decoration: InputDecoration(
            filled: true,
            fillColor: isDark
                ? AppColors.darkBgSecondary
                : AppColors.lightBgSecondary,
            hintText: l10n.depositTxHashPlaceholder,
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(10),
              borderSide: BorderSide(color: cs.outline.withAlpha(50)),
            ),
            enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(10),
              borderSide: BorderSide(color: cs.outline.withAlpha(50)),
            ),
          ),
        ),
        const SizedBox(height: 12),
        SizedBox(
          width: double.infinity,
          height: 48,
          child: FilledButton(
            style: FilledButton.styleFrom(
              backgroundColor: AppColors.brand,
              foregroundColor: Colors.black,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(10),
              ),
            ),
            onPressed: state.hashSubmitting || state.walletPayBusy
                ? null
                : _onSubmitHash,
            child: state.hashSubmitting
                ? const SizedBox(
                    height: 20,
                    width: 20,
                    child: CircularProgressIndicator(
                      strokeWidth: 2,
                      color: Colors.black,
                    ),
                  )
                : Text(
                    l10n.depositSubmitHash,
                    style: const TextStyle(fontWeight: FontWeight.w600),
                  ),
          ),
        ),
      ],
    );
  }

  Widget _buildOnChainContent(
    BuildContext context,
    DepositState state,
    ColorScheme cs,
    AppLocalizations l10n,
    bool isDark,
    String addr,
    RechargeFlatNetworkOption? net,
    bool canWc, {
    required bool wcConfigured,
    required RechargeOrderDetail order,
  }) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        if (addr.isNotEmpty) ...[
          _buildAddressBlock(context, cs, l10n, isDark, addr),
        ],
        if (order.isPendingPayment) ...[
          const SizedBox(height: 16),
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(14),
            decoration: _panelDecoration(cs, isDark),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                if (canWc && wcConfigured)
                  Text(
                    l10n.depositWalletConnectHint,
                    style: TextStyle(
                      color: cs.onSurface.withAlpha(153),
                      fontSize: 12,
                      height: 1.4,
                    ),
                  )
                else if (canWc && !wcConfigured)
                  Text(
                    l10n.depositWalletConnectNotConfigured,
                    style: TextStyle(
                      color: cs.onSurface.withAlpha(120),
                      fontSize: 12,
                      height: 1.4,
                    ),
                  )
                else if (_isTronLike(net))
                  Text(
                    l10n.depositTronHint,
                    style: TextStyle(
                      color: cs.onSurface.withAlpha(153),
                      fontSize: 12,
                      height: 1.4,
                    ),
                  ),
                if (canWc && wcConfigured) ...[
                  const SizedBox(height: 12),
                  SizedBox(
                    width: double.infinity,
                    height: 44,
                    child: OutlinedButton(
                      style: OutlinedButton.styleFrom(
                        foregroundColor: AppColors.brand,
                        side: const BorderSide(color: AppColors.brand),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                      onPressed: (state.hashSubmitting ||
                              state.walletPayBusy ||
                              net == null)
                          ? null
                          : () => _onWalletPay(net, order),
                      child: state.walletPayBusy
                          ? const SizedBox(
                              height: 20,
                              width: 20,
                              child: CircularProgressIndicator(
                                strokeWidth: 2,
                                color: AppColors.brand,
                              ),
                            )
                          : Text(_walletPayButtonLabel(l10n, net)),
                    ),
                  ),
                ],
              ],
            ),
          ),
          _buildTxHashSection(context, state, cs, l10n, isDark),
        ] else if (order.txHash != null && order.txHash!.isNotEmpty) ...[
          const SizedBox(height: 12),
          Text(
            '${l10n.depositTxHashPlaceholder}: ${order.txHash}',
            style: TextStyle(color: cs.onSurface.withAlpha(153), fontSize: 12),
          ),
        ],
      ],
    );
  }

  Widget _buildManualContent(
    BuildContext context,
    DepositState state,
    ColorScheme cs,
    AppLocalizations l10n,
    bool isDark,
    String addr,
    RechargeFlatNetworkOption? net, {
    required RechargeOrderDetail order,
    bool readOnly = false,
  }) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        if (addr.isNotEmpty) ...[
          _buildAddressBlock(
            context,
            cs,
            l10n,
            isDark,
            addr,
            showQr: true,
          ),
        ],
        _buildContractBlock(cs, l10n, isDark, net),
        if (order.isPendingPayment && !readOnly)
          _buildTxHashSection(context, state, cs, l10n, isDark)
        else if (order.txHash != null && order.txHash!.isNotEmpty) ...[
          const SizedBox(height: 12),
          Text(
            '${l10n.depositTxHashPlaceholder}: ${order.txHash}',
            style: TextStyle(color: cs.onSurface.withAlpha(153), fontSize: 12),
          ),
        ],
      ],
    );
  }

}
