import 'package:flutter/material.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../shared/widgets/nav_bar_config.dart';
import '../../core/utils/date_utils.dart' as du;
import '../../shared/widgets/form_section.dart';
import '../../shared/widgets/form_field_row.dart';
import '../../shared/widgets/status_banner.dart';
import '../../shared/widgets/action_bar.dart';
import 'expense_model.dart';
import '../../core/i18n/app_localizations.dart';
import 'expense_list_controller.dart';
import '../../core/theme/app_colors.dart';
import '../../core/theme/app_colors_extension.dart';
import '../../core/auth/role_provider.dart';

class ExpenseDetailPage extends ConsumerWidget {
  final String id;
  const ExpenseDetailPage({super.key, required this.id});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final expense = mockExpenses.firstWhere(
      (e) => e.id == id,
      orElse: () => mockExpenses.first,
    );
    final l10n = AppLocalizations.of(context);
    final isFinance = ref.watch(isFinanceProvider);
    final isAdmin = ref.watch(isAdminProvider);

    ref
        .read(navBarConfigProvider.notifier)
        .update(
          NavBarConfig(
            title: l10n.get('expenseDetail'),
            showBack: true,
            onBack: () => context.pop(),
          ),
        );
    return Column(
      children: [
        Expanded(
          child: SingleChildScrollView(
            padding: const EdgeInsets.all(16),
            child: Column(
              children: [
                _buildStatusBanner(expense, l10n, colors),
                const SizedBox(height: 8),
                _buildSubmitTime(expense, l10n, colors),
                const SizedBox(height: 16),
                _buildBasicInfoSection(expense, l10n, colors),
                const SizedBox(height: 16),
                _buildExpenseDetailSection(expense, l10n, colors),
                const SizedBox(height: 16),
                _buildInvoiceSection(expense, l10n, colors),
                if (isFinance) ...[
                  const SizedBox(height: 16),
                  _buildComplianceSection(expense, l10n, colors),
                ],
                const SizedBox(height: 16),
                _buildApprovalSection(l10n, colors),
                if (isFinance || isAdmin) ...[
                  const SizedBox(height: 16),
                  _buildArchiveSection(expense, l10n, colors),
                ],
              ],
            ),
          ),
        ),
        _buildBottomBar(context, expense, isFinance: isFinance, isAdmin: isAdmin),
      ],
    );
  }

  Widget _buildStatusBanner(ExpenseModel expense, AppLocalizations l10n, AppColorsExtension colors) {
    final (icon, color, label) = switch (expense.status) {
      'approved' => (Icons.check_circle, colors.success, l10n.get('approved')),
      'rejected' => (Icons.cancel, colors.danger, l10n.get('rejected')),
      'draft' => (Icons.edit, colors.statusGray, l10n.get('draft')),
      _ => (Icons.schedule, colors.warning, l10n.get('pending')),
    };
    final approverText = switch (expense.status) {
      'approved' when expense.approvalRecords.isNotEmpty => '${l10n.get('approver')}：${expense.approvalRecords.last.approverName}',
      'rejected' when expense.approvalRecords.isNotEmpty => '${l10n.get('rejecter')}：${expense.approvalRecords.last.approverName}',
      'pending' when expense.currentApproverId.isNotEmpty => '${l10n.get('currentApprover')}：${expense.currentApproverId}',
      _ => '',
    };
    return StatusBanner(icon: icon, statusText: label, subText: approverText, color: color);
  }

  Widget _buildSubmitTime(ExpenseModel expense, AppLocalizations l10n, AppColorsExtension colors) {
    return Padding(
      padding: const EdgeInsets.only(left: 4),
      child: Text('${l10n.get('submitTimeText')}：${du.DateUtils.formatDateTime(expense.createTime)}',
          style: TextStyle(fontSize: AppFontSizes.caption, color: colors.textSecondary)),
    );
  }

  // ═══ 基本信息 + 收款账户 — 对应 create 页 basicInfo + 数据库 Expense 字段 ═══
  Widget _buildBasicInfoSection(ExpenseModel expense, AppLocalizations l10n, AppColorsExtension colors) {
    var pms = expense.paymentMethod;
    if (pms == 'bankTransfer') pms = l10n.get('bankTransfer');
    else if (pms == 'cash') pms = l10n.get('cash');
    else if (pms == 'alipay') pms = l10n.get('alipay');
    else if (pms == 'wechat') pms = l10n.get('wechat');
    return FormSection(
      title: l10n.get('basicInfo'),
      leadingIcon: Icons.info_outline,
      children: [
        FormFieldRow(label: l10n.get('expenseNo'), value: expense.expenseNo, readOnly: true, showArrow: false),
        const SizedBox(height: 16),
        FormFieldRow(label: l10n.get('applicant'), value: expense.applicantName, readOnly: true, showArrow: false),
        const SizedBox(height: 16),
        FormFieldRow(label: l10n.get('department'), value: expense.deptName, readOnly: true, showArrow: false),
        const SizedBox(height: 16),
        FormFieldRow(label: l10n.get('date'), value: du.DateUtils.formatDateTime(expense.createTime), readOnly: true, showArrow: false),
        const SizedBox(height: 16),
        FormFieldRow(label: l10n.get('currency'), value: expense.currencyCode, readOnly: true, showArrow: false),
        const SizedBox(height: 16),
        FormFieldRow(label: l10n.get('feeReason'), value: expense.purpose, readOnly: true, showArrow: false),
        const SizedBox(height: 16),
        FormFieldRow(label: l10n.get('expenseAmount'), value: '¥${expense.totalAmount.toStringAsFixed(2)}', readOnly: true, showArrow: false),
        if (expense.approvedAmount > 0) ...[
          const SizedBox(height: 16),
          FormFieldRow(label: l10n.get('approvedAmount'), value: '¥${expense.approvedAmount.toStringAsFixed(2)}', readOnly: true, showArrow: false),
        ],
        const SizedBox(height: 16),
        FormFieldRow(label: l10n.get('paymentMethod'), value: pms.isNotEmpty ? pms : '-', readOnly: true, showArrow: false),
        if (expense.details.any((d) => d.bankName.isNotEmpty)) ...[
          const SizedBox(height: 16),
          FormSection(title: l10n.get('receiptAccount'), leadingIcon: Icons.account_balance_outlined, children: [
            for (final d in expense.details.where((d) => d.bankName.isNotEmpty))
              Padding(
                padding: const EdgeInsets.only(bottom: 12),
                child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                  Text('${d.bankName}', style: TextStyle(fontSize: AppFontSizes.subtitle, fontWeight: FontWeight.w600, color: colors.textPrimary)),
                  const SizedBox(height: 4),
                  Text('${d.bankAccountName}  ${d.bankAccount}', style: TextStyle(fontSize: AppFontSizes.caption, color: colors.textSecondary)),
                ]),
              ),
          ]),
        ],
      ],
    );
  }

  // ═══ 费用明细 — 对应 create 页 detailSection + 数据库 ExpenseDetail ═══
  Widget _buildExpenseDetailSection(ExpenseModel expense, AppLocalizations l10n, AppColorsExtension colors) {
    return FormSection(
      title: l10n.get('expenseDetails'),
      leadingIcon: Icons.receipt_long_outlined,
      children: [
        if (expense.details.isEmpty)
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 8),
            child: Text(l10n.get('noDetailData'), style: TextStyle(fontSize: AppFontSizes.body, color: colors.textPlaceholder)),
          )
        else
          ...expense.details.asMap().entries.map((e) {
            final d = e.value;
            return Container(
              margin: const EdgeInsets.symmetric(vertical: 8),
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(color: colors.bgPage, borderRadius: BorderRadius.circular(8)),
              child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
                  Expanded(
                    child: Text(d.purpose.isNotEmpty ? d.purpose : d.expenseCategory,
                        style: TextStyle(fontSize: AppFontSizes.subtitle, fontWeight: FontWeight.w600, color: colors.textPrimary)),
                  ),
                  const SizedBox(width: 16),
                  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.isNotEmpty ? ' | ${d.bankName}' : ''}',
                    style: TextStyle(fontSize: AppFontSizes.caption, color: colors.textSecondary)),
                if (d.projectName.isNotEmpty) ...[
                  const SizedBox(height: 4),
                  Text('${l10n.get('relatedProject')}：${d.projectName}  |  ${l10n.get('budgetSubject')}：${d.acctSubjectName}',
                      style: TextStyle(fontSize: AppFontSizes.caption, color: colors.textSecondary)),
                ],
                if (d.costDeptName.isNotEmpty) ...[
                  const SizedBox(height: 4),
                  Text('${l10n.get('costDept')}：${d.costDeptName}',
                      style: TextStyle(fontSize: AppFontSizes.caption, color: colors.textSecondary)),
                ],
                if (d.customerVendorName.isNotEmpty) ...[
                  const SizedBox(height: 4),
                  Text('${l10n.get('customerVendor')}：${d.customerVendorName}',
                      style: TextStyle(fontSize: AppFontSizes.caption, color: colors.textSecondary)),
                ],
                if (d.approvedAmount > 0) ...[
                  const SizedBox(height: 4),
                  Text('${l10n.get('approvedAmount')}：¥${d.approvedAmount.toStringAsFixed(2)}',
                      style: TextStyle(fontSize: AppFontSizes.caption, color: colors.success)),
                ],
                if (d.remark.isNotEmpty) ...[
                  const SizedBox(height: 4),
                  Text(d.remark, maxLines: 2, overflow: TextOverflow.ellipsis,
                      style: TextStyle(fontSize: AppFontSizes.caption, color: colors.textSecondary)),
                ],
              ]),
            );
          }),
        if (expense.details.isNotEmpty) ...[
          const SizedBox(height: 8),
          Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
            Text(l10n.get('total'), style: TextStyle(fontSize: AppFontSizes.body, fontWeight: FontWeight.w600, color: colors.textPrimary)),
            Text('¥${expense.totalAmount.toStringAsFixed(2)}',
                style: TextStyle(fontSize: AppFontSizes.subtitle, fontWeight: FontWeight.w700, color: colors.amountPrimary)),
          ]),
        ],
      ],
    );
  }

  // ═══ 发票附件 ═══
  Widget _buildInvoiceSection(ExpenseModel expense, AppLocalizations l10n, AppColorsExtension colors) {
    return FormSection(
      title: l10n.get('invoiceAttachment'),
      leadingIcon: Icons.attach_file_outlined,
      children: [
        if (expense.attachments.isEmpty)
          Text(l10n.get('noAttachment'), style: TextStyle(fontSize: AppFontSizes.body, color: colors.textPlaceholder))
        else
          Wrap(spacing: 8, runSpacing: 8, children: expense.attachments.map((url) {
            return 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.image_outlined, size: 24, color: colors.textPlaceholder)));
          }).toList()),
      ],
    );
  }

  // ═══ 财务合规查验 ═══
  Widget _buildComplianceSection(ExpenseModel expense, AppLocalizations l10n, AppColorsExtension colors) {
    final checks = [
      (expense.isInvoiceVerified, l10n.get('invoiceCheck1')),
      (expense.isTaxIdMatched, l10n.get('invoiceCheck2')),
      (expense.isCategoryCompliant, l10n.get('invoiceCheck3')),
    ];
    return FormSection(
      title: l10n.get('invoiceCheck'),
      leadingIcon: Icons.verified_outlined,
      children: checks.asMap().entries.map((e) {
        final (passed, text) = e.value;
        return Padding(
          padding: EdgeInsets.only(top: e.key > 0 ? 12 : 0),
          child: SizedBox(height: 24, child: Row(children: [
            Icon(passed ? Icons.check_circle : Icons.radio_button_unchecked, size: 16, color: passed ? colors.success : colors.textPlaceholder),
            const SizedBox(width: 8),
            Text(text, style: TextStyle(fontSize: AppFontSizes.subtitle, color: colors.textPrimary)),
          ])),
        );
      }).toList(),
    );
  }

  // ═══ 审核流程 — 时间线组件 ═══
  Widget _buildApprovalSection(AppLocalizations l10n, AppColorsExtension colors) {
    final steps = <({String title, String desc, String? time, IconData icon, Color iconColor})>[
      (title: l10n.get('approvalStepSubmitted'),       desc: l10n.get('approvalDescSubmitted'),      time: '2026-06-29 09:15', icon: Icons.check_circle,     iconColor: colors.success),
      (title: l10n.get('approvalStepApproved'),        desc: l10n.get('approvalDescApproved'),       time: '2026-06-29 14:30', icon: Icons.check_circle,     iconColor: colors.success),
      (title: l10n.get('approvalStepInvoice'),         desc: l10n.get('approvalDescInvoice'),        time: null,              icon: Icons.schedule,        iconColor: colors.warning),
      (title: l10n.get('approvalStepPayment'),         desc: l10n.get('approvalStepPaymentDesc'),    time: null,              icon: Icons.hourglass_empty, iconColor: colors.textPlaceholder),
    ];
    return FormSection(
      title: l10n.get('approvalFlow'),
      leadingIcon: Icons.fact_check_outlined,
      children: [
        ...steps.asMap().entries.map((e) {
          final s = e.value;
          final isLast = e.key == steps.length - 1;
          final isActive = e.key <= 2;
          final iconColor = isActive ? s.iconColor : colors.textPlaceholder;
          final textColor = isActive ? colors.textPrimary : colors.textPlaceholder;
          final subColor = isActive ? colors.textSecondary : colors.textPlaceholder;
          return IntrinsicHeight(
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                SizedBox(
                  width: 24,
                  child: Column(
                    children: [
                      Container(
                        width: 24, height: 24,
                        decoration: BoxDecoration(
                          color: isActive ? s.iconColor.withAlpha(30) : colors.bgDisabled,
                          shape: BoxShape.circle,
                        ),
                        child: Icon(s.icon, size: 14, color: iconColor),
                      ),
                      if (!isLast)
                        Expanded(
                          child: Container(
                            width: 2,
                            margin: const EdgeInsets.symmetric(vertical: 4),
                            color: isActive ? s.iconColor.withAlpha(60) : colors.border,
                          ),
                        ),
                    ],
                  ),
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: Padding(
                    padding: EdgeInsets.only(bottom: isLast ? 0 : 16),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(s.title, style: TextStyle(fontSize: AppFontSizes.subtitle, fontWeight: FontWeight.w600, color: textColor)),
                        const SizedBox(height: 4),
                        Text(s.desc, style: TextStyle(fontSize: AppFontSizes.caption, color: subColor)),
                        if (s.time != null) ...[
                          const SizedBox(height: 2),
                          Text(s.time!, style: TextStyle(fontSize: AppFontSizes.caption, color: colors.textPlaceholder)),
                        ],
                      ],
                    ),
                  ),
                ),
              ],
            ),
          );
        }),
      ],
    );
  }

  // ═══ 财务归档 ═══
  Widget _buildArchiveSection(ExpenseModel expense, AppLocalizations l10n, AppColorsExtension colors) {
    return FormSection(
      title: l10n.get('financialArchive'),
      leadingIcon: Icons.archive_outlined,
      children: [
        FormFieldRow(label: l10n.get('voucherNo'), value: expense.voucherNo.isNotEmpty ? expense.voucherNo : '-', readOnly: true, showArrow: false),
        const SizedBox(height: 16),
        FormFieldRow(label: l10n.get('bankTransferNo'), value: expense.bankTransferNo.isNotEmpty ? expense.bankTransferNo : '-', readOnly: true, showArrow: false),
        const SizedBox(height: 16),
        FormFieldRow(label: l10n.get('paymentStatus'), value: expense.paymentStatus == 'paid' ? l10n.get('paid') : l10n.get('unpaid'), readOnly: true, showArrow: false),
      ],
    );
  }

  Widget _buildBottomBar(BuildContext context, ExpenseModel expense, {required bool isFinance, required bool isAdmin}) {
    final l10n = AppLocalizations.of(context);
    if (isFinance && expense.status == 'approved' && expense.paymentStatus == 'unpaid') {
      return ActionBar(
        showLeft: true, leftLabel: l10n.get('confirmPaymentAndArchive'),
        centerLabel: l10n.get('nextPendingPayment'), rightLabel: l10n.get('confirmPaymentAndArchive'),
        onLeftTap: () {
          showDialog(context: context, builder: (ctx) => TDAlertDialog(
            title: l10n.get('confirmPaymentAndArchive'), content: l10n.get('confirmPaymentAndArchiveTip'),
            leftBtn: TDDialogButtonOptions(title: l10n.get('cancel'), action: () => Navigator.pop(ctx)),
            rightBtn: TDDialogButtonOptions(title: l10n.get('confirm'), action: () { Navigator.pop(ctx); TDToast.showText(l10n.get('paymentArchiveSuccess'), context: context); context.pop(); }),
          ));
        },
        onCenterTap: () => TDToast.showText(l10n.get('allPaymentsProcessed'), context: context),
      );
    }
    if (isFinance || isAdmin) return const SizedBox.shrink();
    if (expense.status != 'pending' && expense.status != 'draft') return const SizedBox.shrink();
    return ActionBar(
      showLeft: false, centerLabel: l10n.get('withdrawApplication'), rightLabel: l10n.get('submitApproval'),
      onCenterTap: () {
        showDialog(context: context, builder: (ctx) => TDAlertDialog(
          title: l10n.get('withdrawConfirm'), content: l10n.get('withdrawConfirmTip'),
          leftBtn: TDDialogButtonOptions(title: l10n.get('cancel'), action: () => Navigator.pop(ctx)),
          rightBtn: TDDialogButtonOptions(title: l10n.get('confirm'), action: () { Navigator.pop(ctx); TDToast.showText(l10n.get('withdrawn'), context: context); context.pop(); }),
        ));
      },
      onRightTap: null,
    );
  }
}
