import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:nhance_partner/presentation/screens/Enquiry/policy_claims_endros/add_claim_stepper_dialog.dart';
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';

import '../../../../core/services/api_service.dart';
import '../../../../data/utils/Pagination.dart';
import '../../../../data/utils/toastNotification.dart';
import '../../../layouts/main_layout.dart';
import '../../../layouts/responsive_layout.dart';
import '../../../providers/manager_provider.dart';
import '../../../themes/indicators/date_range_picker_field.dart';
import '../../../themes/indicators/export_btn.dart';
import '../../../themes/indicators/search_field_theme.dart';

class claimList extends ConsumerStatefulWidget {
  const claimList({super.key});

  @override
  ConsumerState<claimList> createState() => claimListState();
}

class claimListState extends ConsumerState<claimList> {
  static const Color _teal = Color(0xFF14A492);
  static const Color _surfaceGrey = Color(0xFFF1F5F9);
  static const Color _border = Color(0xFFE2E8F0);
  static const Color _muted = Color(0xFF64748B);
  static const Color _filterFocusTeal = Color(0xFF50A398);
  static const Color _actionDownloadBlue = Color(0xFF1565C0);

  int currentPage = 1;
  int itemsPerPage = 10;
  late ApiService apiService;

  List<Map<String, dynamic>> getStaffData = [];
  List<Map<String, dynamic>> originalData = [];
  List<Map<String, dynamic>> filteredData = [];
  bool isLoading = false;

  final TextEditingController _quickSearchController = TextEditingController();
  final TextEditingController _startDateController = TextEditingController();
  final TextEditingController _endDateController = TextEditingController();
  final ScrollController _tableVScrollController = ScrollController();

  dynamic userId;
  dynamic roleId;
  dynamic managerId;

  // bool _pendingTab = true;

  List<Map<String, dynamic>> _masterClaimTypeMaps = [];
  List<Map<String, dynamic>> _masterInsurerMaps = [];
  List<Map<String, dynamic>> _masterClaimStatusMaps = [];

  String? _filterClaimType;
  String? _filterInsurer;
  /// Selected claim status master id (stored in filter choice `v`).
  String? _filterStatus;

  @override
  void initState() {
    super.initState();

    apiService = ApiService();

    Future.microtask(() {
      managerId = ref.read(managerIdProvider);
      roleId = ref.read(userRoleProvider);
      userId = ref.read(userIdProvider);

      if (userId != null) {
        loadClaimsList();
      }
      _loadFilterMasters();
    });
  }

  Future<void> _loadFilterMasters() async {
    try {
      final claimR = await apiService.fetchMasterDropDown('Claim');
      if ((claimR['status'] == 'success' || claimR['status'] == 200) &&
          claimR['data'] is List) {
        if (mounted) {
          setState(() {
            _masterClaimTypeMaps =
                List<Map<String, dynamic>>.from(claimR['data']);
          });
        }
      }
      final insR = await apiService.fetchMasterDropDown('Insurers');
      if ((insR['status'] == 'success' || insR['status'] == 200) &&
          insR['data'] is List) {
        if (mounted) {
          setState(() {
            _masterInsurerMaps =
                List<Map<String, dynamic>>.from(insR['data']);
          });
        }
      }
      final statusR = await apiService.fetchClaimStatusList();
      if ((statusR['status'] == 'success' || statusR['status'] == 200) &&
          statusR['data'] is List &&
          (statusR['data'] as List).isNotEmpty) {
        if (mounted) {
          setState(() {
            _masterClaimStatusMaps =
                List<Map<String, dynamic>>.from(statusR['data']);
          });
        }
      }
    } catch (_) {}
  }

  @override
  void dispose() {
    _quickSearchController.dispose();
    _startDateController.dispose();
    _endDateController.dispose();
    _tableVScrollController.dispose();
    super.dispose();
  }

  String? _apiDateFromPicker(String text) {
    final t = text.trim();
    if (t.isEmpty) return null;
    try {
      final d = DateRangePickerField.storageFormat.parse(t);
      return DateFormat('yyyy-MM-dd').format(d);
    } catch (_) {
      return null;
    }
  }

  int? _claimTypeIdForFilter() {
    if (_filterClaimType == null || _filterClaimType!.trim().isEmpty) {
      return null;
    }
    return int.tryParse(_filterClaimType!.trim());
  }

  int? _insurerIdForFilter() {
    if (_filterInsurer == null || _filterInsurer!.trim().isEmpty) return null;
    return int.tryParse(_filterInsurer!.trim());
  }

  int? _claimStatusIdForFilter() {
    if (_filterStatus == null || _filterStatus!.trim().isEmpty) return null;
    return int.tryParse(_filterStatus!.trim());
  }

  Future<void> loadClaimsList() async {
    if (!mounted) return;
    setState(() => isLoading = true);

    try {
      final role = roleId?.toString().toLowerCase() ?? '';
      final mid = int.tryParse(managerId?.toString() ?? '');
      final uid = int.tryParse(userId?.toString() ?? '');

      final response = await apiService.fetchClaims(
        managerId: (role == 'manager' || role == 'accounts') ? mid : null,
        agentId: role == 'agent' ? uid : null,
        handlerId: role == 'handler' ? uid : null,
        staffId: (role != 'manager' &&
                role != 'accounts' &&
                role != 'agent' &&
                role != 'handler')
            ? uid
            : null,
        claimTypeId: _claimTypeIdForFilter(),
        claimStatusId: _claimStatusIdForFilter(),
        insurerId: _insurerIdForFilter(),
        fromDate: _apiDateFromPicker(_startDateController.text),
        toDate: _apiDateFromPicker(_endDateController.text),
      );

      if (!mounted) return;

      if (response['status'] == 'success' ||
          response['status'] == 200 ||
          response['status'] == '200') {
        final data = response['data'];
        setState(() {
          if (data is List) {
            getStaffData = data
                .whereType<Map>()
                .map((e) => Map<String, dynamic>.from(e))
                .toList();
          } else if (data is Map) {
            getStaffData = [Map<String, dynamic>.from(data)];
          } else {
            getStaffData = [];
          }
          originalData = List<Map<String, dynamic>>.from(getStaffData);
          _rebuildFiltered();
        });
      } else {
        setState(() {
          getStaffData = [];
          originalData = [];
          filteredData = [];
        });
      }
    } catch (e) {
      debugPrint('Claims list error: $e');
      if (mounted) {
        setState(() {
          getStaffData = [];
          originalData = [];
          filteredData = [];
        });
      }
    } finally {
      if (mounted) setState(() => isLoading = false);
    }
  }

  static String _pickStr(Map<String, dynamic> row, List<String> keys) {
    for (final k in keys) {
      final v = row[k];
      if (v != null && v.toString().trim().isNotEmpty) {
        return v.toString();
      }
    }
    return '-';
  }

  // bool _isSettled(Map<String, dynamic> item) {
  //   final raw = _pickStr(item, ['claim_status_id']);
  //   final id = int.tryParse(raw);
  //   return id == 65;
  // }

  // bool _matchesTab(Map<String, dynamic> item) {
  //   return _pendingTab ? !_isSettled(item) : _isSettled(item);
  // }

