import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shadcn_ui/shadcn_ui.dart';

import '../../../common/domain/metal_type.dart';
import '../../../common/domain/money.dart';
import '../../../common/router/app_router.dart';
import '../../../common/widgets/prototype_ui.dart';
import '../application/asset_portfolio_controller.dart';
import '../../profile/application/price_color_theme.dart';
import '../../profile/application/profile_settings_controller.dart';
import '../data/asset_models.dart';
import '../../market/application/market_controller.dart';

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

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final summary = ref.watch(assetPortfolioControllerProvider);
    final settings = ref.watch(profileSettingsControllerProvider);
    final palette = priceColorPalette(settings.priceColorMode);
    final cs = ShadTheme.of(context).colorScheme;
    final hidden = settings.amountHidden;

    return SafeArea(
      top: false,
      child: ListView(
        padding: const EdgeInsets.fromLTRB(0, 8, 0, 86),
        children: [
          PrototypeFrame(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Row(
                  children: [
                    const Row(
                      children: [
                        _Dot(),
                        SizedBox(width: 8),
                        Text(
                          '金值',
                          style: TextStyle(
                            fontSize: 17,
                            fontWeight: FontWeight.w600,
                          ),
                        ),
                      ],
                    ),
                    const Spacer(),
                    IconButton(
                      onPressed: () => _showAddAssetSheet(context),
                      icon: const Icon(Icons.add, size: 22),
                      color: const Color(0xFF9A968D),
                      padding: EdgeInsets.zero,
                      constraints: const BoxConstraints.tightFor(
                        width: 30,
                        height: 30,
                      ),
                    ),
                    IconButton(
                      onPressed: () => ref
                          .read(profileSettingsControllerProvider.notifier)
                          .toggleAmountHidden(),
                      icon: Icon(
                        hidden
                            ? Icons.visibility_off_outlined
                            : Icons.visibility_outlined,
                        size: 20,
                      ),
                      color: const Color(0xFF9A968D),
                      padding: EdgeInsets.zero,
                      constraints: const BoxConstraints.tightFor(
                        width: 30,
                        height: 30,
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 26),
                Text(
                  '我的贵金属总估值',
                  textAlign: TextAlign.center,
                  style: TextStyle(fontSize: 13, color: cs.mutedForeground),
                ),
                const SizedBox(height: 10),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Padding(
                      padding: EdgeInsets.only(top: 11),
                      child: Text(
                        '¥',
                        style: TextStyle(
                          fontSize: 28,
                          fontWeight: FontWeight.w600,
                        ),
                      ),
                    ),
                    const SizedBox(width: 3),
                    Text(
                      hidden
                          ? '••••••'
                          : formatCny(summary.totalValue).replaceFirst('¥', ''),
                      style: const TextStyle(
                        fontSize: 64,
                        fontWeight: FontWeight.w600,
                        height: 1,
                        letterSpacing: -2,
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 15),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    _ChangeChip(
                      amount: summary.todayChangeAmount,
                      percent: summary.todayChangePercent,
                      upColor: Color(palette.up),
                      downColor: Color(palette.down),
                      upBackground: Color(palette.upBackground),
                      downBackground: Color(palette.downBackground),
                    ),
                    const SizedBox(width: 10),
                    Text(
                      '今日',
                      style: TextStyle(fontSize: 12, color: cs.mutedForeground),
                    ),
                  ],
                ),
                const SizedBox(height: 14),
                SizedBox(
                  height: 32,
                  child: ListView.separated(
                    scrollDirection: Axis.horizontal,
                    physics: const BouncingScrollPhysics(),
                    itemCount: summary.breakdowns.length,
                    separatorBuilder: (context, index) =>
                        const SizedBox(width: 6),
                    itemBuilder: (context, index) {
                      final item = summary.breakdowns[index];
                      return PrototypePill(
                        label:
                            '${item.metal.shortLabel} ${hidden ? '•••' : formatCny(item.value)}',
                        leading: Container(
                          width: 6,
                          height: 6,
                          decoration: BoxDecoration(
                            color: item.metal.color,
                            shape: BoxShape.circle,
                          ),
                        ),
                      );
                    },
                  ),
                ),
                const SizedBox(height: 14),
                Text(
                  '更新于 16:11 · 行情聚合',
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    fontSize: 11,
                    color: cs.mutedForeground.withValues(alpha: 0.82),
                  ),
                ),
                const SizedBox(height: 12),
                GestureDetector(
                  onTap: () => context.push(
                    '${AppRoutes.marketKline}?metal=gold&period=24h',
                  ),
                  child: SizedBox(
                    height: 46,
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(10),
                      child: PrototypeLineChart(
                        values: const [
                          27,
                          31,
                          29,
                          35,
                          33,
                          37,
                          42,
                          40,
                          46,
                          44,
                          50,
                          53,
                        ],
                      ),
                    ),
                  ),
                ),
                const SizedBox(height: 14),
                GridView.count(
                  crossAxisCount: 2,
                  shrinkWrap: true,
                  physics: const NeverScrollableScrollPhysics(),
                  mainAxisSpacing: 10,
                  crossAxisSpacing: 10,
                  childAspectRatio: 1.6,
                  children: [
                    _StatCard(
                      title: '回收参考',
                      value: hidden
                          ? '¥••••'
                          : formatCny(summary.recycleReferenceValue),
                    ),
                    _StatCard(
                      title: '总盈亏(已填成本)',
                      value: hidden
                          ? '••••'
                          : _signedCny(summary.totalValue - summary.totalCost),
                      valueColor: summary.totalValue - summary.totalCost >= 0
                          ? Color(palette.up)
                          : Color(palette.down),
                    ),
                    _StatCard(
                      title: '总成本',
                      value: hidden ? '¥••••' : formatCny(summary.totalCost),
                    ),
                    _StatCard(
                      title: '总克重',
                      value: '${summary.totalWeightGram.toStringAsFixed(1)} g',
                    ),
                  ],
                ),
                const SizedBox(height: 12),
                PrototypeCard(
                  padding: EdgeInsets.zero,
                  child: Column(
                    children: [
                      Padding(
                        padding: const EdgeInsets.fromLTRB(16, 15, 16, 8),
                        child: Row(
                          children: [
                            const Text(
                              '我的持仓',
                              style: TextStyle(
                                fontSize: 14,
                                fontWeight: FontWeight.w600,
                              ),
                            ),
                            const Spacer(),
                            Text(
                              '${summary.holdings.length} 件 · ${summary.totalWeightGram.toStringAsFixed(1)}g',
                              style: TextStyle(
                                fontSize: 12,
                                color: cs.mutedForeground,
                              ),
                            ),
                          ],
                        ),
                      ),
                      const PrototypeDivider(margin: EdgeInsets.zero),
                      for (final item in summary.holdings) ...[
                        _HoldingRow(
                          valuation: item,
                          hidden: hidden,
                          upColor: Color(palette.up),
                          downColor: Color(palette.down),
                          onTap: () => context.push(
                            '${AppRoutes.assetDetail}?id=${item.holding.id}',
                          ),
                        ),
                        if (item != summary.holdings.last)
                          const PrototypeDivider(margin: EdgeInsets.zero),
                      ],
                      const PrototypeDivider(margin: EdgeInsets.zero),
                      Padding(
                        padding: const EdgeInsets.fromLTRB(16, 14, 16, 16),
                        child: SizedBox(
                          width: double.infinity,
                          child: OutlinedButton.icon(
                            onPressed: () => _showAddAssetSheet(context),
                            icon: const Icon(Icons.add, size: 18),
                            label: const Text('添加资产'),
                            style: OutlinedButton.styleFrom(
                              foregroundColor: const Color(0xFF9A7A2A),
                              side: const BorderSide(color: Color(0xFFE3D6B4)),
                              padding: const EdgeInsets.symmetric(vertical: 12),
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(12),
                              ),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  void _showAddAssetSheet(BuildContext context) {
    context.push(AppRoutes.assetAdd);
  }

  String _signedCny(double value) {
    final sign = value >= 0 ? '+' : '-';
    return '$sign${formatCny(value.abs())}';
  }
}

class _HoldingRow extends StatelessWidget {
  const _HoldingRow({
    required this.valuation,
    required this.hidden,
    required this.upColor,
    required this.downColor,
    required this.onTap,
  });

  final HoldingValuation valuation;
  final bool hidden;
  final Color upColor;
  final Color downColor;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    final holding = valuation.holding;
    final metal = holding.metal;
    final change = valuation.todayChange;
    final changeUp = change >= 0;
    return InkWell(
      onTap: onTap,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 13),
        child: Row(
          children: [
            Container(
              width: 34,
              height: 34,
              decoration: BoxDecoration(
                color: metal.color.withValues(alpha: 0.15),
                borderRadius: BorderRadius.circular(10),
              ),
              child: Icon(
                _iconFor(holding.category),
                size: 18,
                color: metal.color,
              ),
            ),
            const SizedBox(width: 12),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    holding.name,
                    style: const TextStyle(
                      fontSize: 14,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                  const SizedBox(height: 4),
                  Text(
                    '${holding.purityLabel} · ${holding.weightGram.toStringAsFixed(1)}g'
                    '${holding.note == null ? '' : ' · ${holding.note}'}',
                    style: const TextStyle(
                      fontSize: 12,
                      color: Color(0xFF8A8780),
                    ),
                  ),
                ],
              ),
            ),
            const SizedBox(width: 10),
            Column(
              crossAxisAlignment: CrossAxisAlignment.end,
              children: [
                Text(
                  hidden ? '¥••••' : formatCny(valuation.materialValue),
                  style: const TextStyle(
                    fontSize: 15,
                    fontWeight: FontWeight.w600,
                  ),
                ),
                const SizedBox(height: 4),
                Text(
                  '${changeUp ? '↑' : '↓'}${hidden ? '¥••••' : formatCny(change.abs())}',
                  style: TextStyle(
                    fontSize: 12,
                    color: changeUp ? upColor : downColor,
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  IconData _iconFor(AssetCategory category) {
    return switch (category) {
      AssetCategory.bar || AssetCategory.bean => Icons.auto_awesome,
      AssetCategory.ring => Icons.radio_button_unchecked,
      AssetCategory.necklace => Icons.circle_outlined,
      AssetCategory.bracelet => Icons.watch_outlined,
      AssetCategory.earring => Icons.circle,
      AssetCategory.silverware => Icons.circle,
      AssetCategory.platinumPiece => Icons.circle,
    };
  }
}

class _StatCard extends StatelessWidget {
  const _StatCard({required this.title, required this.value, this.valueColor});

  final String title;
  final String value;
  final Color? valueColor;

  @override
  Widget build(BuildContext context) {
    final cs = ShadTheme.of(context).colorScheme;
    return PrototypeCard(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(
            title,
            style: TextStyle(fontSize: 12, color: cs.mutedForeground),
          ),
          Text(
            value,
            style: TextStyle(
              fontSize: 18,
              fontWeight: FontWeight.w600,
              color: valueColor ?? cs.foreground,
            ),
          ),
        ],
      ),
    );
  }
}

class _ChangeChip extends StatelessWidget {
  const _ChangeChip({
    required this.amount,
    required this.percent,
    required this.upColor,
    required this.downColor,
    required this.upBackground,
    required this.downBackground,
  });

  final double amount;
  final double percent;
  final Color upColor;
  final Color downColor;
  final Color upBackground;
  final Color downBackground;

  @override
  Widget build(BuildContext context) {
    final positive = amount >= 0;
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 11, vertical: 5),
      decoration: BoxDecoration(
        color: positive ? upBackground : downBackground,
        borderRadius: BorderRadius.circular(999),
      ),
      child: Text(
        '${positive ? '↑' : '↓'}${formatCny(amount.abs())} · ${positive ? '+' : '-'}${percent.abs().toStringAsFixed(2)}%',
        style: TextStyle(
          fontSize: 13,
          fontWeight: FontWeight.w600,
          color: positive ? upColor : downColor,
        ),
      ),
    );
  }
}

class _Dot extends StatelessWidget {
  const _Dot();

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 8,
      height: 8,
      decoration: const BoxDecoration(
        color: Color(0xFFB5862A),
        shape: BoxShape.circle,
      ),
    );
  }
}

class _AddAssetSheet extends ConsumerStatefulWidget {
  const _AddAssetSheet();

  @override
  ConsumerState<_AddAssetSheet> createState() => _AddAssetSheetState();
}

class _AddAssetSheetState extends ConsumerState<_AddAssetSheet> {
  static const _cats = [
    AssetCategory.bar,
    AssetCategory.necklace,
    AssetCategory.ring,
    AssetCategory.bracelet,
    AssetCategory.bean,
    AssetCategory.earring,
    AssetCategory.silverware,
    AssetCategory.platinumPiece,
  ];

  static const _metalPurities = {
    MetalType.gold: ['足金9999', '足金999', '22K', '18K'],
    MetalType.platinum: ['PT990', 'PT950'],
    MetalType.silver: ['999银', '925银'],
  };

  AssetCategory _cat = AssetCategory.bar;
  MetalType _metal = MetalType.gold;
  int _purityIndex = 0;
  double _gram = 50;
  bool _expanded = false;
  final _costCtrl = TextEditingController();
  final _noteCtrl = TextEditingController();
  final _dateCtrl = TextEditingController(text: '2025-08-12');
  final _channelCtrl = TextEditingController(text: '银行');

  @override
  void dispose() {
    _costCtrl.dispose();
    _noteCtrl.dispose();
    _dateCtrl.dispose();
    _channelCtrl.dispose();
    super.dispose();
  }

  List<String> get _purityOptions => _metalPurities[_metal]!;

  String get _purity =>
      _purityOptions[_purityIndex.clamp(0, _purityOptions.length - 1)];

  void _cyclePurity() {
    setState(() {
      _purityIndex = (_purityIndex + 1) % _purityOptions.length;
    });
  }

  double _factorFor(String purity) {
    return switch (purity) {
      '足金9999' => 0.9999,
      '足金999' => 0.999,
      '22K' => 0.916,
      '18K' => 0.75,
      'PT990' => 0.99,
      'PT950' => 0.95,
      '999银' => 0.999,
      '925银' => 0.925,
      _ => 1,
    };
  }

  String _nameForSelection() {
    return switch (_cat) {
      AssetCategory.bar => '投资金条',
      AssetCategory.necklace => '${_metal.label}项链',
      AssetCategory.ring => '${_metal.label}戒指',
      AssetCategory.bracelet => '${_metal.label}手镯',
      AssetCategory.bean => '金豆',
      AssetCategory.earring => '${_metal.label}耳环',
      AssetCategory.silverware => '银饰',
      AssetCategory.platinumPiece => 'PT饰品',
    };
  }

  @override
  Widget build(BuildContext context) {
    final cs = ShadTheme.of(context).colorScheme;
    final market = ref.watch(marketControllerProvider);
    final quote = market.quotes.firstWhere((item) => item.metal == _metal);
    final basePrice = quote.spotPrice;
    final value = _gram * _factorFor(_purity) * basePrice;

    return SafeArea(
      child: Padding(
        padding: EdgeInsets.only(
          bottom: MediaQuery.viewInsetsOf(context).bottom,
        ),
        child: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.fromLTRB(20, 8, 20, 24),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: [
                Center(
                  child: Container(
                    width: 38,
                    height: 4,
                    margin: const EdgeInsets.only(bottom: 14),
                    decoration: BoxDecoration(
                      color: const Color(0xFFE3DFD4),
                      borderRadius: BorderRadius.circular(999),
                    ),
                  ),
                ),
                Row(
                  children: [
                    const Spacer(),
                    const Text(
                      '添加资产',
                      style: TextStyle(
                        fontSize: 16,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                    const Spacer(),
                    GestureDetector(
                      onTap: () => Navigator.of(context).pop(),
                      child: const Icon(
                        Icons.close,
                        size: 20,
                        color: Color(0xFF8A8780),
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 16),
                const Text(
                  '选择品类',
                  style: TextStyle(fontSize: 13, color: Color(0xFF8A8780)),
                ),
                const SizedBox(height: 10),
                Wrap(
                  spacing: 9,
                  runSpacing: 9,
                  children: [
                    for (final cat in _cats)
                      _Chip(
                        label: cat.label,
                        selected: cat == _cat,
                        onTap: () => setState(() {
                          _cat = cat;
                          if (cat == AssetCategory.silverware) {
                            _metal = MetalType.silver;
                          } else if (cat == AssetCategory.platinumPiece) {
                            _metal = MetalType.platinum;
                          } else {
                            _metal = MetalType.gold;
                          }
                          _purityIndex = 0;
                        }),
                      ),
                  ],
                ),
                const SizedBox(height: 16),
                Container(
                  padding: const EdgeInsets.fromLTRB(16, 13, 16, 13),
                  decoration: BoxDecoration(
                    color: Colors.white,
                    border: Border.all(
                      color: const Color(0xFFE3D6B4),
                      width: 0.5,
                    ),
                    borderRadius: BorderRadius.circular(13),
                  ),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      const Text(
                        '金属 / 纯度',
                        style: TextStyle(
                          fontSize: 13,
                          color: Color(0xFF8A8780),
                        ),
                      ),
                      GestureDetector(
                        onTap: _cyclePurity,
                        child: Row(
                          children: [
                            Text(
                              '${_metal.label} · $_purity',
                              style: const TextStyle(
                                fontSize: 14,
                                fontWeight: FontWeight.w600,
                              ),
                            ),
                            const SizedBox(width: 7),
                            const Icon(
                              Icons.unfold_more,
                              size: 16,
                              color: Color(0xFFB3AFA5),
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
                const SizedBox(height: 16),
                const Text(
                  '克重(克)',
                  style: TextStyle(fontSize: 13, color: Color(0xFF8A8780)),
                ),
                const SizedBox(height: 9),
                Row(
                  children: [
                    _StepButton(
                      icon: Icons.remove,
                      onTap: () =>
                          setState(() => _gram = (_gram - 1).clamp(1, 200)),
                    ),
                    const SizedBox(width: 12),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.symmetric(
                          horizontal: 16,
                          vertical: 12,
                        ),
                        decoration: BoxDecoration(
                          color: Colors.white,
                          border: Border.all(
                            color: const Color(0xFFE3D6B4),
                            width: 0.5,
                          ),
                          borderRadius: BorderRadius.circular(13),
                        ),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.end,
                          children: [
                            Text(
                              _gram.toStringAsFixed(_gram % 1 == 0 ? 0 : 1),
                              style: const TextStyle(
                                fontSize: 32,
                                fontWeight: FontWeight.w600,
                                height: 1,
                              ),
                            ),
                            const SizedBox(width: 6),
                            const Padding(
                              padding: EdgeInsets.only(bottom: 2),
                              child: Text(
                                '克',
                                style: TextStyle(
                                  fontSize: 15,
                                  color: Color(0xFF8A8780),
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                    const SizedBox(width: 12),
                    _StepButton(
                      icon: Icons.add,
                      onTap: () =>
                          setState(() => _gram = (_gram + 1).clamp(1, 200)),
                    ),
                  ],
                ),
                Slider(
                  min: 1,
                  max: 200,
                  value: _gram.clamp(1, 200),
                  onChanged: (value) => setState(() => _gram = value),
                  activeColor: const Color(0xFFB5862A),
                  inactiveColor: const Color(0xFFECEAE3),
                ),
                const SizedBox(height: 8),
                Container(
                  padding: const EdgeInsets.fromLTRB(16, 15, 16, 16),
                  decoration: BoxDecoration(
                    color: const Color(0xFFF6ECD6),
                    borderRadius: BorderRadius.circular(14),
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          const Text(
                            '实时材料价值',
                            style: TextStyle(
                              fontSize: 13,
                              color: Color(0xFF7A5B12),
                            ),
                          ),
                          Text(
                            formatCny(value),
                            style: const TextStyle(
                              fontSize: 24,
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                        ],
                      ),
                      const SizedBox(height: 7),
                      Text(
                        '按${_metal.label}现货 ${basePrice.toStringAsFixed(2)}/克 · 非金店零售价、非回收实收价',
                        style: const TextStyle(
                          fontSize: 11,
                          color: Color(0xFF9A7A2A),
                        ),
                      ),
                    ],
                  ),
                ),
                const SizedBox(height: 14),
                GestureDetector(
                  onTap: () => setState(() => _expanded = !_expanded),
                  child: Container(
                    padding: const EdgeInsets.fromLTRB(16, 13, 16, 13),
                    decoration: BoxDecoration(
                      color: cs.card,
                      borderRadius: BorderRadius.circular(14),
                      border: Border.all(color: cs.border, width: 0.5),
                    ),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Text(
                          '选填:买入成本 · 日期 · 渠道 · 备注 · 照片',
                          style: TextStyle(
                            fontSize: 13,
                            color: cs.mutedForeground,
                          ),
                        ),
                        Icon(
                          _expanded ? Icons.expand_less : Icons.expand_more,
                          color: cs.mutedForeground,
                          size: 18,
                        ),
                      ],
                    ),
                  ),
                ),
                if (_expanded) ...[
                  const SizedBox(height: 12),
                  _FieldRow(
                    label: '买入成本(含工费)',
                    child: TextField(
                      controller: _costCtrl,
                      keyboardType: const TextInputType.numberWithOptions(
                        decimal: true,
                      ),
                      decoration: const InputDecoration(
                        border: InputBorder.none,
                        isDense: true,
                        hintText: '选填',
                      ),
                      textAlign: TextAlign.right,
                    ),
                  ),
                  const SizedBox(height: 10),
                  _FieldRow(
                    label: '购买日期',
                    child: TextField(
                      controller: _dateCtrl,
                      decoration: const InputDecoration(
                        border: InputBorder.none,
                        isDense: true,
                      ),
                      textAlign: TextAlign.right,
                    ),
                  ),
                  const SizedBox(height: 10),
                  _FieldRow(
                    label: '购买渠道',
                    child: Wrap(
                      spacing: 7,
                      runSpacing: 7,
                      alignment: WrapAlignment.end,
                      children: [
                        for (final channel in ['银行', '金店', '电商', '回收市场', '其他'])
                          _Chip(
                            label: channel,
                            selected: _channelCtrl.text == channel,
                            onTap: () =>
                                setState(() => _channelCtrl.text = channel),
                          ),
                      ],
                    ),
                  ),
                  const SizedBox(height: 10),
                  _FieldRow(
                    label: '备注',
                    child: TextField(
                      controller: _noteCtrl,
                      decoration: const InputDecoration(
                        border: InputBorder.none,
                        isDense: true,
                        hintText: '点击填写',
                      ),
                      textAlign: TextAlign.right,
                    ),
                  ),
                  const SizedBox(height: 10),
                  Container(
                    padding: const EdgeInsets.fromLTRB(14, 14, 14, 14),
                    decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(12),
                      border: Border.all(
                        color: const Color(0xFFECEAE3),
                        width: 0.5,
                      ),
                    ),
                    child: Row(
                      children: [
                        Container(
                          width: 60,
                          height: 60,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(11),
                            border: Border.all(
                              color: const Color(0xFFD3CDBE),
                              width: 0.5,
                            ),
                          ),
                          child: const Icon(
                            Icons.camera_alt_outlined,
                            color: Color(0xFFB3AFA5),
                          ),
                        ),
                        const SizedBox(width: 10),
                        const Expanded(
                          child: Text(
                            '添加发票 / 实物照片（选填，仅存本机）',
                            style: TextStyle(
                              fontSize: 12,
                              color: Color(0xFFB3AFA5),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
                const SizedBox(height: 16),
                Row(
                  children: [
                    Expanded(
                      child: OutlinedButton(
                        onPressed: () => Navigator.of(context).pop(),
                        style: OutlinedButton.styleFrom(
                          side: const BorderSide(color: Color(0xFFE3D6B4)),
                          padding: const EdgeInsets.symmetric(vertical: 12),
                        ),
                        child: const Text('取消'),
                      ),
                    ),
                    const SizedBox(width: 10),
                    Expanded(
                      child: FilledButton(
                        onPressed: () {
                          final holding = GoldAssetHolding(
                            id: 'h${DateTime.now().microsecondsSinceEpoch}',
                            name: _nameForSelection(),
                            metal: _metal,
                            category: _cat,
                            purity: _factorFor(_purity),
                            purityLabel: _purity,
                            weightGram: _gram,
                            costAmount: double.tryParse(_costCtrl.text.trim()),
                            purchaseDate: DateTime.tryParse(
                              _dateCtrl.text.trim(),
                            ),
                            channel: _channelCtrl.text.trim().isEmpty
                                ? null
                                : _channelCtrl.text.trim(),
                            note: _noteCtrl.text.trim().isEmpty
                                ? null
                                : _noteCtrl.text.trim(),
                            createdAt: DateTime.now(),
                            updatedAt: DateTime.now(),
                          );
                          ref
                              .read(assetPortfolioControllerProvider.notifier)
                              .addHolding(holding);
                          Navigator.of(context).pop();
                          ScaffoldMessenger.of(context).showSnackBar(
                            const SnackBar(content: Text('已添加 · 总估值已重算')),
                          );
                        },
                        child: const Text('保存'),
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class _Chip extends StatelessWidget {
  const _Chip({
    required this.label,
    required this.selected,
    required this.onTap,
  });

  final String label;
  final bool selected;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 11, vertical: 6),
        decoration: BoxDecoration(
          color: selected ? const Color(0xFFF6ECD6) : Colors.white,
          borderRadius: BorderRadius.circular(999),
          border: Border.all(
            color: selected ? const Color(0xFFE3D6B4) : const Color(0xFFECEAE3),
            width: 0.5,
          ),
        ),
        child: Text(
          label,
          style: TextStyle(
            fontSize: 12,
            fontWeight: selected ? FontWeight.w600 : FontWeight.w500,
            color: selected ? const Color(0xFF7A5B12) : const Color(0xFF5F5E5A),
          ),
        ),
      ),
    );
  }
}

class _StepButton extends StatelessWidget {
  const _StepButton({required this.icon, required this.onTap});

  final IconData icon;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        width: 34,
        height: 34,
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(10),
          border: Border.all(color: const Color(0xFFE3D6B4), width: 0.5),
        ),
        child: Icon(icon, size: 18, color: const Color(0xFFB5862A)),
      ),
    );
  }
}

class _FieldRow extends StatelessWidget {
  const _FieldRow({required this.label, required this.child});

  final String label;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.fromLTRB(14, 12, 14, 12),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: const Color(0xFFECEAE3), width: 0.5),
      ),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Text(
            label,
            style: const TextStyle(fontSize: 13, color: Color(0xFF8A8780)),
          ),
          const SizedBox(width: 10),
          Expanded(child: child),
        ],
      ),
    );
  }
}
