import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import 'package:go_router/go_router.dart';
import '../../shared/widgets/nav_bar_config.dart';
import '../../core/utils/responsive.dart';
import '../../shared/widgets/form_section.dart';
import '../../shared/widgets/form_field_row.dart';
import 'expense_api.dart';
import 'expense_create_controller.dart';
import '../../core/i18n/app_localizations.dart';
import 'expense_model.dart';
import '../../core/theme/app_colors.dart';
import '../../core/theme/app_colors_extension.dart';
import '../../core/data/mock_api_data.dart';
import 'widgets/expense_detail_dialog.dart';
import 'package:image_picker/image_picker.dart';

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

  @override
  ConsumerState<ExpenseApplyPage> createState() => _ExpenseApplyPageState();
}

class _ExpenseApplyPageState extends ConsumerState<ExpenseApplyPage> {
  final _purposeController = TextEditingController();
  final List<String> _attachments = [];

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) => _checkDraft());
  }

  Future<void> _checkDraft() async {
    if (!mounted || widget.editId != null) return;
    final has = await ExpenseCreateController.hasDraft();
    if (!has || !mounted) return;
    final l10n = AppLocalizations.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final yes = await showDialog<bool>(
      context: context,
      builder: (ctx) => TDAlertDialog(
        title: l10n.get('draftFound'),
        content: l10n.get('draftRestorePrompt'),
        leftBtn: TDDialogButtonOptions(
          title: l10n.get('discard'),
          titleColor: colors.textSecondary,
          action: () => Navigator.pop(ctx, false),
        ),
        rightBtn: TDDialogButtonOptions(
          title: l10n.get('restore'),
          titleColor: colors.primary,
          action: () => Navigator.pop(ctx, true),
        ),
      ),
    );
    if (yes == true && mounted) {
      final draft = await ExpenseCreateController.loadDraft();
      if (draft != null && mounted) {
        final api = ref.read(expenseApiProvider);
        ref.read(expenseCreateProvider(widget.editId).notifier)
          ..restoreFromDraft(draft, api);
      }
    } else {
      await ExpenseCreateController.deleteDraft();
    }
  }

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

  @override
  Widget build(BuildContext context) {
    final controller = ref.watch(expenseCreateProvider(widget.editId).notifier);
    final state = ref.watch(expenseCreateProvider(widget.editId));
    final r = ResponsiveHelper.of(context);
    final l10n = AppLocalizations.of(context);

    ref
        .read(navBarConfigProvider.notifier)
        .update(
          NavBarConfig(
            title: widget.editId != null
                ? l10n.get('editExpense')
                : l10n.get('expenseApply'),
            showBack: true,
            onBack: () => context.pop(),
          ),
        );
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final bottomInset = MediaQuery.of(context).padding.bottom;
    return Column(
      children: [
        Expanded(
          child: Align(
            alignment: Alignment.topCenter,
            child: ConstrainedBox(
              constraints: BoxConstraints(maxWidth: r.formMaxWidth),
              child: SingleChildScrollView(
                padding: const EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    _buildImportLink(),
                    const SizedBox(height: 16),
                    _buildBasicInfoSection(controller, state),
                    const SizedBox(height: 16),
                    _buildDetailSection(controller, state),
                    const SizedBox(height: 16),
                    _buildInvoiceSection(controller, state),
                  ],
                ),
              ),
            ),
          ),
        ),
        ColoredBox(
          color: colors.bgCard,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              _buildBottomButtons(controller, state),
              if (bottomInset > 0) SizedBox(height: bottomInset),
            ],
          ),
        ),
      ],
    );
  }

  Widget _buildImportLink() {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final l10n = AppLocalizations.of(context);
    return GestureDetector(
      onTap: () {
        TDToast.showText(l10n.get('expenseApplyImport'), context: context);
      },
      child: Container(
        height: 44,
        decoration: BoxDecoration(
          color: colors.primaryLight,
          borderRadius: BorderRadius.circular(8),
        ),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(Icons.download, size: 14, color: colors.primary),
            const SizedBox(width: 8),
            Text(
              l10n.get('importApprovedPreApp'),
              style: TextStyle(
                fontSize: AppFontSizes.body,
                color: colors.primary,
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildBasicInfoSection(
    ExpenseCreateController controller,
    ExpenseCreateState state,
  ) {
    final l10n = AppLocalizations.of(context);
    final expense = state.expense;
    return FormSection(
      title: l10n.get('basicInfo'),
      leadingIcon: Icons.info_outline,
      children: [
        FormFieldRow(
          label: l10n.get('date'),
          value: _today(),
          readOnly: true,
          showArrow: false,
        ),
        const SizedBox(height: 16),
        FormFieldRow(
          label: l10n.get('reportNo'),
          value: expense.expenseNo.isNotEmpty ? expense.expenseNo : null,
          hint: l10n.get('autoGenerated'),
          readOnly: true,
          showArrow: false,
        ),
        const SizedBox(height: 16),
        FormFieldRow(
          label: l10n.get('currency'),
          value: expense.currencyCode.isNotEmpty ? expense.currencyCode : 'CNY',
          hint: l10n.get('selectCurrency'),
          onTap: () => _showCurrencyPicker(controller, expense.currencyCode),
        ),
        const SizedBox(height: 16),
        FormFieldRow(
          label: l10n.get('applicant'),
          value: expense.applicantName.isNotEmpty
              ? expense.applicantName
              : '张三',
          readOnly: true,
          showArrow: false,
        ),
        const SizedBox(height: 16),
        FormFieldRow(
          label: l10n.get('department'),
          value: expense.deptName.isNotEmpty ? expense.deptName : '技术部',
          readOnly: true,
          showArrow: false,
        ),
        const SizedBox(height: 16),
        FormFieldRow(
          label: l10n.get('paymentMethod'),
          value: expense.paymentMethod.isNotEmpty
              ? expense.paymentMethod
              : null,
          hint: l10n.get('selectPaymentMethod'),
          onTap: () => _showPaymentMethodPicker(controller),
        ),
        const SizedBox(height: 16),
        FormFieldRow(
          label: l10n.get('expenseReason'),
          value: _purposeController.text.isNotEmpty
              ? _purposeController.text
              : null,
          hint: l10n.get('enterExpenseReason'),
          onTap: () => _showTextInput(
            l10n.get('expenseReason'),
            l10n.get('enterExpenseReason'),
            (v) {
              setState(() {
                _purposeController.text = v;
                _purposeController.selection = TextSelection.fromPosition(
                  TextPosition(offset: v.length),
                );
              });
              controller.updatePurpose(v);
            },
            initialText: _purposeController.text,
          ),
        ),
      ],
    );
  }

  Widget _buildDetailSection(
    ExpenseCreateController controller,
    ExpenseCreateState state,
  ) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final l10n = AppLocalizations.of(context);
    final totalApproved = state.expense.details.fold<double>(
      0,
      (sum, d) => sum + d.approvedAmount,
    );
    return FormSection(
      title: l10n.get('expenseDetails'),
      leadingIcon: Icons.receipt_long_outlined,
      showAction: true,
      actionText: l10n.get('add'),
      onActionTap: () => _showAddDetailDialog(controller),
      children: [
        if (state.expense.details.isEmpty)
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 8),
            child: Text(
              l10n.get('noDetailHint'),
              style: TextStyle(fontSize: AppFontSizes.subtitle, color: colors.textPlaceholder),
            ),
          )
        else
          ...state.expense.details.asMap().entries.map((entry) {
            final d = entry.value;
            return Container(
              margin: const EdgeInsets.symmetric(vertical: 8),
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(color: colors.bgPage, borderRadius: BorderRadius.circular(8)),
              child: Stack(
                children: [
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Expanded(child: Text(d.purpose.isNotEmpty ? d.purpose : d.expenseCategory,
                              style: TextStyle(fontSize: AppFontSizes.subtitle, color: colors.textPrimary))),
                          Text('¥${d.totalAmount.toStringAsFixed(2)}',
                              style: TextStyle(fontSize: AppFontSizes.subtitle, fontWeight: FontWeight.w600, color: colors.amountPrimary)),
                        ],
                      ),
                      const SizedBox(height: 4),
                      Text('¥${d.amount.toStringAsFixed(2)} + 税${d.taxAmount.toStringAsFixed(2)} | ${d.bankName}',
                          style: TextStyle(fontSize: AppFontSizes.caption, color: colors.textSecondary)),
                    ],
                  ),
                  Positioned(
                    right: 0, top: 0,
                    child: GestureDetector(
                      onTap: () { controller.removeDetail(entry.key); controller.recalculateAmount(); },
                      child: Container(width: 24, height: 24, decoration: BoxDecoration(color: colors.primaryLight, shape: BoxShape.circle),
                          child: Icon(Icons.close, size: 14, color: colors.primary700)),
                    ),
                  ),
                ],
              ),
            );
          }),
        const SizedBox(height: 8),
        Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
          Text(l10n.get('totalExpense'), style: TextStyle(fontSize: AppFontSizes.body, fontWeight: FontWeight.w600, color: colors.textPrimary)),
          Text('¥${state.expense.totalAmount.toStringAsFixed(2)}', style: TextStyle(fontSize: AppFontSizes.subtitle, fontWeight: FontWeight.w700, color: colors.amountPrimary)),
        ]),
        const SizedBox(height: 4),
        Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
          Text(l10n.get('approvedTotal'), style: TextStyle(fontSize: AppFontSizes.body, fontWeight: FontWeight.w600, color: colors.textPrimary)),
          Text('¥${totalApproved.toStringAsFixed(2)}', style: TextStyle(fontSize: AppFontSizes.subtitle, fontWeight: FontWeight.w700, color: colors.amountPrimary)),
        ]),
      ],
    );
  }

  Widget _buildInvoiceSection(ExpenseCreateController controller, ExpenseCreateState state) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final l10n = AppLocalizations.of(context);
    return FormSection(
      title: l10n.get('invoiceUpload'),
      leadingIcon: Icons.attach_file_outlined,
      children: [
        Text(l10n.get('maxInvoices'), style: TextStyle(fontSize: AppFontSizes.caption, color: colors.textPlaceholder)),
        const SizedBox(height: 8),
        if (_attachments.isEmpty)
          Text(l10n.get('noAttachment'), style: TextStyle(fontSize: AppFontSizes.subtitle, color: colors.textPlaceholder))
        else
          Wrap(
            spacing: 8,
            runSpacing: 8,
            children: [
              ..._attachments.asMap().entries.map((entry) {
                final i = entry.key;
                final path = entry.value;
                final name = path.split('/').last.split('\\').last;
                return SizedBox(
                  width: 80,
                  child: Stack(
                    children: [
                      Container(
                        width: 80,
                        height: 80,
                        decoration: BoxDecoration(
                          color: colors.bgPage,
                          borderRadius: BorderRadius.circular(4),
                          border: Border.all(color: colors.border),
                        ),
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Icon(Icons.insert_drive_file, size: 28, color: colors.primary),
                            const SizedBox(height: 2),
                            Padding(
                              padding: const EdgeInsets.symmetric(horizontal: 4),
                              child: Text(
                                name,
                                maxLines: 2,
                                overflow: TextOverflow.ellipsis,
                                style: TextStyle(fontSize: 10, color: colors.textSecondary),
                                textAlign: TextAlign.center,
                              ),
                            ),
                          ],
                        ),
                      ),
                      Positioned(
                        right: 0,
                        top: 0,
                        child: GestureDetector(
                          onTap: () => setState(() => _attachments.removeAt(i)),
                          child: Container(
                            width: 20,
                            height: 20,
                            decoration: BoxDecoration(
                              color: colors.bgCard,
                              shape: BoxShape.circle,
                              border: Border.all(color: colors.border),
                            ),
                            child: Icon(Icons.close, size: 12, color: colors.textSecondary),
                          ),
                        ),
                      ),
                    ],
                  ),
                );
              }),
              if (_attachments.length < 9)
                GestureDetector(
                  onTap: _pickFiles,
                  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)),
                  ),
                ),
            ],
          ),
      ],
    );
  }

  Future<void> _pickFiles() async {
    final available = 9 - _attachments.length;
    if (available <= 0) return;
    final picker = ImagePicker();
    final images = await picker.pickMultiImage(limit: available);
    if (images.isEmpty) return;
    setState(() {
      _attachments.addAll(images.map((img) => img.path));
      if (_attachments.length > 9) _attachments.length = 9;
    });
  }

  Widget _buildBottomButtons(ExpenseCreateController controller, ExpenseCreateState state) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final l10n = AppLocalizations.of(context);
    return Container(height: 72, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), decoration: BoxDecoration(color: colors.bgCard),
        child: Row(children: [
          _btn(l10n.get('saveDraftShort'), colors.textSecondary, colors.bgCard, () async {
            if (state.isSubmitting) return;
            final ok = await controller.saveDraft();
            if (mounted && ok) TDToast.showText(l10n.get('draftSavedToast'), context: context);
          }),
          const SizedBox(width: 12),
          _btn(l10n.get('reset'), colors.textSecondary, colors.bgCard, () => setState(() => _purposeController.clear())),
          const SizedBox(width: 12),
          _btn(l10n.get('save'), colors.bgCard, colors.primary, () async {
            if (state.isSubmitting) return;
            await controller.saveDraft();
            if (mounted) context.pop();
          }),
        ]));
  }

  Widget _btn(String label, Color fg, Color bg, VoidCallback onTap) {
    return Expanded(child: SizedBox(height: 40,
        child: Material(color: bg, borderRadius: BorderRadius.circular(22),
            child: InkWell(onTap: onTap, borderRadius: BorderRadius.circular(22),
                child: Center(child: Text(label, style: TextStyle(fontSize: AppFontSizes.body, fontWeight: FontWeight.w500, color: fg)))))));
  }

  Future<void> _showAddDetailDialog(ExpenseCreateController controller) async {
    final l10n = AppLocalizations.of(context);
    final result = await ExpenseDetailDialog.show(context, categories: mockCostCategories, l10n: l10n);
    if (result != null && mounted) {
      final now = DateTime.now();
      controller.addDetail(ExpenseDetailModel(
        id: now.millisecondsSinceEpoch.toString(),
        expenseId: '',
        expenseCategory: result.category,
        purpose: result.purpose,
        amount: result.amount,
        taxRate: result.taxRate,
        totalAmount: result.amount,
        customerVendorName: result.customerVendorName,
        offsetAmount: result.offsetAmount,
        remark: result.remark,
        createTime: now,
        updateTime: now,
      ));
      controller.recalculateAmount();
    }
  }

  void _showCurrencyPicker(ExpenseCreateController controller, String cur) {
    final l10n = AppLocalizations.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    const cs = ['CNY', 'USD', 'EUR', 'JPY', 'HKD', 'GBP'];
    TDPicker.showMultiPicker(context, title: l10n.get('selectCurrency'), backgroundColor: colors.bgCard, data: [cs], onConfirm: (s) {
      if (s.isNotEmpty && s[0] is int) { final i = s[0] as int; if (i >= 0 && i < cs.length) { Navigator.of(context).pop(); controller.updateCurrencyCode(cs[i]); } }
    });
  }

  void _showPaymentMethodPicker(ExpenseCreateController controller) {
    final l10n = AppLocalizations.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    const ms = ['bankTransfer', 'cash', 'check', 'alipay', 'wechat'];
    TDPicker.showMultiPicker(context, title: l10n.get('selectPaymentMethod'), backgroundColor: colors.bgCard, data: [ms], onConfirm: (s) {
      if (s.isNotEmpty && s[0] is int) { final i = s[0] as int; if (i >= 0 && i < ms.length) { Navigator.of(context).pop(); TDToast.showText(ms[i], context: context); } }
    });
  }

  void _showTextInput(String title, String hint, void Function(String) onConfirm, {String initialText = ''}) {
    final l10n = AppLocalizations.of(context);
    final c = TextEditingController(text: initialText);
    showGeneralDialog(context: context, pageBuilder: (ctx, _, __) => TDInputDialog(
        textEditingController: c, title: title, hintText: hint,
        leftBtn: TDDialogButtonOptions(title: l10n.get('cancel'), action: () => Navigator.pop(ctx)),
        rightBtn: TDDialogButtonOptions(title: l10n.get('confirm'), action: () { onConfirm(c.text); Navigator.pop(ctx); })));
  }

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