  DateTime? _parseCreated(Map<String, dynamic> item) {
    final raw = _pickStr(item, [
      'created_at',
      'created_date',
      'created_on',
      'inserted_at',
    ]);
    if (raw == '-') return null;
    try {
      return DateTime.parse(raw);
    } catch (_) {
      return null;
    }
  }

  void _addSearchText(List<String> out, String? value) {
    if (value == null) return;
    final s = value.trim();
    if (s.isEmpty || s == '-') return;
    out.add(s);
  }

  void _addSearchDate(List<String> out, Map<String, dynamic> item, List<String> keys) {
    final raw = _pickStr(item, keys);
    if (raw == '-') return;
    _addSearchText(out, raw);
    _addSearchText(out, _formatDate(raw));
  }

  List<String> _searchableTexts(Map<String, dynamic> item) {
    final texts = <String>[];

    for (final value in item.values) {
      _addSearchText(texts, value?.toString());
    }

    _addSearchText(texts, _pickStr(item, ['policy_no', 'policy_number']));
    _addSearchText(texts, _pickStr(item, ['claim_number']));
    _addSearchText(texts, _pickStr(item, ['broker_name', 'broker']));
    _addSearchText(
      texts,
      _pickStr(item, ['agent_name', 'partner_name', 'partner']),
    );
    _addSearchDate(texts, item, [
      'date_of_incident',
      'accident_date',
      'accident_datetime',
      'date_of_accident',
    ]);
    _addSearchDate(texts, item, [
      'created_at',
      'created_date',
      'created_on',
      'inserted_at',
    ]);

    return texts;
  }

  bool _matchesQuickSearch(Map<String, dynamic> item, String query) {
    if (query.isEmpty) return true;
    final q = query.toLowerCase();
    return _searchableTexts(item).any((t) => t.toLowerCase().contains(q));
  }

  void _rebuildFiltered() {
    final q = _quickSearchController.text.trim();
    filteredData = originalData.where((item) {
      return _matchesQuickSearch(item, q);
    }).toList();
  }

  void _applyFilterBar() {
    setState(() => currentPage = 1);
    loadClaimsList();
  }

  void _onQuickSearch(String _) {
    setState(() {
      _rebuildFiltered();
      currentPage = 1;
    });
  }

  // void _setTab(bool pending) {
  //   if (_pendingTab == pending) return;
  //   setState(() {
  //     _pendingTab = pending;
  //     _rebuildFiltered();
  //     currentPage = 1;
  //   });
  // }

  // int get _pendingCount =>
  //     originalData.where((e) => !_isSettled(e)).length;

  // int get _settledCount => originalData.where(_isSettled).length;

  bool get _canShowDeleteAction {
    final role = roleId?.toString().trim().toLowerCase() ?? '';
    return role == 'manager' || role == 'accounts' || role == 'account';
  }

