import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import 'package:easy_refresh/easy_refresh.dart';
import '../../shared/widgets/nav_bar_config.dart';
import '../../core/theme/app_colors_extension.dart';
import '../../core/utils/date_utils.dart' as du;
import '../../core/utils/responsive.dart';
import '../../shared/widgets/list_card.dart';
import '../../shared/widgets/empty_state.dart';
import '../../shared/widgets/skeleton_list_card.dart';
import '../../shared/widgets/list_footer.dart';
import '../../core/i18n/app_localizations.dart';
import 'expense_apply_list_controller.dart';
import 'expense_apply_model.dart';
import 'expense_apply_approval_api.dart';
class ExpenseApplyListPage extends ConsumerStatefulWidget {
  const ExpenseApplyListPage({super.key});
  @override
  ConsumerState<ExpenseApplyListPage> createState() => _ExpenseApplyListPageState();
}

class _ExpenseApplyListPageState extends ConsumerState<ExpenseApplyListPage>
    with WidgetsBindingObserver {
  final _keywordCtrl = TextEditingController();
  final _startDateCtrl = TextEditingController();
  final _endDateCtrl = TextEditingController();
  late final EasyRefreshController _refreshCtrl;

  @override
  void initState() {
    super.initState();
    final now = DateTime.now();
    _startDateCtrl.text = '${now.year}-${now.month.toString().padLeft(2, '0')}-01';
    _endDateCtrl.text = '${now.year}-${now.month.toString().padLeft(2, '0')}-${DateTime(now.year, now.month + 1, 0).day.toString().padLeft(2, '0')}';
    _refreshCtrl = EasyRefreshController();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      ref.read(expenseApplyDateStartProvider.notifier).state = DateTime(now.year, now.month, 1);
      ref.read(expenseApplyDateEndProvider.notifier).state = DateTime(now.year, now.month, DateTime(now.year, now.month + 1, 0).day);
    });
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      _keywordCtrl.clear();
      final now = DateTime.now();
      _startDateCtrl.text = '${now.year}-${now.month.toString().padLeft(2, '0')}-01';
      _endDateCtrl.text = '${now.year}-${now.month.toString().padLeft(2, '0')}-${DateTime(now.year, now.month + 1, 0).day.toString().padLeft(2, '0')}';
      ref.read(expenseApplyKeywordProvider.notifier).state = '';
      ref.read(expenseApplyDateStartProvider.notifier).state = DateTime(now.year, now.month, 1);
      ref.read(expenseApplyDateEndProvider.notifier).state = DateTime(now.year, now.month, DateTime(now.year, now.month + 1, 0).day);
      ref.read(expenseApplyRefreshProvider.notifier).state++;
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _keywordCtrl.dispose();
    _startDateCtrl.dispose();
    _endDateCtrl.dispose();
    _refreshCtrl.dispose();
    super.dispose();
  }

  void _pickDate(TextEditingController ctrl) {
    final l10n = AppLocalizations.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final now = DateTime.now();
    TDPicker.showDatePicker(
      context, title: l10n.get('selectDate'), backgroundColor: colors.bgCard,
      useYear: true, useMonth: true, useDay: true, useHour: false, useMinute: false, useSecond: false, useWeekDay: false,
      dateStart: const [2020, 1, 1], dateEnd: [now.year + 1, 12, 31], initialDate: [now.year, now.month, now.day],
      onConfirm: (selected) {
        ctrl.text = '${selected['year']}-${selected['month'].toString().padLeft(2, '0')}-${selected['day'].toString().padLeft(2, '0')}';
        setState(() {});
        Navigator.of(context).pop();
      },
    );
  }

  void _applyFilter() {
    ref.read(expenseApplyKeywordProvider.notifier).state = _keywordCtrl.text.trim();
    ref.read(expenseApplyDateStartProvider.notifier).state = _startDateCtrl.text.isNotEmpty ? DateTime.tryParse(_startDateCtrl.text) : null;
    ref.read(expenseApplyDateEndProvider.notifier).state = _endDateCtrl.text.isNotEmpty ? DateTime.tryParse(_endDateCtrl.text) : null;
    _refreshCtrl.callRefresh();
  }

  Widget _dateChip(TextEditingController ctrl, String hint, TDThemeData tdTheme, AppColorsExtension colors) {
    final text = ctrl.text;
    return Container(
      height: 40, padding: const EdgeInsets.symmetric(horizontal: 16),
      decoration: BoxDecoration(color: colors.bgSecondaryContainer, borderRadius: BorderRadius.circular(20), border: Border.all(color: tdTheme.componentStrokeColor)),
      child: Row(children: [
        Icon(Icons.calendar_today, size: 16, color: colors.textSecondary), const SizedBox(width: 8),
        Expanded(child: Text(text.isNotEmpty ? text : hint, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 14, color: text.isNotEmpty ? colors.textPrimary : colors.textSecondary))),
        if (text.isNotEmpty) GestureDetector(onTap: () { ctrl.clear(); setState(() {}); }, child: Icon(Icons.close, size: 18, color: colors.textSecondary)),
      ]),
    );
  }

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final tdTheme = TDTheme.of(context);

    setNavBarTitle(context, ref, NavBarConfig(title: l10n.get('expenseApplyList'), showBack: true, onBack: () => SystemNavigator.pop()));
    return Column(children: [
      Container(
        color: colors.bgCard,
        child: Column(mainAxisSize: MainAxisSize.min, children: [
          Padding(padding: const EdgeInsets.fromLTRB(12, 8, 12, 0), child: Row(children: [
            Expanded(child: GestureDetector(onTap: () => _pickDate(_startDateCtrl), child: _dateChip(_startDateCtrl, l10n.get('filterStartDate'), tdTheme, colors))),
            const SizedBox(width: 8), Text('—', style: TextStyle(fontSize: 14, color: colors.textSecondary)), const SizedBox(width: 8),
            Expanded(child: GestureDetector(onTap: () => _pickDate(_endDateCtrl), child: _dateChip(_endDateCtrl, l10n.get('filterEndDate'), tdTheme, colors))),
          ])),
          const SizedBox(height: 8),
          Padding(padding: const EdgeInsets.fromLTRB(12, 0, 12, 8), child: Row(children: [
            Expanded(
              child: Container(
                height: 40, padding: const EdgeInsets.symmetric(horizontal: 16),
                decoration: BoxDecoration(color: colors.bgSecondaryContainer, borderRadius: BorderRadius.circular(20), border: Border.all(color: tdTheme.componentStrokeColor)),
                child: Row(children: [
                  Expanded(child: TextField(controller: _keywordCtrl, style: TextStyle(fontSize: 14, color: colors.textPrimary), decoration: InputDecoration(hintText: l10n.get('searchExpenseApply'), hintStyle: TextStyle(fontSize: 14, color: colors.textSecondary), border: InputBorder.none, isCollapsed: true), onChanged: (_) => setState(() {}))),
                  if (_keywordCtrl.text.isNotEmpty) GestureDetector(onTap: () { _keywordCtrl.clear(); setState(() {}); _applyFilter(); }, child: Icon(Icons.close, size: 18, color: colors.textSecondary)),
                ]),
              ),
            ),
            const SizedBox(width: 8),
            GestureDetector(
              onTap: () {
                final dir = ref.read(expenseApplySortDirProvider);
                ref.read(expenseApplySortDirProvider.notifier).state = dir == 'ASC' ? 'DESC' : 'ASC';
                _applyFilter();
              },
              child: Container(width: 40, height: 40, decoration: BoxDecoration(color: colors.primary, borderRadius: BorderRadius.circular(20)), child: Center(child: Icon(ref.watch(expenseApplySortDirProvider) == 'ASC' ? Icons.arrow_upward : Icons.arrow_downward, color: Colors.white, size: 20))),
            ),
            const SizedBox(width: 8),
            GestureDetector(onTap: _applyFilter, child: Container(width: 40, height: 40, decoration: BoxDecoration(color: colors.primary, borderRadius: BorderRadius.circular(20)), child: const Icon(Icons.search, color: Colors.white, size: 22))),
          ])),
        ]),
      ),
      Expanded(child: Container(color: colors.bgPage, child: _ExpenseApplyListContent(refreshCtrl: _refreshCtrl))),
    ]);
  }
}

