import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import '../../../core/i18n/app_localizations.dart';
import '../../../core/theme/app_colors.dart';
import '../../../core/theme/app_colors_extension.dart';
import '../../../core/data/mock_api_data.dart';

/// 数字输入控制配置。
///
/// 封装键盘类型与输入过滤器，调用方控制：
/// - 是否允许小数
/// - 最多几位小数
/// - 对应的键盘类型
class NumberInputConfig {
  final bool allowDecimal;
  final int maxDecimalPlaces;

  const NumberInputConfig({
    this.allowDecimal = false,
    this.maxDecimalPlaces = 2,
  });

  /// 键盘类型：小数用带小数点的数字键盘，整数用纯数字键盘。
  TextInputType get keyboardType => allowDecimal
      ? const TextInputType.numberWithOptions(decimal: true)
      : TextInputType.number;

  /// 输入过滤器。
  List<TextInputFormatter> get inputFormatters => [
    FilteringTextInputFormatter.allow(
      allowDecimal
          ? RegExp(r'^\d*\.?\d{0,' + maxDecimalPlaces.toString() + r'}$')
          : RegExp(r'^\d*$'),
    ),
  ];

  /// 仅整数。
  static const integer = NumberInputConfig();

  /// 最多 2 位小数（如数量）。
  static const qty = NumberInputConfig(allowDecimal: true);

  /// 最多 2 位小数（如金额/单价）。
  static const money = NumberInputConfig(allowDecimal: true);
}

/// 费用明细输入数据。
class ExpenseDetailData {
  final String category;
  final String categoryName;
  final double quantity;
  final String unit;
  final double unitPrice;
  final String remark;

  const ExpenseDetailData({
    required this.category,
    required this.categoryName,
    required this.quantity,
    required this.unit,
    required this.unitPrice,
    required this.remark,
  });
}

/// 添加费用明细弹窗。
///
/// 使用 [TDSlidePopupRoute] 从底部滑出，卡片化展示表单字段。
/// [quantityConfig] 与 [priceConfig] 控制各自输入的数字格式。
/// const NumberInputConfig(allowDecimal: true, maxDecimalPlaces: 3) // 允许小数，最多3位小数
class ExpenseDetailDialog extends StatefulWidget {
  final List<CostCategory> categories;
  final List<String> unitKeys;
  final AppLocalizations l10n;
  final NumberInputConfig quantityConfig;
  final NumberInputConfig priceConfig;

  const ExpenseDetailDialog({
    super.key,
    required this.categories,
    required this.unitKeys,
    required this.l10n,
    this.quantityConfig = NumberInputConfig.qty,
    this.priceConfig = NumberInputConfig.money,
  });

  /// 显示弹窗，返回 [ExpenseDetailData] 或 `null`（取消时）。
  static Future<ExpenseDetailData?> show(
    BuildContext context, {
    required List<CostCategory> categories,
    required List<String> unitKeys,
    required AppLocalizations l10n,
    NumberInputConfig quantityConfig = NumberInputConfig.money,
    NumberInputConfig priceConfig = NumberInputConfig.money,
  }) {
    FocusScope.of(context).unfocus();
    return Navigator.push<ExpenseDetailData>(
      context,
      TDSlidePopupRoute<ExpenseDetailData>(
        slideTransitionFrom: SlideTransitionFrom.bottom,
        isDismissible: false,
        builder: (_) => ExpenseDetailDialog(
          categories: categories,
          unitKeys: unitKeys,
          l10n: l10n,
          quantityConfig: quantityConfig,
          priceConfig: priceConfig,
        ),
      ),
    );
  }

  @override
  State<ExpenseDetailDialog> createState() => _ExpenseDetailDialogState();
}

class _ExpenseDetailDialogState extends State<ExpenseDetailDialog> {
  late String _cat;
  late String _unit;
  late String _catLabel;
  late String _unitLabel;
  late TextEditingController _qtyCtrl;
  late TextEditingController _priceCtrl;
  late TextEditingController _remarkCtrl;

  List<CostCategory> get _cats => widget.categories;
  AppLocalizations get _l10n => widget.l10n;

  @override
  void initState() {
    super.initState();
    _cat = _cats.isNotEmpty ? _cats.first.code : 'other';
    _unit = widget.unitKeys.first;
    _catLabel = _l10n.get(_cats.firstWhere((c) => c.code == _cat).nameKey);
    _unitLabel = _l10n.get(_unit);
    _qtyCtrl = TextEditingController(text: '1');
    _priceCtrl = TextEditingController();
    _remarkCtrl = TextEditingController();
  }

  @override
  void dispose() {
    _qtyCtrl.dispose();
    _priceCtrl.dispose();
    _remarkCtrl.dispose();
    super.dispose();
  }