  void _confirmDelete(BuildContext context, String id) {
    showDialog(
      context: context,
      builder: (ctx) => AlertDialog(
        backgroundColor: Colors.white,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
        title: Row(
          children: [
            Icon(Icons.warning_amber_rounded, color: Colors.red.shade600, size: 22),
            const SizedBox(width: 8),
            Text(
              'Delete Claim',
              style: GoogleFonts.poppins(fontSize: 15, fontWeight: FontWeight.w600),
            ),
          ],
        ),
        content: Text(
          'Are you sure you want to delete this claim?\nThis action cannot be undone.',
          style: GoogleFonts.poppins(fontSize: 13, color: Colors.grey.shade700),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(ctx),
            child: Text(
              'Cancel',
              style: GoogleFonts.poppins(fontSize: 13, color: Colors.grey.shade600),
            ),
          ),
          ElevatedButton(
            style: ElevatedButton.styleFrom(
              backgroundColor: Colors.red.shade600,
              shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
            ),
            onPressed: () async {
              Navigator.pop(ctx);
              await _deleteClaim(id);
            },
            child: Text(
              'Delete',
              style: GoogleFonts.poppins(fontSize: 13, color: Colors.white),
            ),
          ),
        ],
      ),
    );
  }

  Future<void> _deleteClaim(String id) async {
    if (id.isEmpty || id == '-') {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(
            'Invalid claim id.',
            style: GoogleFonts.poppins(fontSize: 13),
          ),
          backgroundColor: Colors.red.shade600,
          behavior: SnackBarBehavior.floating,
        ),
      );
      return;
    }

    final updatedBy = userId?.toString().trim();
    if (updatedBy == null || updatedBy.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(
            'User id not available.',
            style: GoogleFonts.poppins(fontSize: 13),
          ),
          backgroundColor: Colors.red.shade600,
          behavior: SnackBarBehavior.floating,
        ),
      );
      return;
    }

    try {
      setState(() => isLoading = true);

      final response = await apiService.deleteClaim(
        id: id,
        updatedBy: updatedBy,
      );

      if (response['status'] == 'success' || response['code'] == 200) {
        refresh();
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text(
              'Claim deleted successfully.',
              style: GoogleFonts.poppins(fontSize: 13),
            ),
            backgroundColor: Colors.green.shade600,
            behavior: SnackBarBehavior.floating,
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
            duration: const Duration(seconds: 2),
          ),
        );
      } else {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text(
              response['message']?.toString() ?? 'Failed to delete claim.',
              style: GoogleFonts.poppins(fontSize: 13),
            ),
            backgroundColor: Colors.red.shade600,
            behavior: SnackBarBehavior.floating,
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
            duration: const Duration(seconds: 2),
          ),
        );
      }
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('Error: $e', style: GoogleFonts.poppins(fontSize: 13)),
          backgroundColor: Colors.red.shade600,
          behavior: SnackBarBehavior.floating,
        ),
      );
    } finally {
      if (mounted) setState(() => isLoading = false);
    }
  }

  List<String> _uniqueFrom(String Function(Map<String, dynamic>) pick) {
    final s = <String>{};
    for (final r in originalData) {
      final v = pick(r);
      if (v != '-') s.add(v);
    }
    return s.toList()..sort();
  }

  List<Map<String, dynamic>> get _paginatedSorted {
    final sorted = [...filteredData]
      ..sort((a, b) {
        final ida = int.tryParse(_pickStr(a, ['id'])) ?? 0;
        final idb = int.tryParse(_pickStr(b, ['id'])) ?? 0;
        return idb.compareTo(ida);
      });
    if (sorted.isEmpty) return [];
    final maxPage = (sorted.length / itemsPerPage).ceil();
    final safePage = currentPage.clamp(1, maxPage);
    final start = (safePage - 1) * itemsPerPage;
    final end = (start + itemsPerPage).clamp(0, sorted.length);
    return sorted.sublist(start, end);
  }

  DateTime? _parseClaimDateTime(String raw) {
    final t = raw.trim();
    if (t.isEmpty || t == '-') return null;
    final patterns = <DateFormat>[
      DateFormat('dd-MM-yyyy hh:mm a'),
      DateFormat('dd-MM-yyyy HH:mm'),
      DateFormat('dd-MM-yyyy'),
      DateFormat('yyyy-MM-dd HH:mm:ss'),
      DateFormat('yyyy-MM-dd'),
    ];
    for (final p in patterns) {
      try {
        return p.parse(t);
      } catch (_) {}
    }
    try {
      return DateTime.parse(t);
    } catch (_) {
      return null;
    }
  }

  String _formatDate(String rawDate) {
    final dt = _parseClaimDateTime(rawDate);
    if (dt != null) return DateFormat('dd-MM-yyyy').format(dt);
    return rawDate;
  }

  String _formatDateTime(String raw) {
    final dt = _parseClaimDateTime(raw);
    if (dt != null) {
      return DateFormat('dd-MM-yyyy, hh:mm a').format(dt);
    }
    return raw;
  }

  void refresh() {
    loadClaimsList();
  }

  void _clearFilters() {
    setState(() {
      _startDateController.clear();
      _endDateController.clear();
      _filterClaimType = null;
      _filterInsurer = null;
      _filterStatus = null;
      _quickSearchController.clear();
      currentPage = 1;
    });
    loadClaimsList();
  }

  InputDecoration _filterDropdownDecoration(String hintText) {
    return InputDecoration(
      isDense: true,
      hintText: hintText,
      hintStyle: GoogleFonts.inter(fontSize: 11, color: const Color(0xFF94A3B8)),
      filled: true,
      fillColor: Colors.white,
      contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
      border: OutlineInputBorder(
        borderRadius: BorderRadius.circular(8),
        borderSide: const BorderSide(color: _border),
      ),
      enabledBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(8),
        borderSide: const BorderSide(color: _border),
      ),
      focusedBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(8),
        borderSide: const BorderSide(color: _filterFocusTeal, width: 1.5),
      ),
    );
  }

  Map<String, dynamic> _filterAllItem(String label) => {
        'v': '',
        'label': label,
        'sub': '',
      };

  Map<String, dynamic> _findSelectedChoice(
    List<Map<String, dynamic>> choices,
    String? value,
  ) {
    final v = value ?? '';
    for (final c in choices) {
      if ((c['v']?.toString() ?? '') == v) return c;
    }
    return choices.isNotEmpty ? choices.first : _filterAllItem('');
  }

  List<Map<String, dynamic>> _claimTypeFilterChoices(List<String> fromData) {
    final byId = <String, Map<String, dynamic>>{};
    for (final m in _masterClaimTypeMaps) {
      final id = (m['id'] ?? '').toString().trim();
      final label = (m['claim_type'] ?? '').toString().trim();
      if (id.isEmpty || label.isEmpty) continue;
      byId[id] = {'v': id, 'label': label, 'sub': ''};
    }
    for (final label in fromData) {
      if (label.isEmpty) continue;
      if (byId.values.any((c) => (c['label'] as String) == label)) continue;
      for (final row in originalData) {
        if (_pickStr(row, ['claim_type_value']) == label) {
          final id = (row['claim_type_id'] ?? '').toString().trim();
          if (id.isNotEmpty) byId[id] = {'v': id, 'label': label, 'sub': ''};
          break;
        }
      }
    }
    final list = byId.values.toList()
      ..sort((a, b) => (a['label'] as String).compareTo(b['label'] as String));
    return [_filterAllItem('Claim type'), ...list];
  }

  List<Map<String, dynamic>> _statusFilterChoices(List<String> fromData) {
    final byId = <String, Map<String, dynamic>>{};

    void addStatus(String? id, String label) {
      final idStr = id?.toString().trim() ?? '';
      final lab = label.trim();
      if (idStr.isEmpty || lab.isEmpty || lab == '-') return;
      byId[idStr] = {'v': idStr, 'label': lab, 'sub': ''};
    }

    for (final m in _masterClaimStatusMaps) {
      addStatus(
        m['id']?.toString(),
        (m['claim_status'] ??
                m['status'] ??
                m['name'] ??
                m['claim_status_value'] ??
                m['status_name'] ??
                '')
            .toString(),
      );
    }

    for (final row in originalData) {
      addStatus(
        row['claim_status_id']?.toString(),
        _pickStr(row, ['claim_status_value']),
      );
    }

    for (final label in fromData) {
      if (label.isEmpty) continue;
      if (byId.values.any((c) => (c['label'] as String) == label)) continue;
      for (final row in originalData) {
        if (_pickStr(row, ['claim_status_value']) == label) {
          addStatus(row['claim_status_id']?.toString(), label);
          break;
        }
      }
    }

    final list = byId.values.toList()
      ..sort((a, b) => (a['label'] as String).compareTo(b['label'] as String));
    return [_filterAllItem('Status'), ...list];
  }

  List<Map<String, dynamic>> _insurerFilterChoices(List<String> fromData) {
    final byId = <String, Map<String, dynamic>>{};
    for (final m in _masterInsurerMaps) {
      final id = (m['id'] ?? '').toString().trim();
      final label = (m['insurer_short_name'] ??
              m['insurer_name'] ??
              m['name'] ??
              '')
          .toString()
          .trim();
      if (id.isEmpty || label.isEmpty) continue;
      byId[id] = {'v': id, 'label': label, 'sub': ''};
    }
    for (final label in fromData) {
      if (label.isEmpty) continue;
      if (byId.values.any((c) => (c['label'] as String) == label)) continue;
      for (final row in originalData) {
        if (_pickStr(row, ['insurer_short_name']) == label) {
          final id = (row['insurer_id'] ?? '').toString().trim();
          if (id.isNotEmpty) byId[id] = {'v': id, 'label': label, 'sub': ''};
          break;
        }
      }
    }
    final list = byId.values.toList()
      ..sort((a, b) => (a['label'] as String).compareTo(b['label'] as String));
    return [_filterAllItem('Select Insurer'), ...list];
  }

  InputDecoration _popupSearchDecoration(String hint) {
    return InputDecoration(
      filled: true,
      fillColor: Colors.white,
      hintText: hint,
      hintStyle: GoogleFonts.inter(fontSize: 12, color: const Color(0xFF94A3B8)),
      isDense: true,
      contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
      border: OutlineInputBorder(
        borderRadius: BorderRadius.circular(8),
        borderSide: const BorderSide(color: _border),
      ),
      enabledBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(8),
        borderSide: const BorderSide(color: _border),
      ),
      focusedBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(8),
        borderSide: const BorderSide(color: _filterFocusTeal, width: 1.5),
      ),
    );
  }

  Widget _buildFilterDropdownSearch({
    required double width,
    String? placeholder,
    required String? selectedValue,
    required List<Map<String, dynamic>> choices,
    required void Function(String?) onChanged,
    bool twoLineItems = false,
  }) {
    final hint = placeholder ??
        (choices.isNotEmpty
            ? (choices.first['label'] ?? '').toString()
            : '');
    final selected = _findSelectedChoice(choices, selectedValue);

    return SizedBox(
      height: 38,
      width: width,
      child: DropdownSearch<Map<String, dynamic>>(
        selectedItem: selected,
        items: (filter, infiniteScrollProps) => choices,
        itemAsString: (m) {
          final label = (m['label'] ?? '').toString();
          final sub = (m['sub'] ?? '').toString();
          if (twoLineItems && sub.isNotEmpty) return '$label $sub';
          return label;
        },
        compareFn: (a, b) =>
            (a['v']?.toString() ?? '') == (b['v']?.toString() ?? ''),
        decoratorProps: DropDownDecoratorProps(
          decoration: _filterDropdownDecoration(hint),
        ),
        dropdownBuilder: (context, selectedItem) {
          final m = selectedItem ?? _filterAllItem(hint);
          final isAll = (m['v']?.toString() ?? '').isEmpty;
          final label = (m['label'] ?? hint).toString();
          return Align(
            alignment: Alignment.centerLeft,
            child: Text(
              label,
              style: GoogleFonts.inter(
                fontSize: 11,
                color: isAll
                    ? const Color(0xFF94A3B8)
                    : const Color(0xFF334155),
              ),
              overflow: TextOverflow.ellipsis,
              maxLines: 1,
            ),
          );
        },
        popupProps: PopupProps.menu(
          showSearchBox: true,
          fit: FlexFit.loose,
          constraints: const BoxConstraints(maxHeight: 280),
          menuProps: MenuProps(
            backgroundColor: Colors.white,
            elevation: 8,
            borderRadius: BorderRadius.circular(8),
          ),
          searchFieldProps: TextFieldProps(
            decoration: _popupSearchDecoration('Search'),
          ),
          itemBuilder: (context, item, isDisabled, isSelected) {
            final isAll = (item['v']?.toString() ?? '').isEmpty;
            if (isAll) return const SizedBox.shrink();

            final label = (item['label'] ?? '').toString();
            final sub = (item['sub'] ?? '').toString();
            final showTwoLine =
                twoLineItems && !isAll && sub.isNotEmpty;

            return Container(
              color: isSelected ? const Color(0xFFF1F5F9) : null,
              child: Padding(
                padding:
                    const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
                child: showTwoLine
                        ? Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              Text(
                                label.toUpperCase(),
                                style: GoogleFonts.inter(
                                  fontSize: 12,
                                  fontWeight: FontWeight.w700,
                                  color: const Color(0xFF0F172A),
                                ),
                                maxLines: 2,
                                overflow: TextOverflow.ellipsis,
                              ),
                              if (sub.isNotEmpty) ...[
                                const SizedBox(height: 2),
                                Text(
                                  sub,
                                  style: GoogleFonts.inter(
                                    fontSize: 10,
                                    color: const Color(0xFF94A3B8),
                                  ),
                                ),
                              ],
                            ],
                          )
                        : Text(
                            label,
                            style: GoogleFonts.inter(
                              fontSize: 12,
                              fontWeight: FontWeight.w500,
                              color: const Color(0xFF0F172A),
                            ),
                          ),
              ),
            );
          },
        ),
        onChanged: (val) {
          final v = val?['v']?.toString() ?? '';
          onChanged(v.isEmpty ? null : v);
        },
      ),
    );
  }

  Map<String, dynamic> get _exportConfig => {
        'displayHeaders': const [
          'S No',
          'Created Date',
          'Claim Type',
          'Vehicle No',
          'Insured Name',
          'Policy Number',
          'Claim Number',
          'Accident Date',
          'Insurer',
          'Broker',
          'Partner',
          'Remarks',
          'Status',
          'Pending Days',
        ],
        'keys': const [
          'sno',
          'created_at',
          'claim_type_value',
          'reg_no',
          'insured_name',
          'policy_no',
          'claim_number',
          'accident_date',
          'insurer_short_name',
          'broker',
          'partner',
          'remark',
          'claim_status_value',
          'pending_days',
        ],
        'valueFormatters': {
          'created_at': (dynamic v, Map<String, dynamic> row) {
            final raw = _pickStr(row, [
              'created_at',
              'created_date',
              'created_on',
            ]);
            if (raw == '-') return '-';
            return _formatDate(raw);
          },
          'accident_date': (dynamic v, Map<String, dynamic> row) {
            final raw = _pickStr(row, [
              'date_of_incident',
              'accident_date',
              'accident_datetime',
              'date_of_accident',
            ]);
            if (raw == '-') return '-';
            return _formatDate(raw);
          },
          'insured_name': (dynamic v, Map<String, dynamic> row) => _pickStr(row, [
            'insured_name',
            'customer_name',
            'proposer_name',
          ]),
          'claim_number': (dynamic v, Map<String, dynamic> row) =>
              _pickStr(row, ['claim_number']),
          'broker': (dynamic v, Map<String, dynamic> row) =>
              _pickStr(row, ['broker_name', 'broker']),
          'partner': (dynamic v, Map<String, dynamic> row) =>
              _pickStr(row, ['agent_name', 'partner_name', 'partner']),
          'remark': (dynamic v, Map<String, dynamic> row) =>
              _pickStr(row, ['remark']),
          'pending_days': (dynamic v, Map<String, dynamic> row) =>
              _pendingDaysLabel(row),
          'settled_amount': (dynamic v, Map<String, dynamic> row) => _pickStr(row, [
            'settled_amount',
            'claim_amount',
            'settlement_amount',
          ]),
        },
      };

  Future<void> _onExportClaims() async {
    final cfg = _exportConfig;
    try {
      await ExcelExporter.exportToExcel(
        sheetName: 'Claims',
        data: filteredData,
        displayHeaders: cfg['displayHeaders'] as List<String>,
        keys: cfg['keys'] as List<String>,
        fileName: 'claim_list',
        valueFormatters:
            cfg['valueFormatters'] as Map<String, ExportValueFormatter>?,
      );
      if (mounted) {
        ToastHelper.showSuccessToast(context, 'Export finished');
      }
    } catch (e) {
      if (mounted) {
        ToastHelper.showErrorToast(context, 'Export failed: $e');
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return MainLayout(
      title: 'Claims',
      body: SelectionArea(
        child: Padding(
          padding: const EdgeInsets.all(12),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              _buildHeaderTabs(context),
              const SizedBox(height: 14),
              _buildFilterBar(context),
              const SizedBox(height: 12),
              Expanded(
                child: isLoading
                    ? const Center(child: CircularProgressIndicator())
                    : ResponsiveLayout.isMobile(context)
                        ? _buildMobileList()
                        : _buildDesktopTable(),
              ),
              const SizedBox(height: 8),
              _buildFooter(context),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildHeaderTabs(BuildContext context) {
    return Text(
      'Claims',
      style: GoogleFonts.poppins(
        fontSize: 14,
        fontWeight: FontWeight.w400,
      ),
    );
  }

  // Widget _tabSwitcher() {
  //   return Container(
  //     padding: const EdgeInsets.all(4),
  //     decoration: BoxDecoration(
  //       color: const Color(0xFFF1F5F9),
  //       borderRadius: BorderRadius.circular(10),
  //     ),
  //     child: Row(
  //       mainAxisSize: MainAxisSize.min,
  //       children: [
  //         _tabChip(
  //           label: 'Pending Claims',
  //           count: _pendingCount,
  //           selected: _pendingTab,
  //           onTap: () => _setTab(true),
  //         ),
  //         const SizedBox(width: 6),
  //         _tabChip(
  //           label: 'Settled Claims',
  //           count: _settledCount,
  //           selected: !_pendingTab,
  //           onTap: () => _setTab(false),
  //         ),
  //       ],
  //     ),
  //   );
  // }

  // Widget _tabChip({
  //   required String label,
  //   required int count,
  //   required bool selected,
  //   required VoidCallback onTap,
  // }) {
  //   return Material(
  //     color: Colors.transparent,
  //     child: InkWell(
  //       onTap: onTap,
  //       borderRadius: BorderRadius.circular(8),
  //       child: AnimatedContainer(
  //         duration: const Duration(milliseconds: 180),
  //         padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
  //         decoration: BoxDecoration(
  //           color: selected ? Colors.white : Colors.transparent,
  //           borderRadius: BorderRadius.circular(8),
  //           boxShadow: selected
  //               ? [
  //                   BoxShadow(
  //                     color: Colors.black.withValues(alpha: 0.06),
  //                     blurRadius: 8,
  //                     offset: const Offset(0, 2),
  //                   ),
  //                 ]
  //               : null,
  //         ),
  //         child: Row(
  //           mainAxisSize: MainAxisSize.min,
  //           children: [
  //             Text(
  //               label,
  //               style: GoogleFonts.inter(
  //                 fontSize: 12,
  //                 fontWeight: FontWeight.w600,
  //                 color: selected ? _teal : _muted,
  //               ),
  //             ),
  //             const SizedBox(width: 8),
  //             Container(
  //               width: 26,
  //               height: 26,
  //               alignment: Alignment.center,
  //               decoration: BoxDecoration(
  //                 color: selected
  //                     ? _teal.withValues(alpha: 0.12)
  //                     : const Color(0xFFE2E8F0),
  //                 shape: BoxShape.circle,
  //               ),
  //               child: Text(
  //                 '$count',
  //                 style: GoogleFonts.inter(
  //                   fontSize: 11,
  //                   fontWeight: FontWeight.w700,
  //                   color: selected ? _teal : _muted,
  //                 ),
  //               ),
  //             ),
  //           ],
  //         ),
  //       ),
  //     ),
  //   );
  // }

  Widget _buildFilterBar(BuildContext context) {
    final isMobile = ResponsiveLayout.isMobile(context);
    final inner = isMobile
        ? Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              _filterControlsRow(context),
              const SizedBox(height: 10),
              _buildSearchAndActions(context),
            ],
          )
        : Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Expanded(child: _filterControlsRow(context)),
              _buildSearchAndActions(context),
            ],
          );

    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
      decoration: BoxDecoration(
        border: Border.all(color: _border),
        borderRadius: BorderRadius.circular(10),
        color: Colors.white,
      ),
      child: inner,
    );
  }

  Widget _filterControlsRow(BuildContext context) {
    final isMobile = ResponsiveLayout.isMobile(context);
    final claimTypeChoices = _claimTypeFilterChoices(
      _uniqueFrom((r) => _pickStr(r, ['claim_type_value'])),
    );
    final insurerChoices = _insurerFilterChoices(
      _uniqueFrom((r) => _pickStr(r, ['insurer_short_name'])),
    );
    final statusChoices = _statusFilterChoices(
      _uniqueFrom((r) => _pickStr(r, ['claim_status_value'])),
    );

    final dateW = isMobile ? 168.0 : 175.0;
    final dropW = isMobile ? 128.0 : 140.0;

    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          DateRangePickerField(
            startController: _startDateController,
            endController: _endDateController,
            hintText: 'Select date range',
            showLabelAboveField: false,
            txtwidth: dateW,
            txtheight: 38,
            lastDate: DateTime.now(),
            useFormField: false,
          ),
          const SizedBox(width: 8),
          _buildFilterDropdownSearch(
            width: dropW,
            selectedValue: _filterClaimType,
            choices: claimTypeChoices,
            twoLineItems: true,
            onChanged: (v) => setState(() => _filterClaimType = v),
          ),
          const SizedBox(width: 8),
          _buildFilterDropdownSearch(
            width: dropW + 8,
            selectedValue: _filterInsurer,
            choices: insurerChoices,
            twoLineItems: true,
            onChanged: (v) => setState(() => _filterInsurer = v),
          ),
          const SizedBox(width: 8),
          _buildFilterDropdownSearch(
            width: dropW,
            selectedValue: _filterStatus,
            choices: statusChoices,
            onChanged: (v) => setState(() => _filterStatus = v),
          ),
          const SizedBox(width: 8),
          _squareFilterButton(
            icon: Icons.search,
            filled: true,
            onTap: _applyFilterBar,
          ),
          const SizedBox(width: 8),
          _squareFilterButton(
            icon: Icons.refresh,
            filled: false,
            onTap: _clearFilters,
          ),
        ],
      ),
    );
  }

  Widget _squareFilterButton({
    required VoidCallback onTap,
    required bool filled,
    IconData? icon,
    String? assetPath,
    String? tooltip,
  }) {
    assert(icon != null || assetPath != null);

    final child = assetPath != null
        ? Image.asset(
            assetPath,
            height: 16,
            width: 16,
            color: filled ? Colors.white : _muted,
            errorBuilder: (_, __, ___) => Icon(
              Icons.open_in_new_rounded,
              size: 20,
              color: filled ? Colors.white : _muted,
            ),
          )
        : Icon(
            icon,
            size: 20,
            color: filled ? Colors.white : _muted,
          );

    final button = Material(
      color: filled ? _teal : Colors.white,
      borderRadius: BorderRadius.circular(8),
      child: InkWell(
        onTap: onTap,
        borderRadius: BorderRadius.circular(8),
        child: Container(
          width: 38,
          height: 38,
          alignment: Alignment.center,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(8),
            border: filled ? null : Border.all(color: _border),
          ),
          child: child,
        ),
      ),
    );

    if (tooltip != null) {
      return Tooltip(message: tooltip, child: button);
    }
    return button;
  }

  Widget _buildSearchAndActions(BuildContext context) {
    final isMobile = ResponsiveLayout.isMobile(context);
    final searchField = ThemedSearchField(
      hintText: 'Search...',
      backgroundColor: Colors.white,
      txtHeight: 38,
      onChanged: _onQuickSearch,
      controller: _quickSearchController,
      txtwidth: isMobile
          ? MediaQuery.sizeOf(context).width * 0.5
          : 200,
    );

    final actions = Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        const SizedBox(width: 10),
        _squareFilterButton(
          icon: Icons.add,
          filled: true,
          tooltip: 'Add claim',
          onTap: () {
            showDialog<void>(
              context: context,
              builder: (ctx) => AddClaimStepperDialog(
                managerId: managerId,
                userId: userId,
                role: roleId,
                onSuccess: refresh,
              ),
            );
          },
        ),
        const SizedBox(width: 8),
        _squareFilterButton(
          filled: true,
          assetPath: 'assets/miscellaneous/export.png',
          tooltip: 'Export',
          onTap: _onExportClaims,
        ),
      ],
    );

    if (isMobile) {
      return Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Expanded(child: searchField),
          actions,
        ],
      );
    }

    return Row(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        searchField,
        actions,
      ],
    );
  }

  Widget _buildFooter(BuildContext context) {
    final total = filteredData.length;
    final showing = _paginatedSorted.length;
    final label = total == 1 ? 'claim' : 'claims';

    return Row(
      children: [
        Text(
          'Showing $showing of $total $label',
          style: GoogleFonts.inter(fontSize: 12, color: _muted),
        ),
        const Spacer(),
        Text(
          total == 0 ? 'Page 1' : 'Page $currentPage',
          style: GoogleFonts.inter(fontSize: 12, color: _muted),
        ),
        const SizedBox(width: 16),
        PaginationControls(
          currentPage: currentPage,
          itemsPerPage: itemsPerPage,
          totalItems: filteredData.length,
          onPageChanged: (page) {
            setState(() => currentPage = page);
          },
          onItemsPerPageChanged: (items) {
            setState(() {
              itemsPerPage = items;
              currentPage = 1;
            });
          },
        ),
      ],
    );
  }

  int _calculatePendingDays(String? createdAt) {
    if (createdAt == null || createdAt.isEmpty) return 0;
    try {
      final created = DateFormat('dd-MM-yyyy').parse(createdAt.split(' ')[0]);
      final today = DateTime.now();
      return today.difference(created).inDays;
    } catch (e) {
      return 0;
    }
  }

  bool _isClosedClaimStatus(Map<String, dynamic> item) {
    final status =
        _pickStr(item, ['claim_status_value', 'status']).toLowerCase();
    return status.contains('closed') || status.contains('settled');
  }

  String _pendingDaysLabel(Map<String, dynamic> item) {
    final days = _calculatePendingDays(item['created_at']?.toString());
    return _isClosedClaimStatus(item) ? '-' : '$days';
  }

  Widget _pendingDaysCell(Map<String, dynamic> item) {
    return Expanded(
      flex: 1,
      child: Builder(
        builder: (context) {
          final days = _calculatePendingDays(item['created_at']?.toString());
          return Padding(
            padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 12),
            child: Center(
              child: Text(
                _isClosedClaimStatus(item) ? '-' : '$days',
                textAlign: TextAlign.center,
                style: _dataBold.copyWith(
                  color: _isClosedClaimStatus(item)
                      ? _muted
                      : (days > 7
                          ? Colors.red
                          : days > 3
                              ? Colors.orange
                              : Colors.green),
                ),
              ),
            ),
          );
        },
      ),
    );
  }

  Widget _buildDesktopTable() {
    if (filteredData.isEmpty) {
      return Center(
        child: Text(
          'No claims match your filters.',
          style: GoogleFonts.inter(color: _muted),
        ),
      );
    }

    final rows = _paginatedSorted;
    final startSerial = (currentPage - 1) * itemsPerPage;

    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        _tableHeaderRow(),
        Expanded(
          child: Scrollbar(
            controller: _tableVScrollController,
            thumbVisibility: true,
            interactive: true,
            child: ListView(
              controller: _tableVScrollController,
              primary: false,
              padding: EdgeInsets.zero,
              physics: const ClampingScrollPhysics(),
              children: [
                for (var index = 0; index < rows.length; index++) ...[
                  if (index > 0) const Divider(height: 1, color: _border),
                  _pendingDataRow(rows[index], startSerial + index + 1),
                ],
              ],
            ),
          ),
        ),
      ],
    );
  }

  Widget _headerCell(
    String text, {
    int flex = 1,
    TextAlign align = TextAlign.start,
  }) {
    return Expanded(
      flex: flex,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 12),
        child: Align(
          alignment: align == TextAlign.center
              ? Alignment.center
              : Alignment.centerLeft,
          child: Text(
            text.toUpperCase(),
            softWrap: true,
            maxLines: 2,
            overflow: TextOverflow.ellipsis,
            textAlign: align,
            style: GoogleFonts.inter(
              fontSize: 10,
              fontWeight: FontWeight.w700,
              letterSpacing: 0.3,
              color: const Color(0xFF475569),
            ),
          ),
        ),
      ),
    );
  }

  Widget _headerCellFixed(
    String text, {
    required double width,
    TextAlign align = TextAlign.start,
  }) {
    return SizedBox(
      width: width,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 12),
        child: Align(
          alignment: align == TextAlign.center
              ? Alignment.center
              : Alignment.centerLeft,
          child: Text(
            text.toUpperCase(),
            softWrap: false,
            maxLines: 1,
            overflow: TextOverflow.visible,
            textAlign: align,
            style: GoogleFonts.inter(
              fontSize: 10,
              fontWeight: FontWeight.w700,
              letterSpacing: 0.3,
              color: const Color(0xFF475569),
            ),
          ),
        ),
      ),
    );
  }

  Widget _headerCellSno() {
    return Expanded(
      flex: 1,
      child: Padding(
        padding: const EdgeInsets.only(left: 6, right: 2, top: 12, bottom: 12),
        child: Align(
          alignment: Alignment.centerLeft,
          child: Text(
            'S NO',
            softWrap: true,
            maxLines: 2,
            style: GoogleFonts.inter(
              fontSize: 9,
              fontWeight: FontWeight.w700,
              letterSpacing: 0.2,
              color: const Color(0xFF475569),
            ),
          ),
        ),
      ),
    );
  }

  Widget _tableHeaderRow() {
    return Container(
      decoration: BoxDecoration(
        color: _surfaceGrey,
        borderRadius: BorderRadius.circular(8),
      ),
      child: Row(
        children: [
          _headerCellSno(),
          _headerCell('Created Date', flex: 2),
          _headerCell('Claim Type', flex: 2),
          _headerCell('Vehicle No', flex: 2),
          _headerCell('Insured Name', flex: 2),
          _headerCell('Policy Number', flex: 2),
          _headerCell('Claim Number', flex: 2),
          _headerCell('Accident Date', flex: 2),
          _headerCell('Insurer', flex: 2),
          _headerCell('Broker', flex: 2),
          _headerCell('Partner', flex: 2),
          _headerCell('Remarks', flex: 2),
          _headerCell('Status', flex: 2),
          _headerCell('Pending Days', flex: 1, align: TextAlign.center),
          _headerCell('Action', flex: 2, align: TextAlign.center),
        ],
      ),
    );
  }

  Widget _cell(Widget child, {int flex = 1}) {
    return Expanded(
      flex: flex,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 12),
        child: Align(
          alignment: Alignment.centerLeft,
          child: child,
        ),
      ),
    );
  }

  Widget _cellFixed(Widget child, {required double width}) {
    return SizedBox(
      width: width,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 12),
        child: Align(
          alignment: Alignment.centerLeft,
          child: child,
        ),
      ),
    );
  }

  Widget _cellSno(Widget child) {
    return Expanded(
      flex: 1,
      child: Padding(
        padding: const EdgeInsets.only(left: 6, right: 2, top: 12, bottom: 12),
        child: Align(
          alignment: Alignment.centerLeft,
          child: child,
        ),
      ),
    );
  }

  Widget _cellText(
    String text, {
    int flex = 1,
    int maxLines = 2,
    FontWeight? fontWeight,
    bool ellipsis = true,
  }) {
    return _cell(
      Text(
        text,
        style: _dataStyle.copyWith(
          fontWeight: fontWeight ?? FontWeight.w400,
        ),
        maxLines: maxLines,
        softWrap: maxLines > 1,
        overflow: ellipsis ? TextOverflow.ellipsis : TextOverflow.visible,
      ),
      flex: flex,
    );
  }

  Widget _cellTextFixed(
    String text, {
    required double width,
    int maxLines = 1,
    FontWeight? fontWeight,
    TextAlign align = TextAlign.start,
  }) {
    return SizedBox(
      width: width,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 12),
        child: Align(
          alignment: align == TextAlign.center
              ? Alignment.center
              : Alignment.centerLeft,
          child: Text(
            text,
            textAlign: align,
            style: _dataStyle.copyWith(
              fontWeight: fontWeight ?? FontWeight.w400,
            ),
            maxLines: maxLines,
            softWrap: maxLines > 1,
            overflow: TextOverflow.visible,
          ),
        ),
      ),
    );
  }

  Widget _cellRemarks(String text, {int flex = 3}) {
    final display = text.trim().isEmpty ? '-' : text.trim();
    final textWidget = Text(
      display,
      style: _dataStyle,
      maxLines: 1,
      softWrap: false,
      overflow: TextOverflow.ellipsis,
    );
    if (display == '-') {
      return _cell(textWidget, flex: flex);
    }
    return _cell(
      Tooltip(
        richMessage: WidgetSpan(
          child: ConstrainedBox(
            constraints: const BoxConstraints(maxWidth: 420),
            child: Text(
              display,
              style: GoogleFonts.inter(
                fontSize: 13,
                height: 1.45,
                fontWeight: FontWeight.w400,
                color: Colors.white,
              ),
            ),
          ),
        ),
        padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
        margin: const EdgeInsets.only(bottom: 6),
        preferBelow: false,
        verticalOffset: 10,
        waitDuration: const Duration(milliseconds: 250),
        showDuration: const Duration(seconds: 10),
        decoration: BoxDecoration(
          color: const Color(0xFF334155),
          borderRadius: BorderRadius.circular(8),
          boxShadow: const [
            BoxShadow(
              color: Color(0x40000000),
              blurRadius: 10,
              offset: Offset(0, 3),
            ),
          ],
        ),
        child: textWidget,
      ),
      flex: flex,
    );
  }      
   
  Widget _pendingDataRow(Map<String, dynamic> item, int sno) {
    final createdRaw = _pickStr(item, [
      'created_at',
      'created_date',
      'created_on',
    ]);
    final accidentRaw = _pickStr(item, [
      'date_of_incident',
      'accident_date',
      'accident_datetime',
      'date_of_accident',
    ]);
    final insured = _pickStr(item, [
      'insured_name',
      'customer_name',
      'proposer_name',
    ]);
    final remarks = _pickStr(item, ['remark']);  

    return Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        _cellSno(Text('$sno', style: _dataStyle)),
        _cellText(
          createdRaw != '-' ? _formatDate(createdRaw) : '-',
          flex: 2,
          maxLines: 2,
        ),
        _cell(
          _claimTypeChip(_pickStr(item, ['claim_type_value'])),
          flex: 2,
        ),
        _cellText(_pickStr(item, ['reg_no']), flex: 2, maxLines: 2),
        _cellText(insured, flex: 2, maxLines: 2, fontWeight: FontWeight.w600),
        _cellText(
          _pickStr(item, ['policy_no', 'policy_number']),
          flex: 2,
          maxLines: 2,
        ),
        _cellText(
          _pickStr(item, ['claim_number']),
          flex: 2,
          maxLines: 2,
        ),
        _cellText(
          accidentRaw != '-' ? _formatDate(accidentRaw) : '-',
          flex: 2,
          maxLines: 2,
        ),
        _cellText(_pickStr(item, ['insurer_short_name']), flex: 2, maxLines: 2),
        _cellText(_pickStr(item, ['broker_name', 'broker']), flex: 2, maxLines: 2),
        _cellText(
          _pickStr(item, ['agent_name', 'partner_name', 'partner']),
          flex: 2,
          maxLines: 2,
        ),
        _cellRemarks(remarks, flex: 2),
        _cell(
          _statusChip(_pickStr(item, ['claim_status_value'])),
          flex: 2,
        ),
        _pendingDaysCell(item),
        _cell(Center(child: _actionIcons(item)), flex: 2),
      ],
    );
  }

  // Widget _settledDataRow(Map<String, dynamic> item, int sno) {
  //   final accidentRaw = _pickStr(item, [
  //     'date_of_incident',
  //     'accident_date',
  //     'accident_datetime',
  //     'date_of_accident',
  //   ]);
  //   final insured = _pickStr(item, [
  //     'insured_name',
  //     'customer_name',
  //     'proposer_name',
  //   ]);
  //   final remarks = _pickStr(item, ['remarks', 'claim_description']);
  //   final settled = _pickStr(item, [
  //     'settled_amount',
  //     'claim_amount',
  //     'settlement_amount',
  //   ]);
  //   return Row(
  //     crossAxisAlignment: CrossAxisAlignment.center,
  //     children: [
  //       _cellSno(Text('$sno', style: _dataStyle)),
  //       _cellText(_pickStr(item, ['reg_no']), flex: 2, maxLines: 2),
  //       _cellText(insured, flex: 2, maxLines: 2, fontWeight: FontWeight.w600),
  //       _cellText(_pickStr(item, ['policy_no']), flex: 2, maxLines: 2),
  //       _cellText(
  //         accidentRaw != '-' ? _formatDate(accidentRaw) : '-',
  //         flex: 2,
  //         maxLines: 2,
  //       ),
  //       _cellText(_pickStr(item, ['insurer_short_name']), flex: 2, maxLines: 2),
  //       _cellText(_pickStr(item, ['broker_name', 'broker']), flex: 2, maxLines: 2),
  //       _cellText(
  //         _pickStr(item, ['agent_name', 'partner_name', 'partner']),
  //         flex: 2,
  //         maxLines: 2,
  //       ),
  //       _cellRemarks(remarks, flex: 2),
  //       _cell(
  //         _statusChip(_pickStr(item, ['claim_status_value'])),
  //         flex: 2,
  //       ),
  //       _pendingDaysCell(item),
  //       _cellText(settled == '-' ? '-' : settled, flex: 2, maxLines: 2),
  //       _cell(_actionIcons(item), flex: 1),
  //     ],
  //   );
  // }

  Widget _actionIcons(Map<String, dynamic> item) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        IconButton(
          padding: EdgeInsets.zero,
          constraints: const BoxConstraints(minWidth: 28, minHeight: 28),
          tooltip: 'Edit',
          icon: const Icon(Icons.edit_outlined, color: _teal, size: 18),
          onPressed: () {
            showDialog<void>(
              context: context,
              builder: (ctx) => AddClaimStepperDialog(
                managerId: managerId,
                userId: userId,
                role: roleId,
                claimToEdit: item,
                onSuccess: refresh,
              ),
            );
          },
        ),
        if (_canShowDeleteAction) const SizedBox(width: 6),
        // IconButton(
        //   padding: EdgeInsets.zero,
        //   constraints: const BoxConstraints(minWidth: 30, minHeight: 30),
        //   tooltip: 'Upload',
        //   icon: const Icon(Icons.cloud_upload_outlined, color: _teal, size: 18),
        //   onPressed: () {},
        // ),
        // IconButton(
        //   padding: EdgeInsets.zero,
        //   constraints: const BoxConstraints(minWidth: 30, minHeight: 30),
        //   tooltip: 'Download',
        //   icon: const Icon(
        //     Icons.cloud_download_outlined,
        //     color: _actionDownloadBlue,
        //     size: 18,
        //   ),
        //   onPressed: () {},
        // ),
        if (_canShowDeleteAction)
          IconButton(
            padding: EdgeInsets.zero,
            constraints: const BoxConstraints(minWidth: 28, minHeight: 28),
            tooltip: 'Delete',
            icon: const Icon(
              Icons.delete_outline,
              color: Color(0xFFC62828),
              size: 18,
            ),
            onPressed: () {
              final claimId = _pickStr(item, ['id']);
              _confirmDelete(context, claimId);
            },
          ),
      ],
    );
  }

  Widget _claimTypeChip(String text) {
    final t = text.toLowerCase();
    Color bg;
    Color fg;
    if (t.contains('theft')) {
      bg = const Color(0xFFFFEBEE);
      fg = const Color(0xFFC62828);
    } else if (t.contains('tp') && !t.contains('own')) {
      bg = const Color(0xFFE3F2FD);
      fg = const Color(0xFF1565C0);
    } else if (t.contains('od') || t.contains('own damage')) {
      bg = const Color(0xFFF3E5F5);
      fg = const Color(0xFF6A1B9A);
    } else {
      bg = const Color(0xFFF3E5F5);
      fg = const Color(0xFF6A1B9A);
    }
    return Align(
      alignment: Alignment.centerLeft,
      child: _pillWrapWords(text, bg, fg),
    );
  }

  String _statusDisplayLabel(String text) {
    final t = text.trim();
    if (t.isEmpty || t == '-') return t.isEmpty ? '-' : t;
    final compact = t.replaceAll(RegExp(r'\s+'), '').toUpperCase();
    if (compact == 'INPROGRESS') return 'IN PROGRESS';
    return t;
  }

  Widget _statusChip(String text) {
    final label = _statusDisplayLabel(text);
    final t = label.toLowerCase();
    Color bg;
    Color fg;
    if (t.contains('reject')) {
      bg = const Color(0xFFFFEBEE);
      fg = const Color(0xFFC62828);
    } else if (t.contains('open')) {
      bg = const Color(0xFFFFF3E0);
      fg = const Color(0xFFEF6C00);
    } else if (t.contains('progress')) {
      bg = const Color(0xFFF3E5F5);
      fg = const Color(0xFF6A1B9A);
    } else if (t.contains('settled')) {
      bg = const Color(0xFFE8F5E9);
      fg = const Color(0xFF2E7D32);
    } else {
      bg = const Color(0xFFF1F5F9);
      fg = const Color(0xFF475569);
    }
    return Align(
      alignment: Alignment.centerLeft,
      child: _pill(label, bg, fg),
    );
  }

  Widget _pill(String text, Color bg, Color fg, {bool showFull = false}) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
      decoration: BoxDecoration(
        color: bg,
        borderRadius: BorderRadius.circular(20),
      ),
      child: Text(
        text,
        maxLines: 1,
        softWrap: false,
        overflow: TextOverflow.visible,
        style: GoogleFonts.inter(
          fontSize: 10.5,
          fontWeight: FontWeight.w600,
          color: fg,
        ),
      ),
    );
  }

  /// Pill label that wraps only between words, never inside a word.
  Widget _pillWrapWords(String text, Color bg, Color fg) {
    final style = GoogleFonts.inter(
      fontSize: 10.5,
      fontWeight: FontWeight.w600,
      color: fg,
    );
    final words = text.trim().split(RegExp(r'\s+')).where((w) => w.isNotEmpty);
    if (words.isEmpty) {
      return _pill('-', bg, fg);
    }
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
      decoration: BoxDecoration(
        color: bg,
        borderRadius: BorderRadius.circular(20),
      ),
      child: Wrap(
        spacing: 4,
        runSpacing: 2,
        crossAxisAlignment: WrapCrossAlignment.center,
        children: words
            .map((w) => Text(w, style: style))
            .toList(),
      ),
    );
  }

  TextStyle get _dataStyle => GoogleFonts.inter(
        fontSize: 11.5,
        fontWeight: FontWeight.w400,
        color: const Color(0xFF0F172A),
      );

  TextStyle get _dataBold => GoogleFonts.inter(
        fontSize: 12,
        fontWeight: FontWeight.w700,
        color: const Color(0xFF0F172A),
      );

  Widget _buildMobileList() {
    if (filteredData.isEmpty) {
      return Center(
        child: Text(
          'No claims match your filters.',
          style: GoogleFonts.inter(color: _muted),
        ),
      );
    }
    final rows = _paginatedSorted;
    final startSerial = (currentPage - 1) * itemsPerPage;

    return ListView.separated(
      itemCount: rows.length,
      separatorBuilder: (_, _) => const SizedBox(height: 10),
      itemBuilder: (context, index) {
        final item = rows[index];
        final sno = startSerial + index + 1;
        return _mobileCard(item, sno);
      },
    );
  }

  Widget _mobileCard(Map<String, dynamic> item, int sno) {
    return Container(
      padding: const EdgeInsets.all(14),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: _border),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Text('#$sno', style: _dataStyle.copyWith(color: _muted)),
              const Spacer(),
              _statusChip(_pickStr(item, ['claim_status_value'])),
            ],
          ),
          const SizedBox(height: 8),
          Text(
            _pickStr(item, ['reg_no']),
            style: _dataStyle.copyWith(
              fontWeight: FontWeight.w700,
              fontSize: 14,
            ),
          ),
          const SizedBox(height: 4),
          Text(
            _pickStr(item, [
              'insured_name',
              'customer_name',
              'proposer_name',
            ]),
            style: _dataStyle.copyWith(fontWeight: FontWeight.w500),
          ),
          const SizedBox(height: 8),
          Wrap(
            spacing: 8,
            runSpacing: 8,
            children: [
              _claimTypeChip(_pickStr(item, ['claim_type_value'])),
            ],
          ),
          const Divider(height: 20),
          _mobilePair(
            'Policy',
            _pickStr(item, ['policy_no', 'policy_number']),
          ),
          _mobilePair(
            'Claim No',
            _pickStr(item, ['claim_number']),
          ),
          _mobilePair('Insurer', _pickStr(item, ['insurer_short_name'])),
          _mobilePair('Pending days', _pendingDaysLabel(item)),
          // if (!_pendingTab) ...[
          //   _mobilePair(
          //     'Settled (₹)',
          //     _pickStr(item, [
          //       'settled_amount',
          //       'claim_amount',
          //       'settlement_amount',
          //     ]),
          //   ),
          // ],
          const SizedBox(height: 8),
          Align(
            alignment: Alignment.centerRight,
            child: _actionIcons(item),
          ),
        ],
      ),
    );
  }

  Widget _mobilePair(String k, String v) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 6),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(
            width: 88,
            child: Text(
              k,
              style: GoogleFonts.inter(
                fontSize: 11,
                color: _muted,
                fontWeight: FontWeight.w500,
              ),
            ),
          ),
          Expanded(
            child: Text(v, style: _dataStyle),
          ),
        ],
      ),
    );
  }
}