class _ExpenseApplyListContent extends ConsumerWidget {
  final EasyRefreshController refreshCtrl;
  const _ExpenseApplyListContent({required this.refreshCtrl});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final r = ResponsiveHelper.of(context);
    final itemsAsync = ref.watch(expenseApplyMyListProvider(''));
    if (itemsAsync.isLoading && !itemsAsync.hasValue) return Center(child: ConstrainedBox(constraints: BoxConstraints(maxWidth: r.listMaxWidth), child: const SkeletonLoadingList()));
    return Center(child: ConstrainedBox(constraints: BoxConstraints(maxWidth: r.listMaxWidth), child: EasyRefresh(controller: refreshCtrl, header: TDRefreshHeader(), onRefresh: () async { ref.read(expenseApplyRefreshProvider.notifier).state++; }, child: _buildContent(itemsAsync, context, ref))));
  }

  Widget _buildContent(AsyncValue<List<ExpenseApplyModel>> itemsAsync, BuildContext context, WidgetRef ref) {
    final l10n = AppLocalizations.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    if (itemsAsync.isReloading) {
      final oldItems = itemsAsync.valueOrNull ?? [];
      if (oldItems.isEmpty) return ListView(children: [const SizedBox(height: 120), EmptyState(message: l10n.get('noExpenseApplications'))]);
      return ListView.builder(padding: const EdgeInsets.fromLTRB(16, 16, 16, 24), itemCount: oldItems.length, itemBuilder: (_, i) {
        final m = oldItems[i];
        final card = ListCard(
          cardNo: m.expenseApplyNo, amount: '¥${m.estimatedAmount.toStringAsFixed(2)}',
          applicant: m.deptName.isNotEmpty ? '${m.applicantName} · ${m.deptName}' : m.applicantName,
          description: m.remark.isNotEmpty ? '${m.purpose}\n${l10n.get('remark')}: ${m.remark}' : m.purpose,
          date: du.DateUtils.formatDate(m.createTime),
          statusTag: _buildUrgencyChip(m.urgency, l10n, colors),
          onTap: () { context.push('/expense-apply/detail/${m.expenseApplyNo}'); },
        );
        return Padding(padding: const EdgeInsets.only(bottom: 16), child: card);
      });
    }
    if (itemsAsync.hasError) return ListView(children: [const SizedBox(height: 120), EmptyState(message: l10n.get('loadFailed'))]);
    final items = itemsAsync.requireValue;
    if (items.isEmpty) return ListView(children: [const SizedBox(height: 120), EmptyState(message: l10n.get('noExpenseApplications'))]);
    return ListView.builder(padding: const EdgeInsets.fromLTRB(16, 16, 16, 24), itemCount: items.length + 1, itemBuilder: (_, i) {
      if (i == items.length) return ListFooter(itemCount: items.length);
      final m = items[i];
      final card = ListCard(
        cardNo: m.expenseApplyNo, amount: '¥${m.estimatedAmount.toStringAsFixed(2)}',
        applicant: m.deptName.isNotEmpty ? '${m.applicantName} · ${m.deptName}' : m.applicantName,
        description: m.remark.isNotEmpty ? '${m.purpose}\n${l10n.get('remark')}: ${m.remark}' : m.purpose,
        date: du.DateUtils.formatDate(m.createTime),
        statusTag: _buildUrgencyChip(m.urgency, l10n, colors),
        onTap: () { context.push('/expense-apply/detail/${m.expenseApplyNo}'); },
      );
      return Padding(padding: const EdgeInsets.only(bottom: 16), child: card);
    });
  }

  Widget _buildUrgencyChip(String urgency, AppLocalizations l10n, AppColorsExtension colors) {
    // 与费用申请单创建页保持一致: critical→danger, urgent→warning, normal→primary
    final (label, color) = switch (urgency) {
      '3' || 'critical' => (l10n.get('critical'), colors.danger),
      '2' || 'urgent' => (l10n.get('urgent'), colors.warning),
      _ => (l10n.get('normal'), colors.primary),
    };
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 1),
      decoration: BoxDecoration(
        color: color.withValues(alpha: 0.1),
        borderRadius: BorderRadius.circular(4),
        border: Border.all(color: color, width: 0.5),
      ),
      child: Text(label, style: TextStyle(fontSize: 11, fontWeight: FontWeight.w500, color: color)),
    );
  }
}