  void _confirm() {
    final q = double.tryParse(_qtyCtrl.text) ?? 0;
    final p = double.tryParse(_priceCtrl.text) ?? 0;
    if (q <= 0 || p <= 0) {
      TDToast.showText(_l10n.get('quantityPricePositive'), context: context);
      return;
    }
    Navigator.pop(
      context,
      ExpenseDetailData(
        category: _cat,
        categoryName: _l10n.get(
          _cats.firstWhere((c) => c.code == _cat).nameKey,
        ),
        quantity: q,
        unit: _unit,
        unitPrice: p,
        remark: _remarkCtrl.text,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final bottomInset = MediaQuery.of(context).viewInsets.bottom;

    return SafeArea(
      child: Padding(
        padding: EdgeInsets.only(bottom: bottomInset),
        child: Container(
          decoration: BoxDecoration(
            color: colors.bgPage,
            borderRadius: const BorderRadius.vertical(top: Radius.circular(16)),
          ),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              _buildHeader(colors),
              Flexible(
                child: SingleChildScrollView(
                  padding: const EdgeInsets.fromLTRB(16, 0, 16, 12),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: [
                      _buildCategoryCard(colors),
                      const SizedBox(height: 12),
                      _buildQuantityCard(),
                      const SizedBox(height: 12),
                      _buildUnitCard(colors),
                      const SizedBox(height: 12),
                      _buildPriceCard(),
                      const SizedBox(height: 12),
                      _buildRemarkCard(colors),
                    ],
                  ),
                ),
              ),
              Container(
                padding: const EdgeInsets.fromLTRB(16, 12, 16, 16),
                decoration: BoxDecoration(
                  color: colors.bgCard,
                  border: Border(
                    top: BorderSide(color: colors.border, width: 0.5),
                  ),
                ),
                child: _buildActions(),
              ),
            ],
          ),
        ),
      ),
    );
  }

  // ── 标题栏（居中标题 + 右侧关闭） ──
  Widget _buildHeader(AppColorsExtension colors) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Center(
          child: Container(
            margin: const EdgeInsets.only(top: 8, bottom: 4),
            width: 36,
            height: 4,
            decoration: BoxDecoration(
              color: colors.border,
              borderRadius: BorderRadius.circular(2),
            ),
          ),
        ),
        Padding(
          padding: const EdgeInsets.fromLTRB(20, 8, 12, 16),
          child: Row(
            children: [
              const SizedBox(width: 28),
              Expanded(
                child: Center(
                  child: Text(
                    _l10n.get('addExpenseDetail'),
                    style: TextStyle(
                      fontSize: AppFontSizes.title,
                      fontWeight: FontWeight.w600,
                      color: colors.textPrimary,
                    ),
                  ),
                ),
              ),
              GestureDetector(
                onTap: () => Navigator.pop(context),
                child: Padding(
                  padding: const EdgeInsets.all(4),
                  child: Icon(Icons.close, size: 20, color: colors.textSecondary),
                ),
              ),
            ],
          ),
        ),
      ],
    );
  }

  // ── 选择卡片（点击唤起 TDPicker.showMultiPicker，右侧箭头） ──
  Widget _pickerCard({
    required String label,
    required bool required,
    required String currentLabel,
    required List<String> labels,
    required ValueChanged<int> onSelected,
    required AppColorsExtension colors,
  }) {
    final tdTheme = TDTheme.of(context);
    return GestureDetector(
      onTap: () {
        TDPicker.showMultiPicker(
          context,
          title: label,
          backgroundColor: colors.bgCard,
          data: [labels.map((e) => e).toList()],
          onConfirm: (selected) {
            if (selected.isNotEmpty && selected[0] is int) {
              final idx = selected[0] as int;
              if (idx >= 0 && idx < labels.length) {
                Navigator.of(context).pop();
                onSelected(idx);
              }
            }
          },
        );
      },
      child: Container(
        padding: const EdgeInsets.only(
          left: 16, right: 16, top: 12, bottom: 12,
        ),
        decoration: BoxDecoration(
          color: tdTheme.bgColorContainer,
          borderRadius: BorderRadius.circular(tdTheme.radiusDefault),
          border: Border.all(color: tdTheme.componentStrokeColor),
        ),
        child: Row(
          children: [
            TDText(
              label,
              maxLines: 1,
              overflow: TextOverflow.visible,
              font: tdTheme.fontBodyLarge,
              fontWeight: FontWeight.w400,
              style: const TextStyle(letterSpacing: 0),
            ),
            if (required)
              Padding(
                padding: const EdgeInsets.only(left: 4.0),
                child: TDText(
                  '*',
                  font: tdTheme.fontBodyLarge,
                  fontWeight: FontWeight.w400,
                  style: TextStyle(color: tdTheme.errorColor6),
                ),
              ),
            const SizedBox(width: 12),
            Expanded(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.end,
                mainAxisSize: MainAxisSize.max,
                children: [
                  Flexible(
                    child: TDText(
                      currentLabel,
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                      font: tdTheme.fontBodyLarge,
                      fontWeight: FontWeight.w400,
                      textColor: tdTheme.textColorPrimary,
                      textAlign: TextAlign.end,
                    ),
                  ),
                  const SizedBox(width: 4),
                  Icon(
                    Icons.chevron_right,
                    size: 18,
                    color: tdTheme.textColorPlaceholder,
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  // ── 费用类别 ──
  Widget _buildCategoryCard(AppColorsExtension colors) {
    return _pickerCard(
      label: _l10n.get('expenseCategory'),
      required: true,
      currentLabel: _catLabel,
      labels: _cats.map((c) => _l10n.get(c.nameKey)).toList(),
      colors: colors,
      onSelected: (idx) => setState(() {
        _cat = _cats[idx].code;
        _catLabel = _l10n.get(_cats[idx].nameKey);
      }),
    );
  }

  // ── 数量（cardStyle，独占一行） ──
  Widget _buildQuantityCard() {
    final screenWidth = MediaQuery.of(context).size.width;

    return TDInput(
      type: TDInputType.cardStyle,
      cardStyle: TDCardStyle.topText,
      width: screenWidth - 32,
      leftLabel: _l10n.get('quantity'),
      required: true,
      controller: _qtyCtrl,
      hintText: '>0',
      contentAlignment: TextAlign.center,
      inputType: widget.quantityConfig.keyboardType,
      inputFormatters: widget.quantityConfig.inputFormatters,
      showBottomDivider: false,
      onChanged: (_) => setState(() {}),
      onClearTap: () {
        _qtyCtrl.clear();
        setState(() {});
      },
    );
  }

  // ── 单位 ──
  Widget _buildUnitCard(AppColorsExtension colors) {
    return _pickerCard(
      label: _l10n.get('unit'),
      required: false,
      currentLabel: _unitLabel,
      labels: widget.unitKeys.map((u) => _l10n.get(u)).toList(),
      colors: colors,
      onSelected: (idx) => setState(() {
        _unit = widget.unitKeys[idx];
        _unitLabel = _l10n.get(_unit);
      }),
    );
  }

  // ── 单价（cardStyle） ──
  Widget _buildPriceCard() {
    final screenWidth = MediaQuery.of(context).size.width;

    return TDInput(
      type: TDInputType.cardStyle,
      cardStyle: TDCardStyle.topText,
      width: screenWidth - 32,
      leftLabel: _l10n.get('unitPrice'),
      required: true,
      controller: _priceCtrl,
      hintText: '>0',
      contentAlignment: TextAlign.center,
      inputType: widget.priceConfig.keyboardType,
      inputFormatters: widget.priceConfig.inputFormatters,
      showBottomDivider: false,
      onChanged: (_) => setState(() {}),
      onClearTap: () {
        _priceCtrl.clear();
        setState(() {});
      },
    );
  }

  // ── 备注 ──
  Widget _buildRemarkCard(AppColorsExtension colors) {
    final tdTheme = TDTheme.of(context);
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.only(left: 4),
          child: TDText(
            _l10n.get('detailRemark'),
            font: tdTheme.fontBodyLarge,
            fontWeight: FontWeight.w400,
            style: const TextStyle(letterSpacing: 0),
          ),
        ),
        const SizedBox(height: 8),
        TDTextarea(
          controller: _remarkCtrl,
          hintText: _l10n.get('optional'),
          maxLines: 3,
          minLines: 1,
          maxLength: 200,
          indicator: true,
          padding: EdgeInsets.zero,
          bordered: true,
          inputType: TextInputType.multiline,
          backgroundColor: tdTheme.bgColorContainer,
        ),
      ],
    );
  }

  // ── 操作按钮 ──
  Widget _buildActions() {
    return Row(
      children: [
        Expanded(
          child: TDButton(
            text: _l10n.get('cancel'),
            size: TDButtonSize.large,
            type: TDButtonType.outline,
            shape: TDButtonShape.rectangle,
            theme: TDButtonTheme.defaultTheme,
            onTap: () => Navigator.pop(context),
          ),
        ),
        const SizedBox(width: 12),
        Expanded(
          child: TDButton(
            text: _l10n.get('confirm'),
            size: TDButtonSize.large,
            type: TDButtonType.fill,
            shape: TDButtonShape.rectangle,
            theme: TDButtonTheme.primary,
            onTap: _confirm,
          ),
        ),
      ],
    );
  }
}
