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 '../shell/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 '../../shared/widgets/approval_timeline.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';

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);

    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: 4),
                _buildSubmitTime(expense, l10n, colors),
                const SizedBox(height: 16),
                _buildBasicInfoSection(expense, l10n, colors),
                const SizedBox(height: 16),
                _buildAccountSection(expense, l10n),
                const SizedBox(height: 16),
                _buildDetailSection(expense, l10n, colors),
                const SizedBox(height: 16),
                _buildInvoiceSection(expense, l10n, colors),
                const SizedBox(height: 16),
                _buildComplianceSection(expense, l10n, colors),
                const SizedBox(height: 16),
                if (expense.approvalRecords.isNotEmpty ||
                    expense.approvalChain.isNotEmpty)
                  _buildApprovalSection(expense, l10n),
                const SizedBox(height: 16),
                _buildArchiveSection(expense, l10n),
              ],
            ),
          ),
        ),
        _buildBottomBar(context, expense),
      ],
    );
  }

  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, top: 4),
      child: Align(
        alignment: Alignment.centerLeft,
        child: Text(
          '${l10n.get('submitTimeText')}：${du.DateUtils.formatDateTime(expense.createTime)}',
          style: TextStyle(
            fontSize: AppFontSizes.caption,
            color: colors.textPlaceholder,
          ),
        ),
      ),
    );
  }

  Widget _buildBasicInfoSection(
    ExpenseModel expense,
    AppLocalizations l10n,
    AppColorsExtension colors,
  ) {
    return FormSection(
      title: l10n.get('basicInfo'),
      children: [
        FormFieldRow(
          label: l10n.get('applicant'),
          value: expense.applicantName,
          readOnly: true,
          showArrow: false,
        ),
        FormFieldRow(
          label: l10n.get('department'),
          value: expense.deptName,
          readOnly: true,
          showArrow: false,
        ),
        FormFieldRow(
          label: l10n.get('expenseType'),
          value: expense.expenseType,
          readOnly: true,
          showArrow: false,
        ),
        Container(
          height: 44,
          padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 0),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text(
                l10n.get('expenseAmount'),
                style: TextStyle(
                  fontSize: AppFontSizes.body,
                  color: colors.textSecondary,
                ),
              ),
              Text(
                '¥${expense.totalAmount.toStringAsFixed(2)}',
                style: TextStyle(
                  fontSize: AppFontSizes.subtitle,
                  fontWeight: FontWeight.w700,
                  color: colors.amountPrimary,
                ),
              ),
            ],
          ),
        ),
        FormFieldRow(
          label: l10n.get('relatedProject'),
          value: expense.projectName.isNotEmpty ? expense.projectName : null,
          hint: '-',
          readOnly: true,
          showArrow: false,
        ),
        FormFieldRow(
          label: l10n.get('budgetSubject'),
          value: expense.budgetSubjectId.isNotEmpty
              ? expense.budgetSubjectId
              : null,
          hint: '-',
          readOnly: true,
          showArrow: false,
        ),
      ],
    );
  }

  Widget _buildAccountSection(ExpenseModel expense, AppLocalizations l10n) {
    return FormSection(
      title: l10n.get('receiptAccount'),
      children: [
        FormFieldRow(
          label: l10n.get('bankName'),
          value: expense.accountName.isNotEmpty ? expense.accountName : null,
          hint: '-',
          readOnly: true,
          showArrow: false,
        ),
        FormFieldRow(
          label: l10n.get('accountName'),
          value: expense.accountName.isNotEmpty ? expense.accountName : null,
          hint: '-',
          readOnly: true,
          showArrow: false,
        ),
        FormFieldRow(
          label: l10n.get('bankAccount'),
          value: expense.accountId.isNotEmpty ? expense.accountId : null,
          hint: '-',
          readOnly: true,
          showArrow: false,
        ),
      ],
    );
  }

  Widget _buildDetailSection(
    ExpenseModel expense,
    AppLocalizations l10n,
    AppColorsExtension colors,
  ) {
    return FormSection(
      title: l10n.get('expenseDetails'),
      children: [
        // Table header
        Container(
          height: 36,
          padding: const EdgeInsets.symmetric(horizontal: 8),
          decoration: BoxDecoration(
            color: colors.bgPage,
            borderRadius: BorderRadius.circular(4),
          ),
          child: Row(
            children: [
              Expanded(
                flex: 3,
                child: Text(
                  l10n.get('expenseProject'),
                  style: TextStyle(
                    fontSize: AppFontSizes.caption,
                    fontWeight: FontWeight.w500,
                    color: colors.textSecondary,
                  ),
                ),
              ),
              Expanded(
                flex: 2,
                child: Text(
                  l10n.get('amount'),
                  textAlign: TextAlign.right,
                  style: TextStyle(
                    fontSize: AppFontSizes.caption,
                    fontWeight: FontWeight.w500,
                    color: colors.textSecondary,
                  ),
                ),
              ),
            ],
          ),
        ),
        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.map(
            (d) => SizedBox(
              height: 28,
              child: Row(
                children: [
                  Expanded(
                    flex: 3,
                    child: Text(
                      d.expenseDesc,
                      style: TextStyle(
                        fontSize: AppFontSizes.body,
                        color: colors.textPrimary,
                      ),
                    ),
                  ),
                  Expanded(
                    flex: 2,
                    child: Text(
                      '¥${d.totalAmount.toStringAsFixed(2)}',
                      textAlign: TextAlign.right,
                      style: TextStyle(
                        fontSize: AppFontSizes.body,
                        fontWeight: FontWeight.w500,
                        color: colors.amountPrimary,
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        if (expense.details.isNotEmpty) ...[
          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(
                  '¥${expense.totalAmount.toStringAsFixed(2)}',
                  style: TextStyle(
                    fontSize: AppFontSizes.subtitle,
                    fontWeight: FontWeight.w700,
                    color: colors.amountPrimary,
                  ),
                ),
              ],
            ),
          ),
        ],
      ],
    );
  }

  Widget _buildInvoiceSection(
    ExpenseModel expense,
    AppLocalizations l10n,
    AppColorsExtension colors,
  ) {
    final hasInvoices = expense.invoiceImages.isNotEmpty;

    return FormSection(
      title: l10n.get('invoiceAttachment'),
      children: [
        if (!hasInvoices)
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 8),
            child: Text(
              l10n.get('noInvoice'),
              style: TextStyle(
                fontSize: AppFontSizes.body,
                color: colors.textPlaceholder,
              ),
            ),
          )
        else
          Wrap(
            spacing: 8,
            runSpacing: 8,
            children: expense.invoiceImages.map((url) {
              return Container(
                width: 80,
                height: 80,
                decoration: BoxDecoration(
                  color: colors.bgPage,
                  borderRadius: BorderRadius.circular(4),
                  border: Border.all(
                    color: colors.border,
                    strokeAlign: BorderSide.strokeAlignInside,
                  ),
                ),
                child: Center(
                  child: Icon(
                    Icons.image_outlined,
                    size: 24,
                    color: colors.textPlaceholder,
                  ),
                ),
              );
            }).toList(),
          ),
      ],
    );
  }

  Widget _buildComplianceSection(
    ExpenseModel expense,
    AppLocalizations l10n,
    AppColorsExtension colors,
  ) {
    final checks = [
      l10n.get('invoiceCheck1'),
      l10n.get('invoiceCheck2'),
      l10n.get('invoiceCheck3'),
      l10n.get('invoiceCheck4'),
    ];

    return FormSection(
      title: l10n.get('invoiceCheck'),
      children: checks.map((text) {
        return SizedBox(
          height: 44,
          child: Row(
            children: [
              Icon(Icons.check_circle, size: 16, color: colors.success),
              const SizedBox(width: 8),
              Text(
                text,
                style: TextStyle(
                  fontSize: AppFontSizes.body,
                  color: colors.textPrimary,
                ),
              ),
            ],
          ),
        );
      }).toList(),
    );
  }

  Widget _buildApprovalSection(ExpenseModel expense, AppLocalizations l10n) {
    return FormSection(
      title: l10n.get('approvalFlow'),
      children: [
        ApprovalTimeline(
          records: expense.approvalRecords,
          chain: expense.approvalChain,
          currentApproverId: expense.currentApproverId,
        ),
      ],
    );
  }

  Widget _buildArchiveSection(ExpenseModel expense, AppLocalizations l10n) {
    return FormSection(
      title: l10n.get('financialArchive'),
      children: [
        FormFieldRow(
          label: l10n.get('voucherNo'),
          value: expense.voucherNo.isNotEmpty ? expense.voucherNo : null,
          hint: '-',
          readOnly: true,
          showArrow: false,
        ),
        FormFieldRow(
          label: l10n.get('archiveDate'),
          value: du.DateUtils.formatDate(expense.updateTime),
          readOnly: true,
          showArrow: false,
        ),
        FormFieldRow(
          label: l10n.get('archiver'),
          value: l10n.get('financeDept'),
          readOnly: true,
          showArrow: false,
        ),
      ],
    );
  }

  Widget _buildBottomBar(BuildContext context, ExpenseModel expense) {
    final l10n = AppLocalizations.of(context);
    final canWithdraw =
        expense.status == 'pending' || expense.status == 'draft';

    if (!canWithdraw) {
      return const SizedBox.shrink();
    }

    return ActionBar(
      showLeft: false,
      centerLabel: l10n.get('withdrawApplication'),
      rightLabel: l10n.get('submitApproval'),
      onCenterTap: () {
        TDToast.showText(l10n.get('withdrawn'), context: context);
        context.pop();
      },
      onRightTap: null,
    );
  }
}
