import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import '../../core/i18n/app_localizations.dart';
import '../../shared/widgets/action_bar.dart';
import '../../shared/widgets/form_section.dart';
import '../../shared/widgets/form_field_row.dart';
import '../shell/nav_bar_config.dart';
import '../../core/theme/app_colors.dart';
import '../../core/theme/app_colors_extension.dart';

class ExpenseApplicationApplyPage extends ConsumerStatefulWidget {
  final String? id;
  const ExpenseApplicationApplyPage({super.key, this.id});

  @override
  ConsumerState<ExpenseApplicationApplyPage> createState() =>
      _ExpenseApplicationApplyPageState();
}

class _ExpenseApplicationApplyPageState
    extends ConsumerState<ExpenseApplicationApplyPage> {
  // ── 基本信息 ──
  int _urgency = 0; // 0=普通, 1=紧急, 2=特急
  static const _urgencyLabels = ['普通', '紧急', '特急'];
  final Set<String> _expenseTypes = {};
  static const _expenseTypeOptions = [
    ('travel', '差旅费'),
    ('entertainment', '业务招待费'),
    ('procurement', '日常采购'),
    ('activity', '活动经费'),
    ('office', '办公费'),
    ('meeting', '会议费'),
    ('training', '培训费'),
  ];

  bool _isTaxIncluded = false;
  final _purposeController = TextEditingController();

  // ── 关联管控 ──
  String? _selectedProjectName;
  int? _selectedProjectId;
  String? _selectedSubjectName;
  int? _selectedSubjectId;
  final _availableBudget = 50000.00;
  final _referenceNoController = TextEditingController();

  // ── 费用明细 ──
  final List<_DetailItem> _details = [];
  int _detailIdCounter = 1;

  // ── 附件 ──
  final List<String> _attachments = []; // mock file names

  // ── 专用字段 ──
  String _estimatedStartDate = '';
  String _estimatedEndDate = '';
  String _entertainmentTarget = '';
  String _venue = '';

  @override
  void dispose() {
    _purposeController.dispose();
    _referenceNoController.dispose();
    super.dispose();
  }

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

    ref
        .read(navBarConfigProvider.notifier)
        .update(
          NavBarConfig(
            title: l10n.get('expenseApplyRequest'),
            showBack: true,
            onBack: () {
              if (_hasUnsaved()) {
                _showConfirmDialog(
                  '确认退出',
                  '当前内容尚未保存，是否退出？',
                  '继续编辑',
                  '放弃并退出',
                  () => context.pop(),
                );
              } else {
                context.pop();
              }
            },
          ),
        );

    return PopScope(
      canPop: false,
      onPopInvokedWithResult: (didPop, _) {
        if (!didPop) {
          if (_hasUnsaved()) {
            _showConfirmDialog(
              '确认退出',
              '当前内容尚未保存，是否退出？',
              '继续编辑',
              '放弃并退出',
              () => context.pop(),
            );
          } else {
            context.pop();
          }
        }
      },
      child: Column(
        children: [
          Expanded(
            child: SingleChildScrollView(
              padding: const EdgeInsets.all(16),
              child: Column(
                children: [
                  _buildBasicInfo(l10n),
                  const SizedBox(height: 16),
                  _buildTypeSpecificFields(l10n),
                  const SizedBox(height: 16),
                  _buildControlSection(l10n),
                  const SizedBox(height: 16),
                  _buildDetailsSection(l10n),
                  const SizedBox(height: 16),
                  _buildAttachmentSection(l10n),
                  const SizedBox(height: 80),
                ],
              ),
            ),
          ),
          _buildBottomBar(l10n),
        ],
      ),
    );
  }

  // ═══ 1. 基本信息 ═══
  Widget _buildBasicInfo(AppLocalizations l10n) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    return FormSection(
      title: l10n.get('basicInfo'),
      children: [
        FormFieldRow(
          label: l10n.get('applicant'),
          value: '张三',
          readOnly: true,
          showArrow: false,
        ),
        FormFieldRow(
          label: l10n.get('department'),
          value: '技术部',
          readOnly: true,
          showArrow: false,
        ),
        FormFieldRow(
          label: l10n.get('date'),
          value: _today(),
          readOnly: true,
          showArrow: false,
        ),
        const SizedBox(height: 12),
        _label(l10n.get('emergencyLevel')),
        const SizedBox(height: 6),
        _buildUrgencyRadio(),
        const SizedBox(height: 12),
        _label(l10n.get('expenseType')),
        const SizedBox(height: 6),
        Wrap(
          spacing: 8,
          runSpacing: 8,
          children: _expenseTypeOptions.map((opt) {
            final sel = _expenseTypes.contains(opt.$1);
            return GestureDetector(
              onTap: () => setState(
                () => sel
                    ? _expenseTypes.remove(opt.$1)
                    : _expenseTypes.add(opt.$1),
              ),
              child: TDTag(
                opt.$2,
                size: TDTagSize.medium,
                theme: sel ? TDTagTheme.primary : TDTagTheme.defaultTheme,
                isOutline: !sel,
              ),
            );
          }).toList(),
        ),
        const SizedBox(height: 12),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            _label(l10n.get('isTaxIncluded')),
            TDSwitch(
              isOn: _isTaxIncluded,
              onChanged: (v) {
                setState(() => _isTaxIncluded = v);
                return true;
              },
            ),
          ],
        ),
        const SizedBox(height: 12),
        _label(l10n.get('feeReason')),
        const SizedBox(height: 4),
        TDTextarea(
          controller: _purposeController,
          hintText: l10n.get('enterFeeReason'),
          maxLength: 200,
          backgroundColor: colors.bgPage,
        ),
        const SizedBox(height: 12),
        FormFieldRow(
          label: l10n.get('validUntil'),
          hint: l10n.get('pleaseSelect'),
          onTap: () => _pickDate((d) {}),
        ),
      ],
    );
  }

  Widget _buildUrgencyRadio() {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    return Row(
      children: List.generate(3, (i) {
        final sel = _urgency == i;
        return Padding(
          padding: EdgeInsets.only(right: i < 2 ? 24 : 0),
          child: GestureDetector(
            onTap: () => setState(() => _urgency = i),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Container(
                  width: 18,
                  height: 18,
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    border: Border.all(
                      color: sel ? colors.primary : colors.textPlaceholder,
                      width: 2,
                    ),
                  ),
                  child: sel
                      ? Center(
                          child: Container(
                            width: 8,
                            height: 8,
                            decoration: BoxDecoration(
                              shape: BoxShape.circle,
                              color: colors.primary,
                            ),
                          ),
                        )
                      : null,
                ),
                const SizedBox(width: 6),
                Text(
                  _urgencyLabels[i],
                  style: TextStyle(
                    fontSize: AppFontSizes.body,
                    color: sel ? colors.primary : colors.textSecondary,
                  ),
                ),
              ],
            ),
          ),
        );
      }),
    );
  }

  // ═══ 2. 类型专用字段 ═══
  Widget _buildTypeSpecificFields(AppLocalizations l10n) {
    final ws = <Widget>[];
    if (_expenseTypes.contains('travel')) ws.add(_buildTravelFields(l10n));
    if (_expenseTypes.contains('entertainment')) {
      ws.add(const SizedBox(height: 16));
      ws.add(_buildEntertainmentFields(l10n));
    }
    if (_expenseTypes.contains('meeting')) {
      ws.add(const SizedBox(height: 16));
      ws.add(_buildMeetingFields(l10n));
    }
    return ws.isEmpty ? const SizedBox.shrink() : Column(children: ws);
  }

  Widget _buildTravelFields(AppLocalizations l10n) {
    return FormSection(
      title: '差旅费专用',
      children: [
        FormFieldRow(
          label: l10n.get('estimatedStartDate'),
          value: _estimatedStartDate,
          hint: l10n.get('pleaseSelect'),
          onTap: () =>
              _pickDate((d) => setState(() => _estimatedStartDate = d)),
        ),
        FormFieldRow(
          label: l10n.get('estimatedEndDate'),
          value: _estimatedEndDate,
          hint: l10n.get('pleaseSelect'),
          onTap: () => _pickDate((d) => setState(() => _estimatedEndDate = d)),
        ),
        const SizedBox(height: 8),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            _label(l10n.get('isOvernight')),
            TDSwitch(onChanged: (_) => true),
          ],
        ),
        const SizedBox(height: 8),
        FormFieldRow(
          label: l10n.get('transportType'),
          value: '高铁/动车',
          onTap: () => _showListPicker('选择交通工具', [
            '飞机',
            '高铁/动车',
            '火车（普速）',
            '自驾',
          ], (_) {}),
        ),
      ],
    );
  }

  Widget _buildEntertainmentFields(AppLocalizations l10n) {
    return FormSection(
      title: '招待费专用',
      children: [
        FormFieldRow(
          label: '招待对象单位',
          value: _entertainmentTarget,
          hint: '请输入',
          onTap: () => _showTextInput(
            '招待对象单位',
            (v) => setState(() => _entertainmentTarget = v),
          ),
        ),
        FormFieldRow(
          label: '招待层级',
          value: '普通',
          onTap: () => _showListPicker('选择招待层级', ['普通', '重要', 'VIP'], (_) {}),
        ),
        FormFieldRow(
          label: '外部人数',
          value: '3',
          onTap: () => _showNumberInput('外部人数', (_) {}),
        ),
        FormFieldRow(
          label: '内部陪同人数',
          value: '2',
          onTap: () => _showNumberInput('内部陪同人数', (_) {}),
        ),
        FormFieldRow(
          label: l10n.get('venue'),
          value: _venue,
          hint: '请输入地点',
          onTap: () => _showTextInput(
            l10n.get('venue'),
            (v) => setState(() => _venue = v),
          ),
        ),
      ],
    );
  }

  Widget _buildMeetingFields(AppLocalizations l10n) {
    return FormSection(
      title: '会议费专用',
      children: [
        FormFieldRow(
          label: l10n.get('estimatedStartDate'),
          hint: l10n.get('pleaseSelect'),
          onTap: () => _pickDate((_) {}),
        ),
        FormFieldRow(
          label: l10n.get('estimatedEndDate'),
          hint: l10n.get('pleaseSelect'),
          onTap: () => _pickDate((_) {}),
        ),
        FormFieldRow(
          label: l10n.get('venue'),
          value: _venue,
          hint: '请输入会议地点',
          onTap: () => _showTextInput('会议地点', (_) {}),
        ),
      ],
    );
  }

  // ═══ 3. 关联管控 ═══
  static const _mockProjects = [
    ('华东市场拓展', 100),
    ('ERP系统升级', 101),
    ('新产品研发', 102),
    ('华南渠道建设', 103),
  ];
  static const _mockSubjects = [('差旅费', 5), ('招待费', 6), ('办公费', 7), ('培训费', 8)];

  Widget _buildControlSection(AppLocalizations l10n) {
    return FormSection(
      title: l10n.get('relatedControl'),
      children: [
        FormFieldRow(
          label: l10n.get('relatedProject'),
          value: _selectedProjectName,
          hint: l10n.get('selectProject'),
          onTap: () {
            _showListPicker('选择关联项目', _mockProjects.map((p) => p.$1).toList(), (
              v,
            ) {
              final p = _mockProjects.firstWhere((x) => x.$1 == v);
              setState(() {
                _selectedProjectId = p.$2;
                _selectedProjectName = p.$1;
                _selectedSubjectName = null;
                _selectedSubjectId = null;
              });
            });
          },
        ),
        FormFieldRow(
          label: l10n.get('budgetSubject'),
          value: _selectedSubjectName,
          hint: l10n.get('selectSubject'),
          onTap: _selectedProjectId != null
              ? () {
                  _showListPicker(
                    '选择预算科目',
                    _mockSubjects.map((s) => s.$1).toList(),
                    (v) {
                      final s = _mockSubjects.firstWhere((x) => x.$1 == v);
                      setState(() {
                        _selectedSubjectId = s.$2;
                        _selectedSubjectName = s.$1;
                      });
                    },
                  );
                }
              : null,
        ),
        _buildBudgetRow(l10n),
        const SizedBox(height: 8),
        FormFieldRow(
          label: '关联合同号',
          value: _referenceNoController.text,
          hint: '选填',
          onTap: () => _showTextInput(
            '关联合同号',
            (v) => setState(() {
              _referenceNoController.text = v;
              _referenceNoController.selection = TextSelection.fromPosition(
                TextPosition(offset: v.length),
              );
            }),
          ),
        ),
      ],
    );
  }

  Widget _buildBudgetRow(AppLocalizations l10n) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final over = _totalAmount() > _availableBudget;
    return SizedBox(
      height: 44,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(
            l10n.get('availableBudget'),
            style: TextStyle(
              fontSize: AppFontSizes.body,
              color: colors.textSecondary,
            ),
          ),
          Text(
            '¥${_availableBudget.toStringAsFixed(2)}',
            style: TextStyle(
              fontSize: AppFontSizes.subtitle,
              fontWeight: FontWeight.w700,
              color: over ? colors.danger : colors.amountPrimary,
            ),
          ),
        ],
      ),
    );
  }

  // ═══ 4. 费用明细 ═══
  Widget _buildDetailsSection(AppLocalizations l10n) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    return FormSection(
      title: l10n.get('expenseDetails'),
      showAction: true,
      actionText: l10n.get('add'),
      onActionTap: _showDetailDialog,
      children: [
        if (_details.isEmpty)
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 8),
            child: Text(
              l10n.get('noDetailHint'),
              style: TextStyle(
                fontSize: AppFontSizes.body,
                color: colors.textPlaceholder,
              ),
            ),
          )
        else
          ..._details.asMap().entries.map((e) {
            final d = e.value;
            return Container(
              padding: const EdgeInsets.symmetric(vertical: 6),
              decoration: BoxDecoration(
                border: e.key < _details.length - 1
                    ? Border(bottom: BorderSide(color: colors.border))
                    : null,
              ),
              child: Row(
                children: [
                  Expanded(
                    flex: 3,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          d.categoryName,
                          style: TextStyle(
                            fontSize: AppFontSizes.body,
                            color: colors.textPrimary,
                          ),
                        ),
                        if (d.remark.isNotEmpty)
                          Text(
                            d.remark,
                            style: TextStyle(
                              fontSize: AppFontSizes.caption,
                              color: colors.textPlaceholder,
                            ),
                          ),
                      ],
                    ),
                  ),
                  Text(
                    '${d.quantity}×¥${d.unitPrice.toStringAsFixed(2)}',
                    style: TextStyle(
                      fontSize: AppFontSizes.caption,
                      color: colors.textSecondary,
                    ),
                  ),
                  const SizedBox(width: 8),
                  Text(
                    '¥${d.amount.toStringAsFixed(2)}',
                    style: TextStyle(
                      fontSize: AppFontSizes.body,
                      fontWeight: FontWeight.w600,
                      color: colors.amountPrimary,
                    ),
                  ),
                  GestureDetector(
                    onTap: () => setState(() => _details.removeAt(e.key)),
                    child: Icon(
                      Icons.close,
                      size: 16,
                      color: colors.textPlaceholder,
                    ),
                  ),
                ],
              ),
            );
          }),
        Container(height: 1, color: colors.border),
        Container(
          height: 36,
          padding: const EdgeInsets.symmetric(vertical: 8),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text(
                l10n.get('total'),
                style: TextStyle(
                  fontSize: AppFontSizes.body,
                  fontWeight: FontWeight.w600,
                  color: colors.textPrimary,
                ),
              ),
              Text(
                '¥${_totalAmount().toStringAsFixed(2)}',
                style: TextStyle(
                  fontSize: AppFontSizes.subtitle,
                  fontWeight: FontWeight.w700,
                  color: colors.amountPrimary,
                ),
              ),
            ],
          ),
        ),
        if (_totalAmount() > _availableBudget)
          Padding(
            padding: const EdgeInsets.only(top: 8),
            child: Row(
              children: [
                Icon(Icons.warning_amber, size: 14, color: colors.danger),
                const SizedBox(width: 6),
                Expanded(
                  child: Text(
                    '您的申请金额已超支，提交后将自动触发高管特批流程',
                    style: TextStyle(
                      fontSize: AppFontSizes.caption,
                      color: colors.danger,
                    ),
                  ),
                ),
              ],
            ),
          ),
      ],
    );
  }

  double _totalAmount() => _details.fold(0, (s, d) => s + d.amount);

  static const _detailCategories = [
    ('transport', '交通费'),
    ('hotel', '住宿费'),
    ('office_supplies', '办公用品'),
    ('meals', '餐饮费'),
    ('materials', '材料费'),
    ('service', '服务费'),
    ('other', '其他'),
  ];
  static const _units = ['张', '间', '人', '天', '套', '个'];

  void _showDetailDialog() {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    String cat = 'transport';
    String unit = '张';
    final qtyCtrl = TextEditingController(text: '1');
    final priceCtrl = TextEditingController();
    final remarkCtrl = TextEditingController();

    showDialog(
      context: context,
      builder: (ctx) => StatefulBuilder(
        builder: (ctx, setDlg) => TDAlertDialog(
          title: '添加费用明细',
          contentWidget: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              _label('费用类别'),
              const SizedBox(height: 4),
              GestureDetector(
                onTap: () {
                  Navigator.pop(ctx);
                  _showListPicker(
                    '选择费用类别',
                    _detailCategories.map((c) => c.$2).toList(),
                    (v) {
                      cat = _detailCategories.firstWhere((c) => c.$2 == v).$1;
                      _showDetailDialog();
                    },
                  );
                },
                child: Container(
                  height: 44,
                  padding: const EdgeInsets.symmetric(horizontal: 12),
                  decoration: BoxDecoration(
                    color: colors.bgPage,
                    borderRadius: BorderRadius.circular(4),
                  ),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text(
                        _detailCategories.firstWhere((c) => c.$1 == cat).$2,
                        style: const TextStyle(fontSize: AppFontSizes.body),
                      ),
                      Icon(
                        Icons.arrow_drop_down,
                        color: colors.textPlaceholder,
                      ),
                    ],
                  ),
                ),
              ),
              const SizedBox(height: 12),
              Row(
                children: [
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        _label('数量'),
                        const SizedBox(height: 4),
                        TDInput(controller: qtyCtrl, hintText: '>0'),
                      ],
                    ),
                  ),
                  const SizedBox(width: 12),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        _label('单位'),
                        const SizedBox(height: 4),
                        GestureDetector(
                          onTap: () {
                            Navigator.pop(ctx);
                            _showListPicker('选择单位', _units, (v) {
                              unit = v;
                              _showDetailDialog();
                            });
                          },
                          child: Container(
                            height: 44,
                            padding: const EdgeInsets.symmetric(horizontal: 12),
                            decoration: BoxDecoration(
                              color: colors.bgPage,
                              borderRadius: BorderRadius.circular(4),
                            ),
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                              children: [
                                Text(
                                  unit,
                                  style: const TextStyle(
                                    fontSize: AppFontSizes.body,
                                  ),
                                ),
                                Icon(
                                  Icons.arrow_drop_down,
                                  color: colors.textPlaceholder,
                                ),
                              ],
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 12),
              _label('单价'),
              const SizedBox(height: 4),
              TDInput(controller: priceCtrl, hintText: '>0'),
              const SizedBox(height: 12),
              _label('明细说明'),
              const SizedBox(height: 4),
              TDInput(controller: remarkCtrl, hintText: '选填'),
            ],
          ),
          leftBtn: TDDialogButtonOptions(
            title: '取消',
            action: () => Navigator.pop(ctx),
          ),
          rightBtn: TDDialogButtonOptions(
            title: '确定',
            titleColor: colors.primary,
            action: () {
              final q = int.tryParse(qtyCtrl.text) ?? 0;
              final p = double.tryParse(priceCtrl.text) ?? 0;
              if (q <= 0 || p <= 0) {
                TDToast.showText('数量和单价必须大于0', context: context);
                return;
              }
              setState(
                () => _details.add(
                  _DetailItem(
                    id: _detailIdCounter++,
                    category: cat,
                    categoryName: _detailCategories
                        .firstWhere((c) => c.$1 == cat)
                        .$2,
                    quantity: q,
                    unit: unit,
                    unitPrice: p,
                    amount: q * p,
                    remark: remarkCtrl.text,
                  ),
                ),
              );
              Navigator.pop(ctx);
            },
          ),
        ),
      ),
    );
  }

  // ═══ 5. 附件上传 ═══
  Widget _buildAttachmentSection(AppLocalizations l10n) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    return FormSection(
      title: l10n.get('attachmentUpload'),
      children: [
        Text(
          l10n.get('maxAttachment'),
          style: TextStyle(
            fontSize: AppFontSizes.caption,
            color: colors.textPlaceholder,
          ),
        ),
        const SizedBox(height: 12),
        Wrap(
          spacing: 8,
          runSpacing: 8,
          children: [
            ..._attachments.asMap().entries.map(
              (e) => Stack(
                clipBehavior: Clip.none,
                children: [
                  Container(
                    width: 80,
                    height: 80,
                    decoration: BoxDecoration(
                      color: colors.primaryLight,
                      borderRadius: BorderRadius.circular(4),
                    ),
                    child: Center(
                      child: Icon(Icons.image, color: colors.primary, size: 32),
                    ),
                  ),
                  Positioned(
                    right: -4,
                    top: -4,
                    child: GestureDetector(
                      onTap: () => setState(() => _attachments.removeAt(e.key)),
                      child: Container(
                        width: 20,
                        height: 20,
                        decoration: BoxDecoration(
                          color: colors.danger,
                          shape: BoxShape.circle,
                        ),
                        child: const Icon(
                          Icons.close,
                          size: 12,
                          color: Colors.white,
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            if (_attachments.length < 9)
              GestureDetector(
                onTap: () {
                  // Mock: add attachment
                  setState(
                    () => _attachments.add(
                      '附件_${DateTime.now().millisecondsSinceEpoch}.jpg',
                    ),
                  );
                  TDToast.showText('已添加附件（mock）', context: context);
                },
                child: Container(
                  width: 80,
                  height: 80,
                  decoration: BoxDecoration(
                    color: colors.bgPage,
                    borderRadius: BorderRadius.circular(4),
                    border: Border.all(color: colors.border),
                  ),
                  child: Center(
                    child: Icon(
                      Icons.add,
                      size: 24,
                      color: colors.textPlaceholder,
                    ),
                  ),
                ),
              ),
          ],
        ),
      ],
    );
  }

  // ═══ 6. 底部操作栏 ═══
  Widget _buildBottomBar(AppLocalizations l10n) {
    final isDraft = widget.id != null;
    return ActionBar(
      leftLabel: isDraft ? l10n.get('reset') : null,
      centerLabel: l10n.get('saveDraft'),
      rightLabel: l10n.get('submitApproval'),
      showLeft: isDraft,
      onLeftTap: isDraft
          ? () => _showConfirmDialog(
              '确认重置',
              '将清空所有已填内容，此操作不可撤销',
              '取消',
              '确认重置',
              _resetAll,
            )
          : null,
      onCenterTap: () {
        TDToast.showSuccess('已保存为草稿', context: context);
        context.pop();
      },
      onRightTap: () {
        final err = _validate();
        if (err.isNotEmpty) {
          TDToast.showText(err.first, context: context);
          return;
        }
        TDToast.showSuccess('已提交，等待审批', context: context);
        context.pop();
      },
    );
  }

  List<String> _validate() {
    final e = <String>[];
    if (_expenseTypes.isEmpty) e.add('请至少选择一项费用类型');
    if (_purposeController.text.trim().isEmpty) e.add('请填写费用事由');
    if (_selectedProjectId == null) e.add('请选择关联项目');
    if (_selectedSubjectId == null) e.add('请选择预算科目');
    if (_details.isEmpty) e.add('请至少添加一行费用明细');
    if (_expenseTypes.contains('travel')) {
      if (_estimatedStartDate.isEmpty) e.add('请选择预计开始日期');
      if (_estimatedEndDate.isEmpty) e.add('请选择预计结束日期');
    }
    return e;
  }

  void _resetAll() => setState(() {
    _purposeController.clear();
    _expenseTypes.clear();
    _urgency = 0;
    _isTaxIncluded = false;
    _selectedProjectId = null;
    _selectedProjectName = null;
    _selectedSubjectId = null;
    _selectedSubjectName = null;
    _referenceNoController.clear();
    _details.clear();
    _attachments.clear();
    _estimatedStartDate = '';
    _estimatedEndDate = '';
    _entertainmentTarget = '';
    _venue = '';
  });

  bool _hasUnsaved() =>
      _purposeController.text.isNotEmpty ||
      _expenseTypes.isNotEmpty ||
      _details.isNotEmpty ||
      _attachments.isNotEmpty ||
      _selectedProjectId != null;

  // ═══ 通用弹窗方法 ═══
  void _showConfirmDialog(
    String title,
    String content,
    String leftText,
    String rightText,
    VoidCallback onConfirm,
  ) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    showDialog(
      context: context,
      builder: (ctx) => TDAlertDialog(
        title: title,
        content: content,
        leftBtn: TDDialogButtonOptions(
          title: leftText,
          titleColor: colors.primary,
          action: () => Navigator.pop(ctx),
        ),
        rightBtn: TDDialogButtonOptions(
          title: rightText,
          titleColor: colors.danger,
          action: () {
            Navigator.pop(ctx);
            onConfirm();
          },
        ),
      ),
    );
  }

  void _showListPicker(
    String title,
    List<String> items,
    Function(String) onPick,
  ) {
    showDialog(
      context: context,
      builder: (ctx) => TDAlertDialog(
        title: title,
        contentWidget: SizedBox(
          width: double.maxFinite,
          child: ListView(
            shrinkWrap: true,
            children: items
                .map(
                  (item) => TDCell(
                    title: item,
                    onClick: (_) {
                      onPick(item);
                      Navigator.pop(ctx);
                    },
                  ),
                )
                .toList(),
          ),
        ),
        leftBtn: TDDialogButtonOptions(
          title: '取消',
          action: () => Navigator.pop(ctx),
        ),
      ),
    );
  }

  void _showTextInput(String title, Function(String) onConfirm) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final c = TextEditingController();
    showDialog(
      context: context,
      builder: (ctx) => TDAlertDialog(
        title: title,
        contentWidget: TDInput(controller: c, hintText: '请输入'),
        leftBtn: TDDialogButtonOptions(
          title: '取消',
          action: () => Navigator.pop(ctx),
        ),
        rightBtn: TDDialogButtonOptions(
          title: '确定',
          titleColor: colors.primary,
          action: () {
            onConfirm(c.text);
            Navigator.pop(ctx);
          },
        ),
      ),
    );
  }

  void _showNumberInput(String title, Function(int) onConfirm) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final c = TextEditingController();
    showDialog(
      context: context,
      builder: (ctx) => TDAlertDialog(
        title: title,
        contentWidget: TDInput(
          controller: c,
          inputType: TextInputType.number,
          hintText: '请输入数字',
        ),
        leftBtn: TDDialogButtonOptions(
          title: '取消',
          action: () => Navigator.pop(ctx),
        ),
        rightBtn: TDDialogButtonOptions(
          title: '确定',
          titleColor: colors.primary,
          action: () {
            onConfirm(int.tryParse(c.text) ?? 0);
            Navigator.pop(ctx);
          },
        ),
      ),
    );
  }

  void _pickDate(Function(String) onPick) {
    final now = DateTime.now();
    TDPicker.showDatePicker(
      context,
      title: '选择日期',
      useYear: true,
      useMonth: true,
      useDay: true,
      initialDate: [now.year, now.month, now.day],
      onConfirm: (selected) {
        onPick(
          '${selected['year']}-${selected['month']!.toString().padLeft(2, '0')}-${selected['day']!.toString().padLeft(2, '0')}',
        );
      },
    );
  }

  Widget _label(String t) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    return Text(
      t,
      style: TextStyle(
        fontSize: AppFontSizes.body,
        color: colors.textSecondary,
      ),
    );
  }

  String _today() {
    final n = DateTime.now();
    return '${n.year}-${n.month.toString().padLeft(2, '0')}-${n.day.toString().padLeft(2, '0')}';
  }
}

class _DetailItem {
  final int id;
  final String category;
  final String categoryName;
  final int quantity;
  final String unit;
  final double unitPrice;
  final double amount;
  final String remark;
  const _DetailItem({
    required this.id,
    required this.category,
    required this.categoryName,
    required this.quantity,
    required this.unit,
    required this.unitPrice,
    required this.amount,
    required this.remark,
  });
}
