import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:jwt_decode/jwt_decode.dart';
import 'package:nhance_partner/core/routing/routes.dart';
import 'package:nhance_partner/core/services/api_service.dart';
import 'package:nhance_partner/data/services/auth_service.dart';
import 'package:nhance_partner/data/utils/Pagination.dart';
import 'package:nhance_partner/data/utils/toastNotification.dart';
import 'package:nhance_partner/presentation/layouts/main_layout.dart';
import 'package:nhance_partner/presentation/layouts/responsive_layout.dart';
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
// import 'package:nhance_partner/presentation/screens/Grid/Gridupload.dart';
import 'package:nhance_partner/presentation/themes/indicators/input_field_decoration.dart';
import 'package:nhance_partner/presentation/themes/indicators/search_field_theme.dart';

class GridViewScreen extends StatelessWidget {
  const GridViewScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return const gridViewScreen();
  }
}

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

  @override
  ConsumerState<gridViewScreen> createState() => _gridViewScreenState();
}

class _gridViewScreenState extends ConsumerState<gridViewScreen> {
  static const String _defaultVehicleTypeLabel = 'TWO WHEELER NEW';

  final ApiService _apiService = ApiService();
  String? _loggedId;

  /// `file_id` from the last successful Manager/Accounts grid load (export matches this).
  String? _gridFileIdUsed;

  bool _isLoading = false;

  // API response
  List<Map<String, dynamic>> _grid = [];
  List<Map<String, dynamic>> _filteredGrid = [];

  List<String> _insurers = [];
  List<String> _rtos = [];
  List<String> _vehicleTypes = [];
  List<String> _segments = [];

  // Filters
  String? _selectedInsurer;
  String? _selectedRto;
  String? _selectedVehicleType;
  String? _selectedSegment;

  final TextEditingController _searchController = TextEditingController();
  final TextEditingController _editVehicleTypeController =
      TextEditingController();
  final TextEditingController _editFuelController = TextEditingController();
  final TextEditingController _editRtoController = TextEditingController();
  final TextEditingController _editSegmentController = TextEditingController();
  final TextEditingController _editBrokerController = TextEditingController();
  final TextEditingController _editCompController = TextEditingController();
  final TextEditingController _editTpController = TextEditingController();
  final TextEditingController _editOdController = TextEditingController();
  final TextEditingController _editBrokerCompController =
      TextEditingController();
  final TextEditingController _editBrokerTpController = TextEditingController();
  final TextEditingController _editBrokerOdController = TextEditingController();
  final TextEditingController _editPartnerCompController =
      TextEditingController();
  final TextEditingController _editPartnerTpController =
      TextEditingController();
  final TextEditingController _editPartnerOdController =
      TextEditingController();
  final TextEditingController _editRemarksController = TextEditingController();

  // Pagination
  int _currentPage = 1;
  int _itemsPerPage = 10;
  bool _isUpdating = false;
  String _retentionRate = '-';

  /// Normalized vehicle type key → retention % from [partner_retention_rate] (via findAgent `retention_by_vehicle`).
  /// Also keys `id:<vehicle_type_id>` when the API returns `vehicle_type_id`.
  final Map<String, num> _retentionByVehicleKey = {};

  @override
  void dispose() {
    _searchController.dispose();
    _editVehicleTypeController.dispose();
    _editFuelController.dispose();
    _editRtoController.dispose();
    _editSegmentController.dispose();
    _editBrokerController.dispose();
    _editCompController.dispose();
    _editTpController.dispose();
    _editOdController.dispose();
    _editBrokerCompController.dispose();
    _editBrokerTpController.dispose();
    _editBrokerOdController.dispose();
    _editPartnerCompController.dispose();
    _editPartnerTpController.dispose();
    _editPartnerOdController.dispose();
    _editRemarksController.dispose();
    super.dispose();
  }

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

  Future<void> _bootstrapGrid() async {
    await Future.wait([
      _loadRetentionRateFromToken(),
      _loadPartnerRetentionByVehicle(),
    ]);
    if (!mounted) return;
    await _fetch();
  }

  Future<void> _loadRetentionRateFromToken() async {
    try {
      final token = await AuthService.getToken();
      if (token == null || token.isEmpty) return;

      final decodedToken = Jwt.parseJwt(token);
      final data = decodedToken['data'];
      if (data is! Map) return;

      final retentionRate = data['retention_rate']?.toString();
      final loggedId = data['id']?.toString();

      if (mounted) {
        setState(() {
          _loggedId = (loggedId == null || loggedId.trim().isEmpty)
              ? null
              : loggedId.trim();
          if (retentionRate != null && retentionRate.trim().isNotEmpty) {
            _retentionRate = retentionRate.trim();
          } else {
            _retentionRate = '-';
          }
          _grid = _applyRetentionToGridRows(_grid);
          _filteredGrid = _applyRetentionToGridRows(_filteredGrid);
        });
      }
    } catch (_) {
      // Keep fallback "-" when token parsing fails.
    }
  }

  String _normalizeVehicleTypeKey(String raw) {
    return raw.toLowerCase().trim().replaceAll(RegExp(r'\s+'), ' ');
  }

  /// Loads per–vehicle-type retention for the logged-in agent, or for Accounts with `?agent_id=` on grid URL.
  Future<void> _loadPartnerRetentionByVehicle() async {
    final appRole =
        (ref.read(userRoleProvider) ?? '').toString().trim().toLowerCase();
    String? agentPk;
    if (appRole == 'agent') {
      try {
        final token = await AuthService.getToken();
        if (token == null || token.isEmpty) return;
        final data = Jwt.parseJwt(token)['data'];
        if (data is Map) {
          agentPk = (data['id']?.toString() ?? '').trim();
          if (agentPk.isEmpty) agentPk = null;
        }
      } catch (_) {
        return;
      }
    } else if (appRole == 'accounts') {
      agentPk = Uri.base.queryParameters['agent_id']?.trim();
      if (agentPk != null && agentPk.isEmpty) agentPk = null;
    }

    if (agentPk == null || agentPk.isEmpty) {
      if (mounted) {
        setState(() {
          _retentionByVehicleKey.clear();
          _grid = _applyRetentionToGridRows(_grid);
          _filteredGrid = _applyRetentionToGridRows(_filteredGrid);
        });
      }
      return;
    }

    try {
      final res = await _apiService.findSingleAgentData(agentPk);
      if ((res['status'] ?? '').toString().toLowerCase() != 'success' ||
          res['data'] == null) {
        return;
      }
      final data = Map<String, dynamic>.from(res['data'] as Map);
      final raw = data['retention_by_vehicle'] ?? data['retentionByVehicle'];
      final next = <String, num>{};
      if (raw is List) {
        for (final item in raw) {
          if (item is! Map) continue;
          final m = Map<String, dynamic>.from(item);
          final rate = _toNum(m['retention_rate'] ?? m['retentionRate']);
          if (rate == null) continue;
          final name = (m['vehicle_type'] ?? '').toString().trim();
          if (name.isNotEmpty) {
            next[_normalizeVehicleTypeKey(name)] = rate;
          }
          final vid =
              int.tryParse((m['vehicle_type_id'] ?? m['vehicleTypeId'] ?? '')
                  .toString());
          if (vid != null) {
            next['id:$vid'] = rate;
          }
        }
      }
      if (mounted) {
        setState(() {
          _retentionByVehicleKey
            ..clear()
            ..addAll(next);
          _grid = _applyRetentionToGridRows(_grid);
          _filteredGrid = _applyRetentionToGridRows(_filteredGrid);
        });
      }
    } catch (_) {
      if (mounted) {
        setState(() {
          _retentionByVehicleKey.clear();
        });
      }
    }
  }

  String? _apiRoleFromAppRole(String? role) {
    if (role == null) return null;
    final r = role.trim();
    if (r.isEmpty) return null;

    switch (r.toLowerCase()) {
      case 'manager':
        return 'Manager';
      case 'handler':
        return 'Handler';
      case 'staff':
        return 'Staff';
      case 'agent':
        return 'Agent';
      case 'accounts':
        return 'Accounts';
      default:
        return r;
    }
  }

  Future<void> _fetch({bool applyRemoteFilters = false}) async {
    setState(() => _isLoading = true);
    try {
      final appRole = ref.read(userRoleProvider);
      final apiRole = _apiRoleFromAppRole(appRole);
      final queryParams = Uri.base.queryParameters;
      final queryRole = queryParams['role']?.trim();
      final queryFileId = queryParams['file_id']?.trim();
      final effectiveRole =
          (queryRole != null && queryRole.isNotEmpty) ? queryRole : apiRole;
      final roleLc = (effectiveRole ?? '').toLowerCase();

      // Manager / Accounts: require file_id (URL or latest from file list).
      // Agent: never send file_id; require logged-in user id for retention.
      String? effectiveFileId;
      if (roleLc == 'agent') {
        effectiveFileId = null;
      } else {
        effectiveFileId =
            (queryFileId != null && queryFileId.isNotEmpty) ? queryFileId : null;

        if (effectiveFileId == null &&
            (roleLc == 'manager' || roleLc == 'accounts')) {
          final fileListRes = await _apiService.fetchGridFileList();
          if ((fileListRes['status'] ?? '').toString().toLowerCase() ==
              'success') {
            final files = List<Map<String, dynamic>>.from(
              fileListRes['data'] ?? const [],
            );
            if (files.isNotEmpty) {
              files.sort((a, b) {
                final left = int.tryParse(a['id']?.toString() ?? '') ?? 0;
                final right = int.tryParse(b['id']?.toString() ?? '') ?? 0;
                return right.compareTo(left);
              });
              effectiveFileId = files.first['id']?.toString();
            }
          }
        }

        if (roleLc == 'manager' || roleLc == 'accounts') {
          if (effectiveFileId == null || effectiveFileId.trim().isEmpty) {
            if (mounted) {
              ToastHelper.showErrorToast(
                context,
                'No grid file found. Open grid from a file or upload a payout grid first.',
              );
            }
            return;
          }
        }
      }

      if (roleLc == 'agent') {
        final lid = _loggedId?.trim();
        if (lid == null || lid.isEmpty) {
          if (mounted) {
            ToastHelper.showErrorToast(
              context,
              'Unable to load grid: missing logged-in user id.',
            );
          }
          return;
        }
      }

      final loggedIdForGrid = roleLc == 'agent' ? _loggedId?.trim() : null;

      final res = await _apiService.loadPayoutGrid(
        role: effectiveRole,
        fileId: effectiveFileId,
        insurer: applyRemoteFilters ? _selectedInsurer : null,
        vehicleType: applyRemoteFilters ? _selectedVehicleType : null,
        segment: applyRemoteFilters ? _selectedSegment : null,
        rto: applyRemoteFilters ? _selectedRto : null,
        search: applyRemoteFilters ? _searchController.text.trim() : null,
        loggedId: loggedIdForGrid,
      );
      if ((res['status'] ?? '').toString().toLowerCase() != 'success') {
        if (mounted) {
          setState(() => _gridFileIdUsed = null);
        }
        ToastHelper.showErrorToast(
          context,
          res['data']?.toString() ?? 'Failed to load payout grid',
        );
        return;
      }

      final payload = _extractPayload(res);
      final grid = payload['grid'];
      final insurers = payload['insurers'];
      final rtos = payload['rtos'];
      final vehicleTypes = payload['vehicle_types'];
      final segments = payload['segments'];

      final rawGrid = (grid is List)
          ? grid
              .map<Map<String, dynamic>>(
                  (e) => (e as Map).cast<String, dynamic>())
              .toList()
          : <Map<String, dynamic>>[];
      _grid = _applyRetentionToGridRows(rawGrid);
      _filteredGrid = List<Map<String, dynamic>>.from(_grid);

      _insurers = _toStringList(insurers);
      _rtos = _toStringList(rtos);
      _vehicleTypes = _toStringList(vehicleTypes);
      _segments = _toStringList(segments);

      _gridFileIdUsed =
          (roleLc == 'manager' || roleLc == 'accounts') ? effectiveFileId : null;

      _applyDefaultVehicleTypeSelection();
      _applyFilters();
    } catch (e) {
      if (mounted) {
        setState(() => _gridFileIdUsed = null);
      }
      ToastHelper.showErrorToast(context, e.toString());
    } finally {
      if (mounted) setState(() => _isLoading = false);
    }
  }

  void _setFilter(VoidCallback fn) {
    fn();
    _applyFilters();
  }

  Map<String, dynamic> _extractPayload(Map<String, dynamic> res) {
    final data = res['data'];
    if (data is Map<String, dynamic>) return data;
    if (data is Map) return data.cast<String, dynamic>();
    return res;
  }

  List<String> _toStringList(dynamic raw) {
    if (raw is! List) return <String>[];
    return raw
        .map((item) {
          if (item is Map) {
            for (final key in const [
              'short_name',
              'name',
              'label',
              'title',
              'value',
              'rto',
              'segment',
              'vehicle_type',
            ]) {
              final val = item[key]?.toString().trim();
              if (val != null && val.isNotEmpty && val.toLowerCase() != 'null') {
                return val;
              }
            }
            final firstVal = item.values.isNotEmpty ? item.values.first : null;
            return firstVal?.toString() ?? '';
          }
          return item?.toString() ?? '';
        })
        .map((e) => e.trim())
        .where((e) => e.isNotEmpty && e.toLowerCase() != 'null')
        .toSet()
        .toList();
  }

  /// Sets [_selectedVehicleType] to the dropdown spelling that matches
  /// [_defaultVehicleTypeLabel], or prepends that label if the API omits it.
  void _applyDefaultVehicleTypeSelection() {
    final desiredLower = _defaultVehicleTypeLabel.toLowerCase();
    for (final v in _vehicleTypes) {
      if (v.trim().toLowerCase() == desiredLower) {
        _selectedVehicleType = v;
        return;
      }
    }
    _vehicleTypes = [_defaultVehicleTypeLabel, ..._vehicleTypes];
    _selectedVehicleType = _defaultVehicleTypeLabel;
  }

  void _applyFilters() {
    final q = _searchController.text.trim().toLowerCase();

    final next = _grid.where((row) {
      bool equalsOrAll(String? selected, dynamic raw) {
        if (selected == null) return true;
        return raw?.toString().toLowerCase() == selected.toLowerCase();
      }

      bool matchesSearch() {
        if (q.isEmpty) return true;
        final values = <String>[
          row['id']?.toString() ?? '',
          row['insurer']?.toString() ?? '',
          row['vehicle_type']?.toString() ?? '',
          row['segment']?.toString() ?? '',
          row['rto']?.toString() ?? '',
          row['remarks']?.toString() ?? '',
          row['comp']?.toString() ?? '',
          row['partner_comp']?.toString() ?? '',
          row['tp']?.toString() ?? '',
          row['od']?.toString() ?? '',
        ].map((e) => e.toLowerCase());

        return values.any((v) => v.contains(q));
      }

      return equalsOrAll(_selectedInsurer, row['insurer']) &&
          equalsOrAll(_selectedVehicleType, row['vehicle_type']) &&
          equalsOrAll(_selectedSegment, row['segment']) &&
          equalsOrAll(_selectedRto, row['rto']) &&
          matchesSearch();
    }).toList();

    setState(() {
      _filteredGrid = next;
      if (_showPartnerRetentionValues && !_hasAnyFilterSelection) {
        _filteredGrid = [];
      }
      _currentPage = 1;
    });
  }

  List<Map<String, dynamic>> get _sortedGrid {
    final next = [..._filteredGrid];
    next.sort((a, b) {
      final ai = int.tryParse(a['id']?.toString() ?? '') ?? 0;
      final bi = int.tryParse(b['id']?.toString() ?? '') ?? 0;
      return bi.compareTo(ai);
    });
    return next;
  }

  List<Map<String, dynamic>> get _paginatedGrid {
    final sorted = _sortedGrid;
    if (sorted.isEmpty) return [];

    final maxPage = (sorted.length / _itemsPerPage).ceil();
    final safePage =
        _currentPage.clamp(1, maxPage == 0 ? 1 : maxPage) as int;

    final startIndex = (safePage - 1) * _itemsPerPage;
    final endIndex = (startIndex + _itemsPerPage).clamp(0, sorted.length);
    return sorted.sublist(startIndex, endIndex);
  }

  String _nullableString(dynamic v) {
    if (v == null) return '-';
    final s = v.toString().trim();
    if (s.isEmpty || s.toLowerCase() == 'null') return '-';
    return s;
  }

  num? _toNum(dynamic value) {
    if (value == null) return null;
    final raw = value.toString().trim();
    if (raw.isEmpty || raw.toLowerCase() == 'null' || raw == '-') return null;
    final normalized = raw.replaceAll(RegExp(r'[^0-9\.\-]'), '');
    if (normalized.isEmpty || normalized == '-' || normalized == '.') return null;
    return num.tryParse(normalized);
  }

  num? _retentionPercentForGridRowPreview(Map<String, dynamic> row) {
    final vt = row['vehicle_type']?.toString().trim() ?? '';
    if (vt.isNotEmpty) {
      final byName = _retentionByVehicleKey[_normalizeVehicleTypeKey(vt)];
      if (byName != null) return byName;
    }
    final vid =
        int.tryParse(row['vehicle_type_id']?.toString() ?? '');
    if (vid != null) {
      final byId = _retentionByVehicleKey['id:$vid'];
      if (byId != null) return byId;
    }
    return null;
  }

  /// Accounts preview: subtract loaded per–vehicle retention; ≤0 → '-'; no match → show base.
  String _partnerValueForRowPreview(Map<String, dynamic> row, dynamic baseValue) {
    final base = _toNum(baseValue);
    if (base == null) return '-';
    final retention = _retentionPercentForGridRowPreview(row);
    if (retention == null) {
      if (base == base.roundToDouble()) return base.toInt().toString();
      return base
          .toStringAsFixed(2)
          .replaceFirst(RegExp(r'0+$'), '')
          .replaceFirst(RegExp(r'\.$'), '');
    }
    final result = base - retention;
    if (result <= 0) return '-';
    if (result == result.roundToDouble()) {
      return result.toInt().toString();
    }
    return result
        .toStringAsFixed(2)
        .replaceFirst(RegExp(r'0+$'), '')
        .replaceFirst(RegExp(r'\.$'), '');
  }

  List<Map<String, dynamic>> _applyRetentionToGridRows(
    List<Map<String, dynamic>> rows,
  ) {
    if (!_showPartnerRetentionValues) {
      return rows
          .map(
            (row) => Map<String, dynamic>.from(row)
              ..remove('partner_comp')
              ..remove('partner_tp')
              ..remove('partner_od'),
          )
          .toList();
    }
    // Partner (agent): API already applies retention on comp/tp/od when logged_id is sent.
    if (_showAddButton) {
      return rows.map((row) {
        final next = Map<String, dynamic>.from(row);
        next['partner_comp'] = next['oa'] ?? next['comp'];
        next['partner_tp'] = next['ob'] ?? next['tp'];
        next['partner_od'] = next['oc'] ?? next['od'];
        return next;
      }).toList();
    }
    // Accounts + ?agent_id= preview: client-side using findAgent retention map.
    return rows.map((row) {
      final next = Map<String, dynamic>.from(row);
      next['partner_comp'] = _partnerValueForRowPreview(next, next['comp']);
      next['partner_tp'] = _partnerValueForRowPreview(next, next['tp']);
      next['partner_od'] = _partnerValueForRowPreview(next, next['od']);
      return next;
    }).toList();
  }

  /// Edit column: Manager & Accounts only (not Agent).
  bool get _showActionColumn {
    final role = (ref.watch(userRoleProvider) ?? '').toString().trim().toLowerCase();
    return role == 'manager' || role == 'accounts';
  }

  bool get _showAddButton {
    final role = (ref.watch(userRoleProvider) ?? '').toString().trim().toLowerCase();
    return role == 'agent';
  }

  /// Partner (agent) login, or Accounts opening grid with `?agent_id=` to preview that partner’s payouts.
  bool get _accountsAgentPreview {
    final role = (ref.watch(userRoleProvider) ?? '').toString().trim().toLowerCase();
    if (role != 'accounts') return false;
    final aid = Uri.base.queryParameters['agent_id']?.trim();
    return aid != null && aid.isNotEmpty;
  }

  bool get _showPartnerRetentionValues =>
      _showAddButton || _accountsAgentPreview;

  bool get _hasAnyFilterSelection {
    return (_selectedInsurer != null && _selectedInsurer!.trim().isNotEmpty) ||
        (_selectedRto != null && _selectedRto!.trim().isNotEmpty) ||
        (_selectedVehicleType != null &&
            _selectedVehicleType!.trim().isNotEmpty) ||
        (_selectedSegment != null && _selectedSegment!.trim().isNotEmpty);
  }

  String _toEditText(dynamic value) {
    if (value == null) return '';
    final s = value.toString().trim();
    if (s.isEmpty || s.toLowerCase() == 'null') return '';
    return s;
  }

  void _setEditControllersFromRow(Map<String, dynamic> row) {
    _editVehicleTypeController.text = _toEditText(row['vehicle_type']);
    _editFuelController.text = _toEditText(row['fuel']);
    _editRtoController.text = _toEditText(row['rto']);
    _editSegmentController.text = _toEditText(row['segment']);
    _editBrokerController.text = _toEditText(row['broker_name']);
    _editCompController.text = _toEditText(row['comp']);
    _editTpController.text = _toEditText(row['tp']);
    _editOdController.text = _toEditText(row['od']);
    _editBrokerCompController.text = _toEditText(row['broker_comp']);
    _editBrokerTpController.text = _toEditText(row['broker_tp']);
    _editBrokerOdController.text = _toEditText(row['broker_od']);
    _editPartnerCompController.text = _toEditText(row['partner_comp']);
    _editPartnerTpController.text = _toEditText(row['partner_tp']);
    _editPartnerOdController.text = _toEditText(row['partner_od']);
    _editRemarksController.text = _toEditText(row['remarks']);
  }

  void _clearEditControllers() {
    _editVehicleTypeController.clear();
    _editFuelController.clear();
    _editRtoController.clear();
    _editSegmentController.clear();
    _editBrokerController.clear();
    _editCompController.clear();
    _editTpController.clear();
    _editOdController.clear();
    _editBrokerCompController.clear();
    _editBrokerTpController.clear();
    _editBrokerOdController.clear();
    _editPartnerCompController.clear();
    _editPartnerTpController.clear();
    _editPartnerOdController.clear();
    _editRemarksController.clear();
  }

  InputDecoration _editFieldDecoration(String label) {
    return InputDecoration(
      labelText: label,
      labelStyle: GoogleFonts.poppins(fontSize: 12),
      isDense: true,
      contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
      border: OutlineInputBorder(
        borderRadius: BorderRadius.circular(8),
      ),
    );
  }

  Widget _modalField(
    String label,
    TextEditingController controller, {
    int maxLines = 1,
  }) {
    return TextField(
      controller: controller,
      maxLines: maxLines,
      style: GoogleFonts.inter(fontSize: 12),
      decoration: _editFieldDecoration(label),
    );
  }


  @override
  Widget build(BuildContext context) {
    return MainLayout(
      title: 'Payout Details',
      body: SelectionArea(
        child: Container(
          width: MediaQuery.of(context).size.width,
          padding: const EdgeInsets.all(8),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              _buildTopBar(context),
              const SizedBox(height: 10),
              _buildFilterBar(context),
              const SizedBox(height: 10),
              if (!ResponsiveLayout.isMobile(context)) _buildDesktopHeader(),
              Expanded(
                child: _isLoading
                    ? const Center(child: CircularProgressIndicator())
                    : _buildGridOrCards(context),
              ),
              SizedBox(
                width: double.infinity,
                child: Align(
                  alignment: Alignment.centerRight,
                  child: PaginationControls(
                    currentPage: _currentPage,
                    itemsPerPage: _itemsPerPage,
                    totalItems: _filteredGrid.length,
                    onPageChanged: (page) => setState(() => _currentPage = page),
                    onItemsPerPageChanged: (items) {
                      setState(() {
                        _itemsPerPage = items;
                        _currentPage = 1;
                      });
                    },
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildTopBar(BuildContext context) {
    final isAgent =
        (ref.watch(userRoleProvider) ?? '').toString().trim().toLowerCase() ==
        'agent';
    final isMobile = ResponsiveLayout.isMobile(context);
    return Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        if (!isAgent) ...[
          Tooltip(
            message: 'Back',
            child: IconButton(
              icon: const Icon(Icons.arrow_left_sharp, size: 25),
              onPressed: () => context.go(AppRoutes.gridList),
              splashRadius: 18,
              padding: const EdgeInsets.all(4),
              hoverColor: Colors.black12,
              constraints: const BoxConstraints(),
            ),
          ),
          const SizedBox(width: 5),
        ],
        Text(
          'Payout Details',
          style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.w400),
        ),
        const Spacer(),
        if (isMobile)
          Expanded(child: _buildSearch(context, true))
        else
          _buildSearch(context, false),
        const SizedBox(width: 12),
        _buildExportButtonWidget(),
      ],
    );
  }

  Widget _buildFilterBar(BuildContext context) {
    final isMobile = ResponsiveLayout.isMobile(context);

    Widget dropdownInsurer() {
      return SizedBox(
        width: isMobile ? double.infinity : 200,
        height: 40,
        child: DropdownSearch<String>(
          items: (filter, infiniteScrollProps) {
            final items = _insurers;
            if (filter.isEmpty) return items;
            return items
                .where((e) => e.toLowerCase().contains(filter.toLowerCase()))
                .toList();
          },
          selectedItem: _selectedInsurer,
          popupProps: const PopupProps.menu(
            showSearchBox: true,
            fit: FlexFit.loose,
          ),
          dropdownBuilder: (context, selectedItem) => Padding(
            padding: const EdgeInsets.only(left: 10),
            child: Text(
              selectedItem ?? '',
              style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
              overflow: TextOverflow.ellipsis,
            ),
          ),
          onChanged: (val) => _setFilter(() => _selectedInsurer = val),
          decoratorProps: DropDownDecoratorProps(
            decoration: _dropdownDecoration('Insurer'),
          ),
          compareFn: (a, b) => a == b,
        ),
      );
    }

    Widget dropdownRto() {
      return SizedBox(
        width: isMobile ? double.infinity : 180,
        height: 40,
        child: DropdownSearch<String>(
          items: (filter, infiniteScrollProps) {
            final items = _rtos;
            if (filter.isEmpty) return items;
            return items
                .where((e) => e.toLowerCase().contains(filter.toLowerCase()))
                .toList();
          },
          selectedItem: _selectedRto,
          popupProps: const PopupProps.menu(
            showSearchBox: true,
            fit: FlexFit.loose,
          ),
          dropdownBuilder: (context, selectedItem) => Padding(
            padding: const EdgeInsets.only(left: 10),
            child: Text(
              selectedItem ?? '',
              style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
              overflow: TextOverflow.ellipsis,
            ),
          ),
          onChanged: (val) => _setFilter(() => _selectedRto = val),
          decoratorProps: DropDownDecoratorProps(
            decoration: _dropdownDecoration('RTO'),
          ),
          compareFn: (a, b) => a == b,
        ),
      );
    }

    Widget dropdownVehicleType() {
      return SizedBox(
        width: isMobile ? double.infinity : 200,
        height: 40,
        child: DropdownSearch<String>(
          items: (filter, infiniteScrollProps) {
            final items = _vehicleTypes;
            if (filter.isEmpty) return items;
            return items
                .where((e) => e.toLowerCase().contains(filter.toLowerCase()))
                .toList();
          },
          selectedItem: _selectedVehicleType,
          popupProps: const PopupProps.menu(
            showSearchBox: true,
            fit: FlexFit.loose,
          ),
          dropdownBuilder: (context, selectedItem) => Padding(
            padding: const EdgeInsets.only(left: 10),
            child: Text(
              selectedItem ?? '',
              style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
              overflow: TextOverflow.ellipsis,
            ),
          ),
          onChanged: (val) => _setFilter(() => _selectedVehicleType = val),
          decoratorProps: DropDownDecoratorProps(
            decoration: _dropdownDecoration('Vehicle Type'),
          ),
          compareFn: (a, b) => a == b,
        ),
      );
    }

    Widget dropdownSegment() {
      return SizedBox(
        width: isMobile ? double.infinity : 220,
        height: 40,
        child: DropdownSearch<String>(
          items: (filter, infiniteScrollProps) {
            final items = _segments;
            if (filter.isEmpty) return items;
            return items
                .where((e) => e.toLowerCase().contains(filter.toLowerCase()))
                .toList();
          },
          selectedItem: _selectedSegment,
          popupProps: const PopupProps.menu(
            showSearchBox: true,
            fit: FlexFit.loose,
          ),
          dropdownBuilder: (context, selectedItem) => Padding(
            padding: const EdgeInsets.only(left: 10),
            child: Text(
              selectedItem ?? '',
              style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
              overflow: TextOverflow.ellipsis,
            ),
          ),
          onChanged: (val) => _setFilter(() => _selectedSegment = val),
          decoratorProps: DropDownDecoratorProps(
            decoration: _dropdownDecoration('Segment'),
          ),
          compareFn: (a, b) => a == b,
        ),
      );
    }

    Widget searchBtn() => _filterIconButton(
          icon: Icons.search,
          message: 'Search',
          onTap: () async {
            if (_showPartnerRetentionValues && !_hasAnyFilterSelection) {
              ToastHelper.showInfoToast(
                context,
                'Please select at least one filter to view/export data.',
              );
              return;
            }
            await _fetch(applyRemoteFilters: true);
          },
        );

    Widget resetBtn() => _filterIconButton(
          icon: Icons.refresh,
          message: 'Reset',
          onTap: () async {
            setState(() {
              _selectedInsurer = null;
              _selectedRto = null;
              _selectedSegment = null;
              _searchController.clear();
              _applyDefaultVehicleTypeSelection();
            });
            await _fetch();
          },
        );

    return SizedBox(
      width: double.infinity,
      child: Container(
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: const Color(0xFFE5E7EB)),
      ),
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
      child: isMobile
          ? Column(
              children: [
                dropdownVehicleType(),
                const SizedBox(height: 10),
                dropdownInsurer(),
                const SizedBox(height: 10),
                dropdownSegment(),
                const SizedBox(height: 10),
                dropdownRto(),
                const SizedBox(height: 10),
                searchBtn(),
                const SizedBox(height: 10),
                resetBtn(),
              ],
            )
          : Row(
              children: [
                Expanded(
                  child: SingleChildScrollView(
                    scrollDirection: Axis.horizontal,
                    child: Row(
                      children: [
                        dropdownVehicleType(),
                        const SizedBox(width: 12),
                        dropdownInsurer(),
                        const SizedBox(width: 12),
                        dropdownSegment(),
                        const SizedBox(width: 12),
                        dropdownRto(),
                        const SizedBox(width: 12),
                        searchBtn(),
                        const SizedBox(width: 8),
                        resetBtn(),
                      ],
                    ),
                  ),
                ),
              ],
            ),
      ),
    );
  }

  Widget _buildSearch(BuildContext context, bool isMobile) {
    return ThemedSearchField(
      hintText: 'Search...',
      controller: _searchController,
      txtHeight: 40,
      txtwidth: isMobile ? null : 240,
      backgroundColor: Colors.white,
      onChanged: (_) => _applyFilters(),
    );
  }

  InputDecoration _dropdownDecoration(String label) {
    return AppInputDecorations.dropdownDecoration(label: label).copyWith(
      filled: true,
      fillColor: Colors.white,
      isDense: true,
      contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
      border: OutlineInputBorder(
        borderRadius: BorderRadius.circular(8),
        borderSide: const BorderSide(color: Color(0xFFE2E8F0)),
      ),
      enabledBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(8),
        borderSide: const BorderSide(color: Color(0xFFE2E8F0)),
      ),
      focusedBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(8),
        borderSide: const BorderSide(color: Color(0xFF2E7D6E)),
      ),
    );
  }

  Widget _filterIconButton({
    required IconData icon,
    required String message,
    required VoidCallback onTap,
  }) {
    return Tooltip(
      message: message,
      child: InkWell(
        onTap: onTap,
        borderRadius: BorderRadius.circular(8),
        child: Container(
          width: 34,
          height: 34,
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(8),
            border: Border.all(color: const Color(0xFFE2E8F0)),
          ),
          child: Icon(icon, size: 18, color: const Color(0xFF334155)),
        ),
      ),
    );
  }

  Widget _buildGridOrCards(BuildContext context) {
    if (_paginatedGrid.isEmpty) {
      return const Center(child: Text('No available data'));
    }

    if (ResponsiveLayout.isMobile(context)) {
      return ListView.separated(
        padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
        itemCount: _paginatedGrid.length,
        separatorBuilder: (context, index) => const SizedBox(height: 10),
        itemBuilder: (context, index) =>
            _gridViewCard(row: _paginatedGrid[index]),
      );
    }

    return ListView.builder(
      itemCount: _paginatedGrid.length,
      itemBuilder: (context, index) {
        return _buildTableRow(_paginatedGrid[index], rowIndex: index);
      },
    );
  }

  Widget _buildDesktopHeader() {
    return Container(
      decoration: BoxDecoration(
        color: const Color(0xFFF1F5F9),
        borderRadius: BorderRadius.circular(6),
      ),
      padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
      child: Row(
        children: [
          Expanded(flex: 1, child: Text('S.No', style: _headerStyle)),
          Expanded(flex: 2, child: Text('Insurer', style: _headerStyle)),
          Expanded(flex: 2, child: Text('Vehicle', style: _headerStyle)),
          Expanded(flex: 3, child: Text('Segment', style: _headerStyle)),
          Expanded(flex: 2, child: Text('RTO', style: _headerStyle)),
          Expanded(flex: 2, child: Text('Comp', style: _headerStyle)),
          Expanded(flex: 2, child: Text('TP', style: _headerStyle)),
          Expanded(flex: 2, child: Text('OD', style: _headerStyle)),
          Expanded(flex: 3, child: Text('Remarks', style: _headerStyle)),
        ],
      ),
    );
  }

  Widget _buildTableRow(Map<String, dynamic> row, {required int rowIndex}) {
    final sno = (_currentPage - 1) * _itemsPerPage + rowIndex + 1;

    return Container(
      padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
      decoration: const BoxDecoration(
        border: Border(
          bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1),
        ),
      ),
      child: Row(
        children: [
          Expanded(flex: 1, child: Text('$sno', style: _dataBold)),
          Expanded(
            flex: 2,
            child: Text(_nullableString(row['insurer']), style: _dataBold),
          ),
          Expanded(
            flex: 2,
            child: Text(_nullableString(row['vehicle_type']), style: _dataBold),
          ),
          Expanded(
            flex: 3,
            child: Text(
              _nullableString(row['segment']),
              style: _dataBold,
              overflow: TextOverflow.ellipsis,
            ),
          ),
          Expanded(flex: 2, child: Text(_nullableString(row['rto']), style: _dataBold)),
          Expanded(
            flex: 2,
            child: Text(_nullableString(row['comp']), style: _dataBold),
          ),
          Expanded(
            flex: 2,
            child: Text(_nullableString(row['tp']), style: _dataBold),
          ),
          Expanded(
            flex: 2,
            child: Text(_nullableString(row['od']), style: _dataBold),
          ),
          Expanded(
            flex: 3,
            child: Text(
              _nullableString(row['remarks']),
              style: _dataBold,
              overflow: TextOverflow.ellipsis,
            ),
          ),
        ],
      ),
    );
  }

  static final _headerStyle = GoogleFonts.poppins(
    fontSize: 11.2,
    fontWeight: FontWeight.w500,
    color: const Color(0xFF1E293B),
  );

  static final _dataBold = GoogleFonts.inter(
    fontSize: 11,
    fontWeight: FontWeight.w400,
    color: const Color(0xFF000000),
  );

  Widget _toolbarIconButton({
    required IconData icon,
    required String message,
    required VoidCallback onTap,
  }) {
    return Tooltip(
      message: message,
      child: InkWell(
        onTap: onTap,
        borderRadius: BorderRadius.circular(8),
        child: Container(
          width: 30,
          height: 30,
          decoration: BoxDecoration(
            color: const Color(0xFF2E7D6E),
            borderRadius: BorderRadius.circular(8),
          ),
          child: Icon(icon, size: 16, color: Colors.white),
        ),
      ),
    );
  }

  Widget _buildExportButtonWidget() {
    return InkWell(
      onTap: _isLoading
          ? () {}
          : () async {
              if (_showPartnerRetentionValues && !_hasAnyFilterSelection) {
                if (mounted) {
                  ToastHelper.showInfoToast(
                    context,
                    'Please select at least one filter to view/export data.',
                  );
                }
                return;
              }
              try {
                final queryParams = Uri.base.queryParameters;
                final role = _apiRoleFromAppRole(ref.read(userRoleProvider));
                final roleLc = (role ?? '').toLowerCase();
                final fileIdFromQuery = queryParams['file_id']?.trim();
                final fileIdToSend =
                    (roleLc == 'manager' || roleLc == 'accounts')
                    ? (_gridFileIdUsed ??
                        (fileIdFromQuery != null && fileIdFromQuery.isNotEmpty
                            ? fileIdFromQuery
                            : null))
                    : null;
                final previewAgentId =
                    queryParams['agent_id']?.trim();
                final loggedIdForExport = roleLc == 'agent'
                    ? _loggedId?.trim()
                    : (previewAgentId != null && previewAgentId.isNotEmpty
                        ? previewAgentId
                        : null);
                await _apiService.downloadGridExcel(
                  role: role,
                  fileId: fileIdToSend,
                  insurer: _selectedInsurer,
                  vehicleType: _selectedVehicleType,
                  segment: _selectedSegment,
                  rto: _selectedRto,
                  search: _searchController.text.trim(),
                  loggedId: loggedIdForExport,
                );
              } catch (e) {
                if (mounted) {
                  ToastHelper.showErrorToast(
                    context,
                    e.toString().replaceFirst('Exception: ', ''),
                  );
                }
              }
            },
      child: Container(
        width: 40,
        height: 36,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(8),
          color: const Color(0xFF2E7D6E),
        ),
        child: Tooltip(
          message: 'Export',
          child: Image.asset(
            "assets/miscellaneous/export.png",
            height: 13,
            width: 13,
          ),
        ),
      ),
    );
  }
}

class _gridViewCard extends StatelessWidget {
  final Map<String, dynamic> row;

  const _gridViewCard({required this.row});

  String _nullableString(dynamic v) {
    if (v == null) return '-';
    final s = v.toString().trim();
    if (s.isEmpty || s.toLowerCase() == 'null') return '-';
    return s;
  }

  @override
  Widget build(BuildContext context) {
    final id = row['id']?.toString() ?? '-';

    return Container(
      margin: const EdgeInsets.symmetric(horizontal: 8),
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: const Color(0xFFEAEAEA)),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Expanded(
                child: Text(
                  '${_nullableString(row['insurer'])} | ${_nullableString(row['vehicle_type'])}',
                  style: GoogleFonts.poppins(
                    fontSize: 13,
                    fontWeight: FontWeight.w500,
                  ),
                  overflow: TextOverflow.ellipsis,
                ),
              ),
              Text(
                'ID: $id',
                style: GoogleFonts.poppins(
                  fontSize: 10,
                  color: const Color(0xFF6E6E6E),
                ),
              ),
            ],
          ),
          const SizedBox(height: 10),
          Text('Segment: ${_nullableString(row['segment'])}',
              style: GoogleFonts.inter(fontSize: 12)),
          const SizedBox(height: 6),
          Text('RTO: ${_nullableString(row['rto'])}',
              style: GoogleFonts.inter(fontSize: 12)),
          const SizedBox(height: 10),
          Row(
            children: [
              Expanded(child: _metric('Comp', row['comp'])),
              const SizedBox(width: 10),
              Expanded(child: _metric('TP', row['tp'])),
              const SizedBox(width: 10),
              Expanded(child: _metric('OD', row['od'])),
            ],
          ),
          const SizedBox(height: 10),
          Text('Remarks: ${_nullableString(row['remarks'])}',
              style: GoogleFonts.inter(fontSize: 12)),
        ],
      ),
    );
  }

  Widget _metric(String label, dynamic value) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
      decoration: BoxDecoration(
        color: const Color(0xFFF8FAFC),
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: const Color(0xFFE2E8F0)),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            label,
            style: GoogleFonts.poppins(
              fontSize: 10,
              color: const Color(0xFF64748B),
            ),
          ),
          const SizedBox(height: 2),
          Text(
            _nullableString(value),
            style: GoogleFonts.poppins(
              fontSize: 12,
              fontWeight: FontWeight.w600,
            ),
          ),
        ],
      ),
    );
  }
}
/* 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:nhance_partner/core/services/api_service.dart';
import 'package:nhance_partner/data/utils/Pagination.dart';
import 'package:nhance_partner/data/utils/toastNotification.dart';
import 'package:nhance_partner/presentation/layouts/main_layout.dart';
import 'package:nhance_partner/presentation/layouts/responsive_layout.dart';
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
import 'package:nhance_partner/presentation/screens/UserManagement/Agent/agentGridFile.dart';
import 'package:nhance_partner/presentation/themes/indicators/export_btn.dart';
import 'package:nhance_partner/presentation/themes/indicators/input_field_decoration.dart';
import 'package:nhance_partner/presentation/themes/indicators/search_field_theme.dart';

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

  @override
  ConsumerState<gridViewScreen> createState() => _gridViewScreenState();
}

class _gridViewScreenState extends ConsumerState<gridViewScreen> {
  final ApiService _apiService = ApiService();

  bool _isLoading = false;

  // API response
  List<Map<String, dynamic>> _grid = [];
  List<Map<String, dynamic>> _filteredGrid = [];

  List<String> _insurers = [];
  List<Map<String, dynamic>> _planTypes = [];
  List<String> _rtos = [];
  List<String> _vehicleTypes = [];
  List<String> _segments = [];

  // Filters
  String? _selectedInsurer;
  String? _selectedRto;
  String? _selectedVehicleType;
  String? _selectedSegment;
  String? _selectedPlanTypeValue; // comp/tp/od

  final TextEditingController _searchController = TextEditingController();

  // Pagination
  int _currentPage = 1;
  int _itemsPerPage = 10;

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

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

  String? _apiRoleFromAppRole(String? role) {
    if (role == null) return null;
    final r = role.trim();
    if (r.isEmpty) return null;

    switch (r.toLowerCase()) {
      case 'manager':
        return 'Manager';
      case 'handler':
        return 'Handler';
      case 'staff':
        return 'Staff';
      case 'agent':
        return 'Agent';
      case 'accounts':
        return 'Accounts';
      default:
        return r;
    }
  }

  Future<void> _fetch() async {
    setState(() => _isLoading = true);
    try {
      final appRole = ref.read(userRoleProvider);
      final apiRole = _apiRoleFromAppRole(appRole);
      final queryParams = Uri.base.queryParameters;
      final queryRole = queryParams['role']?.trim();
      final queryFileId = queryParams['file_id']?.trim();
      final effectiveRole =
          (queryRole != null && queryRole.isNotEmpty) ? queryRole : apiRole;
      String? effectiveFileId =
          (queryFileId != null && queryFileId.isNotEmpty) ? queryFileId : null;

      if (effectiveFileId == null &&
          (effectiveRole?.toLowerCase() == 'manager' ||
              effectiveRole?.toLowerCase() == 'accounts')) {
        final fileListRes = await _apiService.fetchGridFileList();
        if ((fileListRes['status'] ?? '').toString().toLowerCase() ==
            'success') {
          final files = List<Map<String, dynamic>>.from(
            fileListRes['data'] ?? const [],
          );
          if (files.isNotEmpty) {
            files.sort((a, b) {
              final left = int.tryParse(a['id']?.toString() ?? '') ?? 0;
              final right = int.tryParse(b['id']?.toString() ?? '') ?? 0;
              return right.compareTo(left);
            });
            effectiveFileId = files.first['id']?.toString();
          }
        }
      }

      final loggedIdForGrid =
          (effectiveRole ?? '').toLowerCase() == 'agent' ? _loggedId : null;

      final res = await _apiService.loadPayoutGrid(
        role: effectiveRole,
        fileId: effectiveFileId,
        loggedId: loggedIdForGrid,
      );
      if ((res['status'] ?? '').toString().toLowerCase() != 'success') {
        ToastHelper.showErrorToast(
          context,
          res['data']?.toString() ?? 'Failed to load payout grid',
        );
        return;
      }

      final grid = res['grid'];
      final insurers = res['insurers'];
      final planTypes = res['plan_types'];
      final rtos = res['rtos'];
      final vehicleTypes = res['vehicle_types'];
      final segments = res['segments'];

      _grid = (grid is List)
          ? grid
              .map<Map<String, dynamic>>(
                  (e) => (e as Map).cast<String, dynamic>())
              .toList()
          : <Map<String, dynamic>>[];
      _filteredGrid = List<Map<String, dynamic>>.from(_grid);

      _insurers = insurers is List ? insurers.map((e) => e.toString()).toList() : [];
      _planTypes = planTypes is List
          ? planTypes
              .map<Map<String, dynamic>>(
                  (e) => (e as Map).cast<String, dynamic>())
              .toList()
          : [];
      _rtos = rtos is List ? rtos.map((e) => e.toString()).toList() : [];
      _vehicleTypes =
          vehicleTypes is List ? vehicleTypes.map((e) => e.toString()).toList() : [];
      _segments =
          segments is List ? segments.map((e) => e.toString()).toList() : [];

      _applyFilters();
    } catch (e) {
      ToastHelper.showErrorToast(context, e.toString());
    } finally {
      if (mounted) setState(() => _isLoading = false);
    }
  }

  void _setFilter(VoidCallback fn) {
    fn();
    _applyFilters();
  }

  void _applyFilters() {
    final q = _searchController.text.trim().toLowerCase();

    final next = _grid.where((row) {
      bool equalsOrAll(String? selected, dynamic raw) {
        if (selected == null) return true;
        return raw?.toString().toLowerCase() == selected.toLowerCase();
      }

      bool matchesPlanType() {
        if (_selectedPlanTypeValue == null) return true;
        final raw = row[_selectedPlanTypeValue];
        if (raw == null) return false;
        final s = raw.toString().trim().toLowerCase();
        return s.isNotEmpty && s != 'null';
      }

      bool matchesSearch() {
        if (q.isEmpty) return true;
        final values = <String>[
          row['id']?.toString() ?? '',
          row['insurer']?.toString() ?? '',
          row['vehicle_type']?.toString() ?? '',
          row['segment']?.toString() ?? '',
          row['rto']?.toString() ?? '',
          row['remarks']?.toString() ?? '',
          row['comp']?.toString() ?? '',
          row['tp']?.toString() ?? '',
          row['od']?.toString() ?? '',
        ].map((e) => e.toLowerCase());

        return values.any((v) => v.contains(q));
      }

      return equalsOrAll(_selectedInsurer, row['insurer']) &&
          equalsOrAll(_selectedVehicleType, row['vehicle_type']) &&
          equalsOrAll(_selectedSegment, row['segment']) &&
          equalsOrAll(_selectedRto, row['rto']) &&
          matchesPlanType() &&
          matchesSearch();
    }).toList();

    setState(() {
      _filteredGrid = next;
      _currentPage = 1;
    });
  }

  List<Map<String, dynamic>> get _sortedGrid {
    final next = [..._filteredGrid];
    next.sort((a, b) {
      final ai = int.tryParse(a['id']?.toString() ?? '') ?? 0;
      final bi = int.tryParse(b['id']?.toString() ?? '') ?? 0;
      return bi.compareTo(ai);
    });
    return next;
  }

  List<Map<String, dynamic>> get _paginatedGrid {
    final sorted = _sortedGrid;
    if (sorted.isEmpty) return [];

    final maxPage = (sorted.length / _itemsPerPage).ceil();
    final safePage =
        _currentPage.clamp(1, maxPage == 0 ? 1 : maxPage) as int;

    final startIndex = (safePage - 1) * _itemsPerPage;
    final endIndex = (startIndex + _itemsPerPage).clamp(0, sorted.length);
    return sorted.sublist(startIndex, endIndex);
  }

  String _nullableString(dynamic v) {
    if (v == null) return '-';
    final s = v.toString().trim();
    if (s.isEmpty || s.toLowerCase() == 'null') return '-';
    return s;
  }

  @override
  Widget build(BuildContext context) {
    return MainLayout(
      title: 'Grid Details',
      body: SelectionArea(
        child: Container(
          padding: const EdgeInsets.all(8),
          child: Column(
            children: [
              _buildTopBar(context),
              const SizedBox(height: 10),
              _buildFilterBar(context),
              const SizedBox(height: 10),
              Expanded(
                child: _isLoading
                    ? const Center(child: CircularProgressIndicator())
                    : _buildGridOrCards(context),
              ),
              PaginationControls(
                currentPage: _currentPage,
                itemsPerPage: _itemsPerPage,
                totalItems: _filteredGrid.length,
                onPageChanged: (page) => setState(() => _currentPage = page),
                onItemsPerPageChanged: (items) {
                  setState(() {
                    _itemsPerPage = items;
                    _currentPage = 1;
                  });
                },
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildTopBar(BuildContext context) {
    final isAgent =
        (ref.watch(userRoleProvider) ?? '').toString().trim().toLowerCase() ==
        'agent';
    return Row(
      children: [
        if (!isAgent) ...[
          Tooltip(
            message: 'Back',
            child: IconButton(
              icon: const Icon(Icons.arrow_left_sharp, size: 25),
              onPressed: () => context.go(AppRoutes.gridList),
              splashRadius: 18,
              padding: const EdgeInsets.all(4),
              hoverColor: Colors.black12,
              constraints: const BoxConstraints(),
            ),
          ),
          const SizedBox(width: 5),
        ],
        Text(
          'Grid Details',
          style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.w400),
        ),
        const Spacer(),
        ExportBtn(
          sheetName: 'Grid Details',
          fileName: 'payout_grid',
          data: _filteredGrid,
          displayHeaders: const [
            'ID',
            'Insurer',
            'Vehicle Type',
            'Segment',
            'RTO',
            'Comp',
            'TP',
            'OD',
            'Remarks',
          ],
          keys: const [
            'id',
            'insurer',
            'vehicle_type',
            'segment',
            'rto',
            'comp',
            'tp',
            'od',
            'remarks',
          ],
        ),
      ],
    );
  }

  Widget _buildFilterBar(BuildContext context) {
    final isMobile = ResponsiveLayout.isMobile(context);
    final screenWidth = MediaQuery.of(context).size.width;
    final isCompactFilter = !isMobile && screenWidth <= 1400;
    final fieldHeight = isCompactFilter ? 36.0 : 40.0;
    final fieldFontSize = isCompactFilter ? 11.0 : 12.0;
    final fieldSpacing = isCompactFilter ? 8.0 : 12.0;
    final filterHorizontalPadding = isCompactFilter ? 10.0 : 12.0;
    final filterVerticalPadding = isCompactFilter ? 8.0 : 10.0;

    final planTypeItems = <Map<String, dynamic>>[
      {'value': null, 'label': 'All'},
      ..._planTypes,
    ];

    Widget dropdownInsurer() {
      return SizedBox(
        width: isMobile ? double.infinity : 200,
        height: 40,
        child: DropdownSearch<String>(
          items: (filter, infiniteScrollProps) {
            final items = _insurers;
            if (filter.isEmpty) return items;
            return items
                .where((e) => e.toLowerCase().contains(filter.toLowerCase()))
                .toList();
          },
          selectedItem: _selectedInsurer,
          popupProps: const PopupProps.menu(
            showSearchBox: true,
            fit: FlexFit.loose,
          ),
          dropdownBuilder: (context, selectedItem) => Padding(
            padding: const EdgeInsets.only(left: 10),
            child: Text(
              selectedItem ?? 'All',
              style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
              overflow: TextOverflow.ellipsis,
            ),
          ),
          onChanged: (val) => _setFilter(() => _selectedInsurer = val),
          decoratorProps: DropDownDecoratorProps(
            decoration: AppInputDecorations.dropdownDecoration(label: 'Insurer')
                .copyWith(filled: true, fillColor: Colors.white, isDense: true),
          ),
          compareFn: (a, b) => a == b,
        ),
      );
    }

    Widget dropdownPlanType() {
      return SizedBox(
        width: isMobile ? double.infinity : 220,
        height: 40,
        child: DropdownSearch<Map<String, dynamic>>(
          items: (filter, infiniteScrollProps) {
            final items = planTypeItems;
            if (filter.isEmpty) return items;
            return items
                .where((e) =>
                    (e['label']?.toString() ?? '')
                        .toLowerCase()
                        .contains(filter.toLowerCase()))
                .toList();
          },
          selectedItem: planTypeItems.firstWhere(
            (e) => (e['value'] as String?) == _selectedPlanTypeValue,
            orElse: () => planTypeItems.first,
          ),
          itemAsString: (item) => item['label']?.toString() ?? '',
          compareFn: (a, b) => (a['value'] == b['value']),
          popupProps: const PopupProps.menu(
            showSearchBox: true,
            fit: FlexFit.loose,
          ),
          dropdownBuilder: (context, selectedItem) => Padding(
            padding: const EdgeInsets.only(left: 10),
            child: Text(
              selectedItem?['label']?.toString() ?? 'All',
              style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
              overflow: TextOverflow.ellipsis,
            ),
          ),
          onChanged: (val) => _setFilter(() {
            _selectedPlanTypeValue = val?['value'] as String?;
          }),
          decoratorProps: DropDownDecoratorProps(
            decoration:
                AppInputDecorations.dropdownDecoration(label: 'Plan Type')
                    .copyWith(filled: true, fillColor: Colors.white, isDense: true),
          ),
        ),
      );
    }

    Widget dropdownRto() {
      return SizedBox(
        width: isMobile ? double.infinity : 180,
        height: 40,
        child: DropdownSearch<String>(
          items: (filter, infiniteScrollProps) {
            final items = _rtos;
            if (filter.isEmpty) return items;
            return items
                .where((e) => e.toLowerCase().contains(filter.toLowerCase()))
                .toList();
          },
          selectedItem: _selectedRto,
          popupProps: const PopupProps.menu(
            showSearchBox: true,
            fit: FlexFit.loose,
          ),
          dropdownBuilder: (context, selectedItem) => Padding(
            padding: const EdgeInsets.only(left: 10),
            child: Text(
              selectedItem ?? 'All',
              style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
              overflow: TextOverflow.ellipsis,
            ),
          ),
          onChanged: (val) => _setFilter(() => _selectedRto = val),
          decoratorProps: DropDownDecoratorProps(
            decoration: AppInputDecorations.dropdownDecoration(label: 'RTO')
                .copyWith(filled: true, fillColor: Colors.white, isDense: true),
          ),
          compareFn: (a, b) => a == b,
        ),
      );
    }

    Widget dropdownVehicleType() {
      return SizedBox(
        width: isMobile ? double.infinity : 200,
        height: 40,
        child: DropdownSearch<String>(
          items: (filter, infiniteScrollProps) {
            final items = _vehicleTypes;
            if (filter.isEmpty) return items;
            return items
                .where((e) => e.toLowerCase().contains(filter.toLowerCase()))
                .toList();
          },
          selectedItem: _selectedVehicleType,
          popupProps: const PopupProps.menu(
            showSearchBox: true,
            fit: FlexFit.loose,
          ),
          dropdownBuilder: (context, selectedItem) => Padding(
            padding: const EdgeInsets.only(left: 10),
            child: Text(
              selectedItem ?? 'All',
              style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
              overflow: TextOverflow.ellipsis,
            ),
          ),
          onChanged: (val) => _setFilter(() => _selectedVehicleType = val),
          decoratorProps: DropDownDecoratorProps(
            decoration:
                AppInputDecorations.dropdownDecoration(label: 'Vehicle Type')
                    .copyWith(filled: true, fillColor: Colors.white, isDense: true),
          ),
          compareFn: (a, b) => a == b,
        ),
      );
    }

    Widget dropdownSegment() {
      return SizedBox(
        width: isMobile ? double.infinity : 220,
        height: 40,
        child: DropdownSearch<String>(
          items: (filter, infiniteScrollProps) {
            final items = _segments;
            if (filter.isEmpty) return items;
            return items
                .where((e) => e.toLowerCase().contains(filter.toLowerCase()))
                .toList();
          },
          selectedItem: _selectedSegment,
          popupProps: const PopupProps.menu(
            showSearchBox: true,
            fit: FlexFit.loose,
          ),
          dropdownBuilder: (context, selectedItem) => Padding(
            padding: const EdgeInsets.only(left: 10),
            child: Text(
              selectedItem ?? 'All',
              style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
              overflow: TextOverflow.ellipsis,
            ),
          ),
          onChanged: (val) => _setFilter(() => _selectedSegment = val),
          decoratorProps: DropDownDecoratorProps(
            decoration: AppInputDecorations.dropdownDecoration(label: 'Segment')
                .copyWith(filled: true, fillColor: Colors.white, isDense: true),
          ),
          compareFn: (a, b) => a == b,
        ),
      );
    }

    Widget resetBtn() {
      return SizedBox(
        height: 40,
        child: ElevatedButton.icon(
          style: ElevatedButton.styleFrom(
            backgroundColor: const Color(0xFF2E7D6E),
            foregroundColor: Colors.white,
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
          ),
          onPressed: () => setState(() {
            _selectedInsurer = null;
            _selectedPlanTypeValue = null;
            _selectedRto = null;
            _selectedVehicleType = null;
            _selectedSegment = null;
            _searchController.clear();
            _applyFilters();
          }),
          icon: const Icon(Icons.refresh, size: 18),
          label: Text(
            'Reset',
            style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w500),
          ),
        ),
      );
    }

    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: const Color(0xFFE5E7EB)),
      ),
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
      child: isMobile
          ? Column(
              children: [
                _buildSearch(context, isMobile),
                const SizedBox(height: 10),
                dropdownInsurer(),
                const SizedBox(height: 10),
                dropdownPlanType(),
                const SizedBox(height: 10),
                dropdownVehicleType(),
                const SizedBox(height: 10),
                dropdownSegment(),
                const SizedBox(height: 10),
                dropdownRto(),
                const SizedBox(height: 10),
                resetBtn(),
              ],
            )
          : SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              child: Row(
                children: [
                  _buildSearch(context, isMobile),
                  const SizedBox(width: 12),
                  dropdownInsurer(),
                  const SizedBox(width: 12),
                  dropdownPlanType(),
                  const SizedBox(width: 12),
                  dropdownVehicleType(),
                  const SizedBox(width: 12),
                  dropdownSegment(),
                  const SizedBox(width: 12),
                  dropdownRto(),
                  const SizedBox(width: 12),
                  resetBtn(),
                ],
              ),
            ),
    );
  }

  Widget _buildSearch(BuildContext context, bool isMobile) {
    return ThemedSearchField(
      hintText: 'Search...',
      controller: _searchController,
      txtHeight: 40,
      txtwidth: isMobile ? null : 240,
      backgroundColor: Colors.white,
      onChanged: (_) => _applyFilters(),
    );
  }

  Widget _buildGridOrCards(BuildContext context) {
    if (_paginatedGrid.isEmpty) {
      return const Center(child: Text('No available data'));
    }

    if (ResponsiveLayout.isMobile(context)) {
      return ListView.separated(
        padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
        itemCount: _paginatedGrid.length,
        separatorBuilder: (context, index) => const SizedBox(height: 10),
        itemBuilder: (context, index) => _gridViewCard(row: _paginatedGrid[index]),
      );
    }

    return ListView.builder(
      itemCount: _paginatedGrid.length + 1,
      itemBuilder: (context, index) {
        if (index == 0) return _buildTableHeader();
        final rowIndex = index - 1;
        return _buildTableRow(_paginatedGrid[rowIndex], rowIndex: rowIndex);
      },
    );
  }

  Widget _buildTableHeader() {
    return Container(
      decoration: const BoxDecoration(
        border: Border(
          bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1),
        ),
      ),
      padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
      child: Row(
        children: [
          Expanded(flex: 1, child: Text('S.No', style: _headerStyle)),
          Expanded(flex: 2, child: Text('Insurer', style: _headerStyle)),
          Expanded(flex: 2, child: Text('Vehicle', style: _headerStyle)),
          Expanded(flex: 3, child: Text('Segment', style: _headerStyle)),
          Expanded(flex: 2, child: Text('RTO', style: _headerStyle)),
          Expanded(flex: 2, child: Text('Comp', style: _headerStyle)),
          Expanded(flex: 2, child: Text('TP', style: _headerStyle)),
          Expanded(flex: 2, child: Text('OD', style: _headerStyle)),
          Expanded(flex: 3, child: Text('Remarks', style: _headerStyle)),
        ],
      ),
    );
  }

  Widget _buildTableRow(Map<String, dynamic> row, {required int rowIndex}) {
    final sno = (_currentPage - 1) * _itemsPerPage + rowIndex + 1;

    return Container(
      padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
      decoration: const BoxDecoration(
        border: Border(
          bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1),
        ),
      ),
      child: Row(
        children: [
          Expanded(flex: 1, child: Text('$sno', style: _dataBold)),
          Expanded(flex: 2, child: Text(_nullableString(row['insurer']), style: _dataBold)),
          Expanded(flex: 2, child: Text(_nullableString(row['vehicle_type']), style: _dataBold)),
          Expanded(
            flex: 3,
            child: Text(
              _nullableString(row['segment']),
              style: _dataBold,
              overflow: TextOverflow.ellipsis,
            ),
          ),
          Expanded(flex: 2, child: Text(_nullableString(row['rto']), style: _dataBold)),
          Expanded(flex: 2, child: Text(_nullableString(row['comp']), style: _dataBold)),
          Expanded(flex: 2, child: Text(_nullableString(row['tp']), style: _dataBold)),
          Expanded(flex: 2, child: Text(_nullableString(row['od']), style: _dataBold)),
          Expanded(
            flex: 3,
            child: Text(
              _nullableString(row['remarks']),
              style: _dataBold,
              overflow: TextOverflow.ellipsis,
            ),
          ),
        ],
      ),
    );
  }

  static final _headerStyle = GoogleFonts.poppins(
    fontSize: 11.2,
    fontWeight: FontWeight.w500,
    color: const Color(0xFF1E293B),
  );

  static final _dataBold = GoogleFonts.inter(
    fontSize: 11,
    fontWeight: FontWeight.w400,
    color: const Color(0xFF000000),
  );
}

class _gridViewCard extends StatelessWidget {
  final Map<String, dynamic> row;

  const _gridViewCard({required this.row});

  String _nullableString(dynamic v) {
    if (v == null) return '-';
    final s = v.toString().trim();
    if (s.isEmpty || s.toLowerCase() == 'null') return '-';
    return s;
  }

  @override
  Widget build(BuildContext context) {
    final id = row['id']?.toString() ?? '-';

    return Container(
      margin: const EdgeInsets.symmetric(horizontal: 8),
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: const Color(0xFFEAEAEA)),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Expanded(
                child: Text(
                  '${_nullableString(row['insurer'])} | ${_nullableString(row['vehicle_type'])}',
                  style: GoogleFonts.poppins(
                    fontSize: 13,
                    fontWeight: FontWeight.w500,
                  ),
                  overflow: TextOverflow.ellipsis,
                ),
              ),
              Text(
                'ID: $id',
                style: GoogleFonts.poppins(
                  fontSize: 10,
                  color: const Color(0xFF6E6E6E),
                ),
              ),
            ],
          ),
          const SizedBox(height: 10),
          Text('Segment: ${_nullableString(row['segment'])}',
              style: GoogleFonts.inter(fontSize: 12)),
          const SizedBox(height: 6),
          Text('RTO: ${_nullableString(row['rto'])}',
              style: GoogleFonts.inter(fontSize: 12)),
          const SizedBox(height: 10),
          Row(
            children: [
              Expanded(child: _metric('Comp', row['comp'])),
              const SizedBox(width: 10),
              Expanded(child: _metric('TP', row['tp'])),
              const SizedBox(width: 10),
              Expanded(child: _metric('OD', row['od'])),
            ],
          ),
          const SizedBox(height: 10),
          Text('Remarks: ${_nullableString(row['remarks'])}',
              style: GoogleFonts.inter(fontSize: 12)),
        ],
      ),
    );
  }

  Widget _metric(String label, dynamic value) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
      decoration: BoxDecoration(
        color: const Color(0xFFF8FAFC),
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: const Color(0xFFE2E8F0)),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(label,
              style: GoogleFonts.poppins(
                fontSize: 10,
                color: const Color(0xFF64748B),
              )),
          const SizedBox(height: 2),
          Text(
            _nullableString(value),
            style: GoogleFonts.poppins(
              fontSize: 12,
              fontWeight: FontWeight.w600,
            ),
          ),
        ],
      ),
    );
  }
}

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:nhance_partner/core/services/api_service.dart';
import 'package:nhance_partner/data/utils/toastNotification.dart';
import 'package:nhance_partner/data/utils/Pagination.dart';
import 'package:nhance_partner/presentation/layouts/main_layout.dart';
import 'package:nhance_partner/presentation/layouts/responsive_layout.dart';
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
import 'package:nhance_partner/presentation/themes/indicators/input_field_decoration.dart';
import 'package:nhance_partner/presentation/themes/indicators/search_field_theme.dart';
import 'package:nhance_partner/presentation/themes/indicators/export_btn.dart';
import 'package:nhance_partner/presentation/screens/UserManagement/Agent/agentGridFile.dart';

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

  @override
  ConsumerState<gridViewScreen> createState() => _gridViewScreenState();
}

class _gridViewScreenState extends ConsumerState<gridViewScreen> {
  final ApiService _apiService = ApiService();

  bool _isLoading = false;

  // API response
  List<Map<String, dynamic>> _grid = [];
  List<Map<String, dynamic>> _filteredGrid = [];

  List<String> _insurers = [];
  List<Map<String, dynamic>> _planTypes = [];
  List<String> _rtos = [];
  List<String> _vehicleTypes = [];
  List<String> _segments = [];

  // Filters
  String? _selectedInsurer;
  String? _selectedRto;
  String? _selectedVehicleType;
  String? _selectedSegment;
  String? _selectedPlanTypeValue; // comp/tp/od

  final TextEditingController _searchController = TextEditingController();

  // Pagination
  int _currentPage = 1;
  int _itemsPerPage = 10;

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

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

  String? _apiRoleFromAppRole(String? role) {
    if (role == null) return null;
    final r = role.trim();
    if (r.isEmpty) return null;

    // API expects capitalized role names (example: role=Manager)
    switch (r.toLowerCase()) {
      case 'manager':
        return 'Manager';
      case 'handler':
        return 'Handler';
      case 'staff':
        return 'Staff';
      case 'agent':
        return 'Agent';
      case 'accounts':
        return 'Accounts';
      default:
        // fallback: keep original capitalization
        return r;
    }
  }

  Future<void> _fetch() async {
    setState(() => _isLoading = true);
    try {
      final appRole = ref.read(userRoleProvider);
      final apiRole = _apiRoleFromAppRole(appRole);
      final queryParams = Uri.base.queryParameters;
      final queryRole = queryParams['role']?.trim();
      final queryFileId = queryParams['file_id']?.trim();
      final effectiveRole =
          (queryRole != null && queryRole.isNotEmpty) ? queryRole : apiRole;
      String? effectiveFileId =
          (queryFileId != null && queryFileId.isNotEmpty) ? queryFileId : null;

      if (effectiveFileId == null &&
          (effectiveRole?.toLowerCase() == 'manager' ||
              effectiveRole?.toLowerCase() == 'accounts')) {
        final fileListRes = await _apiService.fetchGridFileList();
        if ((fileListRes['status'] ?? '').toString().toLowerCase() ==
            'success') {
          final files = List<Map<String, dynamic>>.from(
            fileListRes['data'] ?? const [],
          );
          if (files.isNotEmpty) {
            files.sort((a, b) {
              final left = int.tryParse(a['id']?.toString() ?? '') ?? 0;
              final right = int.tryParse(b['id']?.toString() ?? '') ?? 0;
              return right.compareTo(left);
            });
            effectiveFileId = files.first['id']?.toString();
          }
        }
      }

      final loggedIdForGrid =
          (effectiveRole ?? '').toLowerCase() == 'agent' ? _loggedId : null;

      final res = await _apiService.loadPayoutGrid(
        role: effectiveRole,
        fileId: effectiveFileId,
        loggedId: loggedIdForGrid,
      );

      if ((res['status'] ?? '').toString().toLowerCase() != 'success') {
        ToastHelper.showErrorToast(
          context,
          res['data']?.toString() ?? 'Failed to load payout grid',
        );
        return;
      }

      final grid = res['grid'];
      final insurers = res['insurers'];
      final planTypes = res['plan_types'];
      final rtos = res['rtos'];
      final vehicleTypes = res['vehicle_types'];
      final segments = res['segments'];

      _grid = (grid is List)
          ? grid.map<Map<String, dynamic>>((e) => (e as Map).cast<String, dynamic>()).toList()
          : <Map<String, dynamic>>[];
      _filteredGrid = List<Map<String, dynamic>>.from(_grid);

      _insurers = insurers is List ? insurers.map((e) => e.toString()).toList() : [];
      _planTypes = planTypes is List
          ? planTypes
              .map<Map<String, dynamic>>((e) => (e as Map).cast<String, dynamic>())
              .toList()
          : [];
      _rtos = rtos is List ? rtos.map((e) => e.toString()).toList() : [];
      _vehicleTypes = vehicleTypes is List ? vehicleTypes.map((e) => e.toString()).toList() : [];
      _segments = segments is List ? segments.map((e) => e.toString()).toList() : [];

      // Ensure filters apply after fresh data load.
      _applyFilters();
    } catch (e) {
      ToastHelper.showErrorToast(context, e.toString());
    } finally {
      if (mounted) setState(() => _isLoading = false);
    }
  }

  void _applyFilters() {
    final q = _searchController.text.trim().toLowerCase();

    List<Map<String, dynamic>> next = _grid.where((row) {
      bool matchesInsurer() {
        if (_selectedInsurer == null) return true;
        return row['insurer']?.toString().toLowerCase() == _selectedInsurer!.toLowerCase();
      }

      bool matchesRto() {
        if (_selectedRto == null) return true;
        return row['rto']?.toString().toLowerCase() == _selectedRto!.toLowerCase();
      }

      bool matchesVehicleType() {
        if (_selectedVehicleType == null) return true;
        return row['vehicle_type']?.toString().toLowerCase() == _selectedVehicleType!.toLowerCase();
      }

      bool matchesSegment() {
        if (_selectedSegment == null) return true;
        return row['segment']?.toString().toLowerCase() == _selectedSegment!.toLowerCase();
      }

      bool matchesPlanType() {
        if (_selectedPlanTypeValue == null) return true;
        final v = _selectedPlanTypeValue!;
        final raw = row[v];
        if (raw == null) return false;
        final s = raw.toString().trim().toLowerCase();
        if (s.isEmpty || s == 'null') return false;
        // Treat 0 as "not configured" only when backend returns 0.
        return s != '0';
      }

      bool matchesSearch() {
        if (q.isEmpty) return true;

        final id = row['id']?.toString().toLowerCase() ?? '';
        final insurer = row['insurer']?.toString().toLowerCase() ?? '';
        final vehicleType = row['vehicle_type']?.toString().toLowerCase() ?? '';
        final segment = row['segment']?.toString().toLowerCase() ?? '';
        final rto = row['rto']?.toString().toLowerCase() ?? '';
        final remarks = row['remarks']?.toString().toLowerCase() ?? '';
        final comp = row['comp']?.toString().toLowerCase() ?? '';
        final tp = row['tp']?.toString().toLowerCase() ?? '';
        final od = row['od']?.toString().toLowerCase() ?? '';

        return [id, insurer, vehicleType, segment, rto, remarks, comp, tp, od].any((s) => s.contains(q));
      }

      return matchesInsurer() &&
          matchesRto() &&
          matchesVehicleType() &&
          matchesSegment() &&
          matchesPlanType() &&
          matchesSearch();
    }).toList();

    setState(() {
      _filteredGrid = next;
      _currentPage = 1;
    });
  }

  List<Map<String, dynamic>> get _sortedGrid {
    final next = [..._filteredGrid];
    next.sort((a, b) {
      final ai = int.tryParse(a['id']?.toString() ?? '') ?? 0;
      final bi = int.tryParse(b['id']?.toString() ?? '') ?? 0;
      return bi.compareTo(ai);
    });
    return next;
  }

  List<Map<String, dynamic>> get _paginatedGrid {
    final sorted = _sortedGrid;
    if (sorted.isEmpty) return [];

    final maxPage = (sorted.length / _itemsPerPage).ceil();
    final safePage = _currentPage.clamp(1, maxPage == 0 ? 1 : maxPage);

    final startIndex = (safePage - 1) * _itemsPerPage;
    final endIndex = (startIndex + _itemsPerPage).clamp(0, sorted.length);
    return sorted.sublist(startIndex, endIndex);
  }

  void _setFilter(VoidCallback fn) {
    fn();
    _applyFilters();
  }

  String _nullableString(dynamic v) {
    if (v == null) return '-';
    final s = v.toString();
    if (s.trim().isEmpty || s.trim().toLowerCase() == 'null') return '-';
    return s;
  }

  @override
  Widget build(BuildContext context) {
    return MainLayout(
      title: 'Grid Details',
      body: SelectionArea(
        child: Container(
          padding: const EdgeInsets.all(8),
          child: Column(
            children: [
              _buildTopBar(context),
              const SizedBox(height: 10),
              _buildFilterBar(context),
              const SizedBox(height: 10),
              Expanded(
                child: _isLoading
                    ? const Center(child: CircularProgressIndicator())
                    : _buildGridOrCards(context),
              ),
              PaginationControls(
                currentPage: _currentPage,
                itemsPerPage: _itemsPerPage,
                totalItems: _filteredGrid.length,
                onPageChanged: (page) => setState(() => _currentPage = page),
                onItemsPerPageChanged: (items) {
                  setState(() {
                    _itemsPerPage = items;
                    _currentPage = 1;
                  });
                },
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildTopBar(BuildContext context) {
    final isMobile = ResponsiveLayout.isMobile(context);
    final isAgent =
        (ref.watch(userRoleProvider) ?? '').toString().trim().toLowerCase() ==
        'agent';

    return Row(
      children: [
        if (!isAgent) ...[
          Tooltip(
            message: 'Back',
            child: IconButton(
              icon: const Icon(Icons.arrow_left_sharp, size: 25),
              onPressed: () => context.go(AppRoutes.gridList),
              splashRadius: 18,
              padding: const EdgeInsets.all(4),
              hoverColor: Colors.black12,
              constraints: const BoxConstraints(),
            ),
          ),
          const SizedBox(width: 5),
        ],
        Text(
          'Grid Details',
          style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.w400),
        ),
        const Spacer(),
        if (!isMobile)
          ExportBtn(
            sheetName: 'Grid Details',
            fileName: 'payout_grid',
            data: _filteredGrid,
            displayHeaders: const [
              'ID',
              'Insurer',
              'Vehicle Type',
              'Segment',
              'RTO',
              'Comp',
              'TP',
              'OD',
              'Remarks',
            ],
            keys: const [
              'id',
              'insurer',
              'vehicle_type',
              'segment',
              'rto',
              'comp',
              'tp',
              'od',
              'remarks',
            ],
          ),
      ],
    );
  }

  Widget _buildFilterBar(BuildContext context) {
    final isMobile = ResponsiveLayout.isMobile(context);

    final planTypeItems = <Map<String, dynamic>>[
      {'value': null, 'label': 'All'},
      ..._planTypes,
    ];

    Widget dropdownInsurer() {
      return SizedBox(
        width: isMobile ? double.infinity : (isCompactFilter ? 180 : 200),
        height: fieldHeight,
        child: DropdownSearch<String>(
          items: _insurers,
          selectedItem: _selectedInsurer,
          dropdownSearchTextInputDecoration: InputDecoration(
            hintText: 'Search insurer...',
            contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
            isDense: true,
          ),
          dropdownBuilder: (context, selectedItem) => Padding(
            padding: const EdgeInsets.only(left: 10),
            child: Text(
              selectedItem ?? 'All',
              style: GoogleFonts.poppins(
                fontSize: fieldFontSize,
                color: Colors.black,
              ),
              overflow: TextOverflow.ellipsis,
            ),
          ),
          popupProps: const PopupProps.menu(
            showSearchBox: true,
          ),
          onChanged: (val) => _setFilter(() => _selectedInsurer = val),
          decoratorProps: DropDownDecoratorProps(
            decoration: AppInputDecorations.dropdownDecoration(label: 'Insurer')
                .copyWith(
                  filled: true,
                  fillColor: Colors.white,
                  isDense: true,
                  labelStyle: GoogleFonts.poppins(fontSize: fieldFontSize),
                ),
          ),
        ),
      );
    }

    Widget dropdownPlanType() {
      return SizedBox(
        width: isMobile ? double.infinity : (isCompactFilter ? 200 : 220),
        height: fieldHeight,
        child: DropdownSearch<Map<String, dynamic>>(
          items: planTypeItems,
          selectedItem: planTypeItems.firstWhere(
            (e) => (e['value'] as String?) == _selectedPlanTypeValue,
            orElse: () => planTypeItems.first,
          ),
          itemAsString: (v) => (v['label'] ?? '').toString(),
          compareFn: (a, b) => (a['value'] == b['value']),
          popupProps: const PopupProps.menu(showSearchBox: true),
          onChanged: (val) => _setFilter(() => _selectedPlanTypeValue = val?['value'] as String?),
          decoratorProps: DropDownDecoratorProps(
            decoration: AppInputDecorations.dropdownDecoration(label: 'Plan Type')
                .copyWith(
                  filled: true,
                  fillColor: Colors.white,
                  isDense: true,
                  labelStyle: GoogleFonts.poppins(fontSize: fieldFontSize),
                ),
          ),
        ),
      );
    }

    Widget dropdownRto() {
      return SizedBox(
        width: isMobile ? double.infinity : (isCompactFilter ? 160 : 180),
        height: fieldHeight,
        child: DropdownSearch<String>(
          items: _rtos,
          selectedItem: _selectedRto,
          popupProps: const PopupProps.menu(showSearchBox: true),
          dropdownSearchTextInputDecoration: InputDecoration(
            hintText: 'Search RTO...',
            contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
            isDense: true,
          ),
          onChanged: (val) => _setFilter(() => _selectedRto = val),
          decoratorProps: DropDownDecoratorProps(
            decoration: AppInputDecorations.dropdownDecoration(label: 'RTO')
                .copyWith(
                  filled: true,
                  fillColor: Colors.white,
                  isDense: true,
                  labelStyle: GoogleFonts.poppins(fontSize: fieldFontSize),
                ),
          ),
        ),
      );
    }

    Widget dropdownVehicleType() {
      return SizedBox(
        width: isMobile ? double.infinity : (isCompactFilter ? 180 : 200),
        height: fieldHeight,
        child: DropdownSearch<String>(
          items: _vehicleTypes,
          selectedItem: _selectedVehicleType,
          popupProps: const PopupProps.menu(showSearchBox: true),
          dropdownSearchTextInputDecoration: InputDecoration(
            hintText: 'Search vehicle type...',
            contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
            isDense: true,
          ),
          onChanged: (val) => _setFilter(() => _selectedVehicleType = val),
          decoratorProps: DropDownDecoratorProps(
            decoration: AppInputDecorations.dropdownDecoration(label: 'Vehicle Type')
                .copyWith(
                  filled: true,
                  fillColor: Colors.white,
                  isDense: true,
                  labelStyle: GoogleFonts.poppins(fontSize: fieldFontSize),
                ),
          ),
        ),
      );
    }

    Widget dropdownSegment() {
      return SizedBox(
        width: isMobile ? double.infinity : (isCompactFilter ? 200 : 220),
        height: fieldHeight,
        child: DropdownSearch<String>(
          items: _segments,
          selectedItem: _selectedSegment,
          popupProps: const PopupProps.menu(showSearchBox: true),
          dropdownSearchTextInputDecoration: InputDecoration(
            hintText: 'Search segment...',
            contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
            isDense: true,
          ),
          onChanged: (val) => _setFilter(() => _selectedSegment = val),
          decoratorProps: DropDownDecoratorProps(
            decoration: AppInputDecorations.dropdownDecoration(label: 'Segment')
                .copyWith(
                  filled: true,
                  fillColor: Colors.white,
                  isDense: true,
                  labelStyle: GoogleFonts.poppins(fontSize: fieldFontSize),
                ),
          ),
        ),
      );
    }

    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: const Color(0xFFE5E7EB)),
      ),
      padding: EdgeInsets.symmetric(
        horizontal: filterHorizontalPadding,
        vertical: filterVerticalPadding,
      ),
      child: isMobile
          ? Column(
              children: [
                _buildSearch(context, isCompact: isCompactFilter),
                const SizedBox(height: 10),
                dropdownInsurer(),
                const SizedBox(height: 10),
                dropdownPlanType(),
                const SizedBox(height: 10),
                dropdownVehicleType(),
                const SizedBox(height: 10),
                dropdownSegment(),
                const SizedBox(height: 10),
                dropdownRto(),
                const SizedBox(height: 10),
                _buildResetButton(),
              ],
            )
          : SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              child: Row(
                children: [
                  _buildSearch(context, isCompact: isCompactFilter),
                  SizedBox(width: fieldSpacing),
                  dropdownInsurer(),
                  SizedBox(width: fieldSpacing),
                  dropdownPlanType(),
                  SizedBox(width: fieldSpacing),
                  dropdownVehicleType(),
                  SizedBox(width: fieldSpacing),
                  dropdownSegment(),
                  SizedBox(width: fieldSpacing),
                  dropdownRto(),
                  SizedBox(width: fieldSpacing),
                  _buildResetButton(isCompact: isCompactFilter),
                ],
              ),
            ),
    );
  }

  Widget _buildSearch(BuildContext context, {bool isCompact = false}) {
    return ThemedSearchField(
      hintText: 'Search...',
      controller: _searchController,
      txtHeight: isCompact ? 36 : 40,
      txtwidth: ResponsiveLayout.isMobile(context)
          ? null
          : (isCompact ? 210 : 240),
      onChanged: (_) => _applyFilters(),
      backgroundColor: Colors.white,
    );
  }

  Widget _buildResetButton({bool isCompact = false}) {
    return SizedBox(
      height: isCompact ? 36 : 40,
      child: ElevatedButton.icon(
        style: ElevatedButton.styleFrom(
          backgroundColor: const Color(0xFF2E7D6E),
          foregroundColor: Colors.white,
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
        ),
        onPressed: () {
          _setFilter(() {
            _selectedInsurer = null;
            _selectedPlanTypeValue = null;
            _selectedRto = null;
            _selectedVehicleType = null;
            _selectedSegment = null;
            _searchController.clear();
          });
        },
        icon: Icon(Icons.refresh, size: isCompact ? 16 : 18),
        label: Text(
          'Reset',
          style: GoogleFonts.poppins(
            fontSize: isCompact ? 11 : 12,
            fontWeight: FontWeight.w500,
          ),
        ),
      ),
    );
  }

  Widget _buildGridOrCards(BuildContext context) {
    if (_paginatedGrid.isEmpty) {
      return const Center(child: Text('No available data'));
    }

    if (ResponsiveLayout.isMobile(context)) {
      return ListView.separated(
        padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
        itemCount: _paginatedGrid.length,
        separatorBuilder: (context, index) => const SizedBox(height: 10),
        itemBuilder: (context, index) {
          final row = _paginatedGrid[index];
          return _gridViewCard(row: row);
        },
      );
    }

    return ListView.builder(
      itemCount: _paginatedGrid.length + 1, // + header
      itemBuilder: (context, index) {
        if (index == 0) return _buildTableHeader();
        final rowIndex = index - 1;
        final row = _paginatedGrid[rowIndex];
        return _buildTableRow(row, rowIndex: rowIndex);
      },
    );
  }

  Widget _buildTableHeader() {
    return Container(
      decoration: const BoxDecoration(
        border: Border(
          bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1),
        ),
      ),
      padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
      child: Row(
        children: [
          Expanded(flex: 1, child: Text('S.No', style: _headerStyle)),
          Expanded(flex: 2, child: Text('Insurer', style: _headerStyle)),
          Expanded(flex: 2, child: Text('Vehicle', style: _headerStyle)),
          Expanded(flex: 3, child: Text('Segment', style: _headerStyle)),
          Expanded(flex: 2, child: Text('RTO', style: _headerStyle)),
          Expanded(flex: 2, child: Text('Comp', style: _headerStyle)),
          Expanded(flex: 2, child: Text('TP', style: _headerStyle)),
          Expanded(flex: 2, child: Text('OD', style: _headerStyle)),
          Expanded(flex: 3, child: Text('Remarks', style: _headerStyle)),
        ],
      ),
    );
  }

  Widget _buildTableRow(
    Map<String, dynamic> row, {
    required int rowIndex,
  }) {
    final sno = (_currentPage - 1) * _itemsPerPage + rowIndex + 1;

    return Container(
      padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
      decoration: const BoxDecoration(
        border: Border(
          bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1),
        ),
      ),
      child: Row(
        children: [
          Expanded(flex: 1, child: Text('$sno', style: _dataBold)),
          Expanded(flex: 2, child: Text(_nullableString(row['insurer']), style: _dataBold)),
          Expanded(flex: 2, child: Text(_nullableString(row['vehicle_type']), style: _dataBold)),
          Expanded(flex: 3, child: Text(_nullableString(row['segment']), style: _dataBold, overflow: TextOverflow.ellipsis)),
          Expanded(flex: 2, child: Text(_nullableString(row['rto']), style: _dataBold)),
          Expanded(flex: 2, child: Text(_nullableString(row['comp']), style: _dataBold)),
          Expanded(flex: 2, child: Text(_nullableString(row['tp']), style: _dataBold)),
          Expanded(flex: 2, child: Text(_nullableString(row['od']), style: _dataBold)),
          Expanded(flex: 3, child: Text(_nullableString(row['remarks']), style: _dataBold, overflow: TextOverflow.ellipsis)),
        ],
      ),
    );
  }

  static final _headerStyle = GoogleFonts.poppins(
    fontSize: 11.2,
    fontWeight: FontWeight.w500,
    color: const Color(0xFF1E293B),
  );

  static final _dataBold = GoogleFonts.inter(
    fontSize: 11,
    fontWeight: FontWeight.w400,
    color: const Color(0xFF000000),
  );
}

class _gridViewCard extends StatelessWidget {
  final Map<String, dynamic> row;

  const _gridViewCard({required this.row});

  String _nullableString(dynamic v) {
    if (v == null) return '-';
    final s = v.toString();
    if (s.trim().isEmpty || s.trim().toLowerCase() == 'null') return '-';
    return s;
  }

  @override
  Widget build(BuildContext context) {
    final id = row['id']?.toString() ?? '-';

    return Container(
      margin: const EdgeInsets.symmetric(horizontal: 8),
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: const Color(0xFFEAEAEA)),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Expanded(
                child: Text(
                  '${_nullableString(row['insurer'])} | ${_nullableString(row['vehicle_type'])}',
                  style: GoogleFonts.poppins(fontSize: 13, fontWeight: FontWeight.w500),
                  overflow: TextOverflow.ellipsis,
                ),
              ),
              Text(
                'ID: $id',
                style: GoogleFonts.poppins(fontSize: 10, color: const Color(0xFF6E6E6E)),
              ),
            ],
          ),
          const SizedBox(height: 10),
          Text('Segment: ${_nullableString(row['segment'])}', style: GoogleFonts.inter(fontSize: 12)),
          const SizedBox(height: 6),
          Text('RTO: ${_nullableString(row['rto'])}', style: GoogleFonts.inter(fontSize: 12)),
          const SizedBox(height: 10),
          Row(
            children: [
              Expanded(
                child: _metric('Comp', row['comp']),
              ),
              const SizedBox(width: 10),
              Expanded(
                child: _metric('TP', row['tp']),
              ),
              const SizedBox(width: 10),
              Expanded(
                child: _metric('OD', row['od']),
              ),
            ],
          ),
          const SizedBox(height: 10),
          Text('Remarks: ${_nullableString(row['remarks'])}', style: GoogleFonts.inter(fontSize: 12)),
        ],
      ),
    );
  }

  Widget _metric(String label, dynamic value) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
      decoration: BoxDecoration(
        color: const Color(0xFFF8FAFC),
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: const Color(0xFFE2E8F0)),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(label, style: GoogleFonts.poppins(fontSize: 10, color: const Color(0xFF64748B))),
          const SizedBox(height: 2),
          Text(_nullableString(value), style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600)),
        ],
      ),
    );
  }
}

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:go_router/go_router.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import 'package:nhance_partner/core/services/api_service.dart';
import 'package:nhance_partner/core/config/env.dart';
import 'package:nhance_partner/data/utils/toastNotification.dart';
import 'package:nhance_partner/data/services/auth_service.dart';
import 'package:nhance_partner/presentation/layouts/main_layout.dart';
import 'package:nhance_partner/presentation/providers/manager_provider.dart';
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
import 'package:nhance_partner/presentation/themes/indicators/date_field_theme.dart';
import 'package:nhance_partner/presentation/themes/indicators/search_field_theme.dart';
import 'package:nhance_partner/presentation/screens/UserManagement/Agent/agentGridFile.dart';

class gridViewScreen extends ConsumerStatefulWidget {
  const gridViewScreen({super.key});
  @override
  ConsumerState<gridViewScreen> createState() => gridViewScreenState();
}

class gridViewScreenState extends ConsumerState<gridViewScreen> {
  int currentPage = 1;
  int itemsPerPage = 10;
  late ApiService apiService;

  // List<Map<String, dynamic>> dataVal = [];
  List<Map<String, dynamic>> getStaffData = [];
  List<Map<String, dynamic>> originalData = [];
  List<Map<String, dynamic>> filteredData = [];
  bool isLoading = false;
  dynamic userId;
  dynamic roleId;
  dynamic managerId;

  // bool isDrawerOpen = false;
  Map<String, dynamic>? selectedRow;
  List<Map<String, dynamic>> endorsementNumbers = [];

  List<Map<String, dynamic>> getEndrosmentType = [];
  List<Map<String, dynamic>> filteredEndrosmentData = [];
  String? hoveredRowId;

  String? selectedFileNames;
  PlatformFile? docUploadedFile;
  String? lastPickedFile;


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

    apiService = ApiService();

    Future.microtask(() async {
      final id = ref.read(managerIdProvider);
      managerId = ref.read(managerIdProvider);
      roleId = ref.read(userRoleProvider);
      userId = ref.read(userIdProvider);
      print("F46 => r : $roleId | mId: $id | uId: $userId ");
      /// ⭐ DEFAULT FILTER FOR ACCOUNTS
      if (roleId == 'Accounts') {
        selectedVerificationVal = 0; // 0 = To Verify
      } else {
        selectedStatusVal = 'Open';
      }

      if (userId != null) {
       await getStaffList(managerId, userId, roleId);
      }
      getEnroementType();
      getInsurerDetails();
    });
  }

  Future<void> getStaffList(int managerId, userId, role) async {
    setState(() {
      isLoading = true;
    });

    print('fetchEndorsementList first $selectedVerificationVal');

    try {
      final response = await apiService.fetchEndorsementList(
        managerId,
        userId,
        role,

        fromDate: startController.text.isNotEmpty
            ? DateFormat('yyyy-MM-dd')
            .format(DateFormat('dd-MM-yyyy')
            .parse(startController.text))
            : null,

        toDate: endController.text.isNotEmpty
            ? DateFormat('yyyy-MM-dd')
            .format(DateFormat('dd-MM-yyyy')
            .parse(endController.text))
            : null,

        endorsementType:
        selectedEndorsementTypeVal?.toString(),

        insurerId:
        selectedInsurerVal?.toString(),

        status: selectedStatusVal == 'All'
            ? ''
            : selectedStatusVal == 'Open'
            ? 'Open'
            : selectedStatusVal == 'Closed'
            ? 'Closed'
            : null,


        verification: selectedVerificationVal == 2
            ? ''
            : selectedVerificationVal == 0
            ? 'To Verify'
            : selectedVerificationVal == 1
            ? 'Verified'
            : null,
        // selectedVerificationVal?.toString(),
      );
      print('fetchEndorsementList');

      if (response['status'] == 'success') {
        final data = response['data'];

        setState(() {
          if (data is List) {
            getStaffData =
            List<Map<String, dynamic>>.from(data);
          } else if (data is Map) {
            getStaffData = [
              Map<String, dynamic>.from(data)
            ];
          } else {
            getStaffData = [];
          }

          originalData = getStaffData;
          filteredData = List.from(originalData);
        });
      } else {
        getStaffData = [];
        originalData = [];
      }
    } catch (e) {
      print('Exception occurred: $e');
    } finally {
      setState(() {
        isLoading = false;
      });
    }
  }

  List<dynamic> get _paginatedData {
    // Sort descending by id first
    final sortedData = [...filteredData]
      ..sort((a, b) => int.parse(b['id']) - int.parse(a['id']));

    if (sortedData.isEmpty) return [];

    // Ensure currentPage is valid
    final maxPage = (sortedData.length / itemsPerPage).ceil();
    final safePage = currentPage.clamp(1, maxPage);

    final startIndex = (safePage - 1) * itemsPerPage;
    final endIndex = (startIndex + itemsPerPage).clamp(0, sortedData.length);

    return sortedData.sublist(startIndex, endIndex);
  }

  void refresh() {
    getStaffList(managerId, userId, roleId);
  }

  void filterData(String query) {
    final lowerQuery = query.toLowerCase();

    setState(() {
      filteredData = getStaffData.where((item) {

        /// 🔹 Search all raw values
        final matchesRawValues = item.values.any(
              (value) =>
          value != null &&
              value.toString().toLowerCase().contains(lowerQuery),
        );

        /// 🔹 Add computed verification text
        final verificationText =
        item['is_data_accuracy_checked'] == '0'
            ? 'to verify'
            : 'verified';

        final matchesVerification =
        verificationText.contains(lowerQuery);

        return matchesRawValues || matchesVerification;

      }).toList();
    });
  }

  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 Endorsement',
              style: GoogleFonts.poppins(fontSize: 15, fontWeight: FontWeight.w600),
            ),
          ],
        ),
        content: Text(
          'Are you sure you want to delete this endorsement?\nThis action cannot be undone.',
          style: GoogleFonts.poppins(fontSize: 13, color: Colors.grey.shade700),
        ),
        actions: [
          // CANCEL
          TextButton(
            onPressed: () => Navigator.pop(ctx),
            child: Text(
              'Cancel',
              style: GoogleFonts.poppins(fontSize: 13, color: Colors.grey.shade600),
            ),
          ),

          // CONFIRM DELETE
          ElevatedButton(
            style: ElevatedButton.styleFrom(
              backgroundColor: Colors.red.shade600,
              shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
            ),
            onPressed: () async {
              Navigator.pop(ctx);
              await _deleteEndorsement(id);
            },
            child: Text(
              'Delete',
              style: GoogleFonts.poppins(fontSize: 13, color: Colors.white),
            ),
          ),
        ],
      ),
    );
  }

  Future<void> _deleteEndorsement(String id) async {
    try {
      setState(() => isLoading = true);

      final response = await apiService.deleteEndorsement(id);

      if (response['status'] == 'success' || response['code'] == 200) {
        refresh();
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text(
              'Endorsement 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'] ?? 'Failed to delete endorsement.',
              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 {
      setState(() => isLoading = false);
    }
  }

  final TextEditingController rightSearchController = TextEditingController();
  final TextEditingController startController = TextEditingController();
  final TextEditingController endController = TextEditingController();

  dynamic selectedStatusVal;
  dynamic selectedVerificationVal;
  dynamic selectedInsurerVal;
  dynamic selectedInsurer;
  dynamic selectedEndorsementTypeVal;

  List<Map<String, dynamic>> getInsurerDetailsData = [];
  List<Map<String, dynamic>> filteredInsurerData = [];
  bool isLoadingA = false;

  String _formatDate(String rawDate) {
    try {
      final dateTime = DateTime.parse(rawDate);
      return DateFormat('dd-MM-yyyy  HH:mm').format(dateTime); // 24-hour format
    } catch (e) {
      return rawDate; // fallback if parsing fails
    }
  }

  String _truncateText(String? text, int maxLength) {
    if (text == null || text.length <= maxLength) {
      return text ?? '-';
    }
    return '${text.substring(0, maxLength)}...';
  }

  List<Widget> _buildPopupMenuActions(BuildContext context, Map<String, dynamic> item) {
    final String Id = item['id']?.toString() ?? '';
    final String? pdfPath = item["endorsement_completion_file"];
    final String? fileName = (pdfPath != null && pdfPath.isNotEmpty)
        ? pdfPath.split('/').last
        : null;

    return [
      // --- EDIT BUTTON ---
      InkWell(
        onTap: () {
          Navigator.pop(context); // Close the menu first
          showDialog(
            context: context,
            barrierDismissible: true,
            builder: (BuildContext dialogContext) {
              return UpdateEndorsementDialog(
                item: item,
                userId: userId, // Ensure these variables are accessible
                managerId: managerId,
                onSubmit: (val) => refresh(),
              );
            },
          );
        },
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0),
          child: Row(
            children: const [
              Icon(Icons.edit_sharp, color: Color(0xFF319718), size: 18),
              SizedBox(width: 12),
              Text('Edit', style: TextStyle(fontSize: 14)),
            ],
          ),
        ),
      ),

      const Divider(height: 1, thickness: 0.5), // Subtle separator

      // --- DOWNLOAD BUTTON ---
      InkWell(
        onTap: () {
          Navigator.pop(context); // Close the menu first
          apiService.downloadFile(
            apiUrl: 'endorsement/downloadEndorsementCompletionFile?id=$Id',
            apiId: Id,
            localFile: null,
            fileName: fileName,
          );
        },
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0),
          child: Row(
            children: const [
              Icon(Icons.download_rounded, color: Colors.blue, size: 18),
              SizedBox(width: 12),
              Text('Download', style: TextStyle(fontSize: 14)),
            ],
          ),
        ),
      ),

      // --- DELETE BUTTON ---
      if (roleId == 'Accounts') ...[
        const Divider(height: 1, thickness: 0.5),
        InkWell(
          onTap: () {
            Navigator.pop(context);
            _confirmDelete(context, Id);
          },
          child: Padding(
            padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0),
            child: Row(
              children: const [
                Icon(Icons.delete_outline, color: Colors.red, size: 18),
                SizedBox(width: 12),
                Text('Delete', style: TextStyle(fontSize: 14, color: Colors.red)),
              ],
            ),
          ),
        ),
      ],
    ];
  }

  Future<void> fetchEndorsementExcelReport() async {
    final String searchValue = rightSearchController.text;
    final response = await apiService.generateEndorsementExcel(managerId,searchValue);
    // Map your controllers and IDs to the API parameters
    // final String fromDate = controllers['startDate']!.text; // "11-01-2025"
    // final String toDate = controllers['endDate']!.text;     // "20-01-2025"
    // print("fetchPolicyExcelReport function called here.");
    //
    // try {
    //   // Assuming you have a generic _makeGetRequest method
    //   final response = await apiService.fetchPolicyExcel(managerId,fromDate,toDate);
    //
    //   if (response != null && response['status'] == 200) {
    //     setState(() {
    //       // Store the list of data in your variable
    //       excelResponseData = response['data'];
    //     });
    //     print("Data fetched. Ready to export.");
    //   }
    // } catch (e) {
    //   debugPrint("Export Error: $e");
    //   print("Failed to fetch report data.");
    // }
  }

  Future<void> getEnroementType() async {
    print('Insurers called');
    setState(() {
      isLoading = true;
    });

    try {
      final response = await apiService.fetchMasterDropDown('Endorsement');

      if (response['status'] == 200) {
        print('getEnroementType - ${response['data']}');
        setState(() {
          getEndrosmentType = List<Map<String, dynamic>>.from(response['data']);
          print('API Data - $getEndrosmentType');

          filteredEndrosmentData = List.from(getEndrosmentType);
          // print('originalData - $filteredEndrosmentData');
        });
      } else {
        getEndrosmentType = [];
        filteredEndrosmentData = [];
      }
    } catch (e) {
      print('Exception occurred: $e');
    } finally {
      setState(() {
        isLoading = false;
      });
    }
  }

  Future<void> getInsurerDetails() async {
    setState(() => isLoadingA = true);
    try {
      final response = await apiService.fetchMasterDropDown('Insurers');

      print("***999999999999999999*********** $response");

      if (response['status'] == 200) {
        print('getInsurerDetails - ${response['data']}');

        setState(() {
          getInsurerDetailsData =
          List<Map<String, dynamic>>.from(response['data']);

          filteredInsurerData =
          List<Map<String, dynamic>>.from(getInsurerDetailsData);

          print("Filtered Insurer Data: $filteredInsurerData");
        });
      } else {
        setState(() {
          getInsurerDetailsData = [];
          filteredInsurerData = [];
        });
      }
    } catch (e) {
      print('Error: $e');
    } finally {
      setState(() => isLoadingA = false);
    }
  }

  Future<void> loadEndorsementNumbers(String id) async {
    // final response = await apiService.fetchEndorsementNumbers(id);
    //
    // if (response['status'] == 'success') {
    //   setState(() {
    //     endorsementNumbers =
    //     List<Map<String, dynamic>>.from(response['data']);
    //   });
    // }
  }

  @override
  Widget build(BuildContext context) {
    return MainLayout(
      title: "Endorsement",
      body: SelectionArea(
        child: Container(
        // color: Colors.yellow.shade50,
        width: MediaQuery.of(context).size.width,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            // Container(
            //   height: 30,
            //   width: MediaQuery.of(context).size.width,
            //   child: GestureDetector(
            //     onTap: () {
            //       context.go(AppRoutes.dashboard);
            //     },
            //     child: Row(
            //       crossAxisAlignment: CrossAxisAlignment.center,
            //       mainAxisAlignment: MainAxisAlignment.start,
            //       children: [
            //         Tooltip(
            //           message: 'Back',
            //           child: IconButton(
            //             icon: const Icon(
            //               Icons.arrow_left_sharp,
            //               size: 25,
            //               color: Color(0xFF425B5B),
            //             ),
            //             onPressed: () {
            //               context.go(AppRoutes.dashboard);
            //             },
            //             splashRadius: 18,
            //             hoverColor: Colors.black12,
            //             padding: const EdgeInsets.all(4),
            //             constraints: const BoxConstraints(),
            //           ),
            //         ),
            //         const SizedBox(width: 5), // spacing between icon and text
            //         Text(
            //           "Endorsement",
            //           style: GoogleFonts.poppins(
            //             fontSize: 14,
            //             fontWeight: FontWeight.w400,
            //           ),
            //         ),
            //       ],
            //     ),
            //   ),
            // ),
            //
            // SizedBox(height: 5),
            Expanded(
              child: Container(
                // color: Colors.green,
                // color: Colors.green.shade50,
                width: MediaQuery.of(context).size.width,

                padding: EdgeInsets.all(8.0),
                child: Column(
                  children: [
                    Container(
                      // height: 40,
                      // color: Colors.pink,
                      child: Row(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        mainAxisAlignment: MainAxisAlignment.start,
                        children: [
                          Text(
                            "Endorsement",
                            style: GoogleFonts.poppins(
                              fontSize: 14,
                              fontWeight: FontWeight.w400,
                            ),
                          ),
                        ],
                      ),
                    ),
                    SizedBox(height: 10),
                    Container(
                      width: double.infinity,
                      child: Row(
                        children: [
                          Expanded(
                            child: buildFilterBar(context),
                          ),
                        ],
                      ),
                    ),
                    SizedBox(height: 10),
                    if (!ResponsiveLayout.isMobile(context))
                      Container(
                        decoration: BoxDecoration(
                          color: Color(0xFFF1F5F9),
                          // color: Color(0xFFEDF6F5),
                          borderRadius: BorderRadius.circular(6),
                        ),
                        padding: const EdgeInsets.symmetric(
                          vertical: 8,
                          horizontal: 16,
                        ),
                        child: Row(
                          children: [
                            Expanded(
                              flex: 1,
                              child: Text('ID ', style: _headerStyle),
                            ),
                            Expanded(
                              flex: 2,
                              child: Text('Vechile TYpe ', style: _headerStyle),
                            ),
                            Expanded(
                              flex: 3,
                              child: Text('Fuel ', style: _headerStyle),
                            ),
                            Expanded(
                              flex: 2,
                              child: Text('Insurer', style: _headerStyle),
                            ),
                            Expanded(
                              flex: 2,
                              child: Text('RTO', style: _headerStyle),
                            ),
                            Expanded(
                              flex: 3,
                              child: Text('Broker', style: _headerStyle),
                            ),
                            Expanded(
                              flex: 2,
                              child: Text('Segment', style: _headerStyle),
                            ),
                            Expanded(
                              flex: 2,
                              child: Text(
                                'Comp',
                                style: _headerStyle,
                              ),
                            ),
                            Expanded(
                              flex: 2,
                              child: Text(
                                'TP',
                                style: _headerStyle,
                              ),
                            ),
                            Expanded(
                              flex: 2,
                              child: Text(
                                'OD',
                                style: _headerStyle,
                              ),
                            ),
                            Expanded(
                              flex: 2,
                              child: Text(
                                'Remarks',
                                style: _headerStyle,
                              ),
                            ),
                            Expanded(
                              flex: 2,
                              child: Text(
                                'Partner Comp',
                                style: _headerStyle,
                              ),
                            ),
                            Expanded(
                              flex: 2,
                              child: Text(
                                'Partner TD',
                                style: _headerStyle,
                              ),
                            ),
                            // if(roleId == 'Accounts')
                            Expanded(
                              flex: 2,
                              child: Text(
                                'Partner OD',
                                style: _headerStyle,
                              ),
                            ),
                            Expanded(
                              flex: 2,
                              child: Text('Action', style: _headerStyle),
                            ),
                          ],
                        ),
                      ),
                    Expanded(
                      child: Row(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          // MAIN TABLE
                          Expanded(
                            flex: 3,
                            child: Container(
                              // color: Colors.white,
                              child: _buildDataTable(context),
                            ),
                          ),

                          // DRAWER (only if open)
                          // if (isDrawerOpen)
                          //   Expanded(
                          //     flex: 1,
                          //     child: _buildDrawer(),
                          //   ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),

            Container(
              // height: 20,
              width: MediaQuery.of(context).size.width,
              // color: Colors.green.shade50,
              child: PaginationControls(
                currentPage: currentPage,
                itemsPerPage: itemsPerPage,
                // totalItems: dataVal.length,
                totalItems: filteredData.length,
                // activeColor: layoutColor, // your theme color
                onPageChanged: (page) {
                  setState(() {
                    currentPage = page;
                  });
                },
                onItemsPerPageChanged: (items) {
                  setState(() {
                    itemsPerPage = items;
                    currentPage = 1;
                  });
                },
              ),
            ),
          ],
        ),
      ), ),
    );
  }

  Widget buildFilterBar(BuildContext context) {
    return SizedBox(
      width: double.infinity,
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(12),
          border: Border.all(color: const Color(0xFFE5E7EB)),
        ),
        child: Row(
          children: [

            /// 🔹 LEFT SIDE (SCROLLABLE FILTERS)
            Expanded(
              child: SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Row(
                  children: [
                    buildRTOSearch(context),
                    const SizedBox(width: 12),

                    buildVechileTypeSearch(context),
                    const SizedBox(width: 12),

                    buildInsurerSearch(context),
                    const SizedBox(width: 12),

                    buildPalntypeSearch(context),
                    const SizedBox(width: 12),

                    buildSegmentSearch(context),
                    const SizedBox(width: 12),

                    _iconButton(Icons.search, () {
                      refresh();
                    }),
                    const SizedBox(width: 8),

                    _iconButton(Icons.refresh, () {
                      selectedRTOVal = null;
                      selectedInsurerVal = null;
                      selectedVechileTypeVal = null;
                      selectedPlanTypeVal = null;
                      selectedSegmentVal = null;
                      rightSearchController.clear();
                      refresh();
                    }),
                  ],
                ),
              ),
            ),

            /// 🔹 RIGHT SIDE (FIXED)
            const SizedBox(width: 20),

            _rightSearchField(),
            const SizedBox(width: 12),
            _exportButton(),
          ],
        ),
      ),
    );
  }

  Widget _buildDataTable(BuildContext context) {
    if (filteredData.isEmpty) {
      return const SizedBox(
        height: 50,
        child: Center(child: Text('No available data')),
      );
    }

    final sortedData = [..._paginatedData];
    return ListView.builder(
      itemCount: ResponsiveLayout.isMobile(context)
          ? sortedData
                .length // only cards for mobile
          : sortedData.length + 1, // +1 for header in desktop
      itemBuilder: (context, index) {
        if (!ResponsiveLayout.isMobile(context) && index == 0) {
          return _buildHeader();
        }

        final startIndex = (currentPage - 1) * itemsPerPage;
        final item =
            sortedData[index - (ResponsiveLayout.isMobile(context) ? 0 : 1)];
        final sno = startIndex + index;

        return !ResponsiveLayout.isMobile(context)
            ? _buildDataRow(item, sno)
            : _buildDataCard(item, sno);
      },
    );
  }

  Widget _buildHeader() {
    return SizedBox.shrink();
  }

  Widget _buildDataRow(Map<String, dynamic> item, sno) {
    final String id = item['id']?.toString() ?? '';
    
    

    return MouseRegion(
      cursor: SystemMouseCursors.click,
      child: GestureDetector(
        onTap: () async {
          setState(() {
            selectedRow = item;
            // isDrawerOpen = true;
          });

          await loadEndorsementNumbers(item['id']);
        },
        child: AnimatedContainer(
          duration: const Duration(milliseconds: 150),
          padding: const EdgeInsets.symmetric(
              vertical: 10, horizontal: 16),
          decoration: BoxDecoration(
            // color: bgColor,
            border: const Border(
              bottom: BorderSide(
                color: Color(0xFFEAEAEA),
                width: 1,
              ),
            ),
          ),
          child: Row(
            children: [

              Expanded(flex: 1, child: Text('$sno', style: _dataBold)),

              Expanded(
                flex: 2,
                child: Text(
                  item['vehicle_type'] != null
                      ? item['vehicle_type'].toString()
                      : '-',
                  style: _dataBold,
                ),
              ),

              Expanded(
                flex: 3,
                child: Text(
                  item['fuel'] != null
                      ? item['feul'].toString()
                      : '-',
                  style: _dataBold,
                ),
              ),

              Expanded(
                  flex: 2,
                  child: Text(item['insurer'] ?? '-', style: _dataBold)),

              Expanded(
                  flex: 2,
                  child: Text(item['rto'] ?? '-', style: _dataBold)),

              Expanded(
                  flex: 3,
                  child:
                  Text(item['broker_name'] ?? '-', style: _dataBold)),
Expanded(
                  flex: 2,
                  child: Text(item['swgment'] ?? '-', style: _dataBold)),
              
              Expanded(
                  flex: 2,
                  child: Text(item['comp'] ?? '-', style: _dataBold)),
      Expanded(
                  flex: 2,
                  child: Text(item['tp'] ?? '-', style: _dataBold)),
      Expanded(
                  flex: 2,
                  child: Text(item['od'] ?? '-', style: _dataBold)),
      Expanded(
                  flex: 2,
                  child: Text(item['remarks'] ?? '-', style: _dataBold)),
      Expanded(
                  flex: 2,
                  child: Text(item['partner_comp'] ?? '-', style: _dataBold)),
      Expanded(
                  flex: 2,
                  child: Text(item['partner_tp'] ?? '-', style: _dataBold)),
      Expanded(
                  flex: 2,
                  child: Text(item['partner_od'] ?? '-', style: _dataBold)),
              Expanded(
                flex: 2,
                child: item['is_active'] == "1"
                    ? Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    // --- EDIT ---
                    _actionIconButton(
                      context: context,
                      tooltip: 'Edit',
                      iconColor: const Color(0xFF319718),
                      onTap: () async {
                        _openEditModal(item);
                        if (result == true) refresh();
                      },
                      customIcon: Image.asset(
                        "assets/miscellaneous/Edit.png",
                        height: 15,
                        width: 15,
                      ),
                    ),
                  ],
                )
                    : const Text('-'), _buildListWidget
              ),
            ],
          ),
        ),
      ),
    );
  }



  Widget _buildDataCard(Map<String, dynamic> item, int sno) {
    return Container(
      margin: const EdgeInsets.symmetric(vertical: 6, horizontal: 8),
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: const Color(0xFFF6FEFD),
        borderRadius: BorderRadius.circular(8.0),
        border: Border.all(color: const Color(0xffD9EBE8)),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              
              
      
      
      
      
      
      
      
              Text(item['vehicle_type'] ?? '-', style: _headerStyle),
              PopupMenuButton<int>(
                color: Colors.white,
                padding: EdgeInsets.zero,
                offset: Offset(0, 30),
                icon: Icon(Icons.more_vert, color: Color(0xFF475569), size: 14),
                itemBuilder: (context) => [
                  CustomPopupMenuEntry(
                    child: Container(
                      padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: _buildPopupMenuActions(context, item),
                      ),
                    ),
                  ),
                ],
              ),
            ],
          ),
          const Divider(color: Color(0xffD9EBE8), thickness: 0.8),

          // Policy From + Status
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    
                    Text("Fuel", style: _cardheaderStyle),
                    Text(
                      item['fuel'] ?? '-',
                      style: _cardBodyStyle,
                    ),
                  ],
                ),
              ),
              SizedBox(width: 5),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    //remarks
                    Text("remarks", style: _cardheaderStyle),
                    Text(
                      item['remarks'] ?? '-',
                      style: _cardBodyStyle,
                      maxLines: 3,
                      softWrap: true,
                    ),
                  ],
                ),
              ),
            ],
          ),
          const SizedBox(height: 15),

          
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,

                  mainAxisAlignment: MainAxisAlignment.start,
                  children: [
                    //company
                    Text("Insurer", style: _cardheaderStyle),
                    Text(
                      item['insurer'] ?? '-',
                      style: _cardBodyStyle,
                      maxLines: 3,
                      softWrap: true,
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 15),
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text("RTO", style: _cardheaderStyle),
                  Text(
                      item['rto'] ?? '-',
                      style: _cardBodyStyle,
                    ),
                ],
              ),
              const SizedBox(height: 15),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: [
                    
                    Text("broker", style: _cardheaderStyle),
                    Text(
                      item['broker_name'] ?? '-',
                      style: _cardBodyStyle,
                      maxLines: 2,
                      softWrap: true,
                    ),
                  ],
                ),
              ),
            ],
          ),
          const SizedBox(height: 15),

          // Created On + Remarks
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    
                    Text("comp", style: _cardheaderStyle),
                    Text(
                      item['partner_comp']  '&' item['comp'] ?? '-',
                      style: _cardBodyStyle,
                    ),
                  ],
                ),
              ),
              SizedBox(width: 5),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    
                    Text("TP", style: _cardheaderStyle),
                    Text(
                      item['partner_tp']  '&' item['tp'] ?? '-',
                      style: _cardBodyStyle,
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 15),
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text("OD", style: _cardheaderStyle),
                  Text(
                      item['partner_od']  '&' item['OD'] ?? '-',
                      style: _cardBodyStyle,
                    ),
                ],
              ),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildDrawer() {
    return Container(
      margin: const EdgeInsets.only(left: 12),
      decoration: BoxDecoration(
        color: Colors.white,
        border: Border.all(color: const Color(0xFFEAEAEA)),
        borderRadius: BorderRadius.circular(8),
      ),
      child: Column(
        children: [

          // HEADER
          Container(
            padding: const EdgeInsets.all(12),
            decoration: const BoxDecoration(
              border: Border(
                bottom: BorderSide(color: Color(0xFFEAEAEA)),
              ),
            ),
            child: Row(
              children: [
                Expanded(
                  child: Text(
                    "${selectedRow?['']} - Grid",
                    style: _headerStyle,
                  ),
                ),
                IconButton(
                  icon: const Icon(Icons.close),
                  onPressed: () {
                    setState(() {
                      // isDrawerOpen = false;
                      selectedRow = null;
                    });
                  },
                ),
              ],
            ),
          ),

          // TABLE
          Expanded(
            child: endorsementNumbers.isEmpty
                ? const Center(child: Text("No "))
                : ListView.builder(
              itemCount: endorsementNumbers.length,
              itemBuilder: (context, index) {
                final item = endorsementNumbers[index];
                return Container(
                  padding: const EdgeInsets.all(12),
                  decoration: const BoxDecoration(
                    border: Border(
                      bottom: BorderSide(
                        color: Color(0xFFEAEAEA),
                      ),
                    ),
                  ),
                  child: Row(
                    children: [
                      Expanded(
                        child: Text(
                          item['vechile_type'] ?? '-',
                          style: _dataBold,
                        ),
                      ),
                      IconButton(
                        icon: const Icon(Icons.edit, size: 16),
                        onPressed: () {},
                      ),
                      IconButton(
                        icon: const Icon(Icons.download, size: 16),
                        onPressed: () {},
                      ),
                    ],
                  ),
                );
              },
            ),
          ),

          // PAGINATION
          PaginationControls(
            currentPage: 1,
            itemsPerPage: 10,
            totalItems: endorsementNumbers.length,
            onPageChanged: (page) {},
            onItemsPerPageChanged: (items) {},
          ),
        ],
      ),
    );
  }

  Widget buildRTOSearch(BuildContext context) {
    final List<Map<String, dynamic>> endorsementOptions =
    List<Map<String, dynamic>>.from(filteredEndrosmentData);

    Map<String, dynamic>? selectedItem;

    if (selectedEndorsementTypeVal != null &&
        selectedEndorsementTypeVal.toString().isNotEmpty &&
        endorsementOptions.isNotEmpty) {
      try {
        selectedItem = endorsementOptions.firstWhere(
              (e) =>
          e['id'].toString() ==
              selectedEndorsementTypeVal.toString(),
        );
      } catch (_) {
        selectedItem = null;
      }
    }

    return SizedBox(
      height: 33,
      child: Container(
        width: ResponsiveLayout.isMobile(context)
            ? null
            : MediaQuery.of(context).size.width * 0.10,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(10),
          border: Border.all(color: const Color(0xFFE2E8F0)),
        ),
        child: DropdownSearch<Map<String, dynamic>>(
          selectedItem: selectedItem,

          items: (filter, infiniteScrollProps) {
            if (filter.isEmpty) return endorsementOptions;

            return endorsementOptions
                .where((item) => item['endorsement_type']
                .toString()
                .toLowerCase()
                .contains(filter.toLowerCase()))
                .toList();
          },

          itemAsString: (item) =>
          item['endorsement_type']?.toString() ?? '',

          compareFn: (item, selected) {
            if (selected == null) return false;
            return item['id'].toString() ==
                selected['id'].toString();
          },

          dropdownBuilder: (context, selectedItem) {
            return Align(
              alignment: Alignment.centerLeft,
              child: Text(
                selectedItem != null
                    ? selectedItem['endorsement_type']
                    .toString()
                    : '',
                style: GoogleFonts.poppins(
                  fontSize: 11,
                  color: Colors.black,
                ),
                maxLines: 1,
                overflow: TextOverflow.ellipsis,
              ),
            );
          },

          decoratorProps: DropDownDecoratorProps(
            decoration:
            AppInputDecorations.dropdownDecoration(
              label: "Insurer",
            ).copyWith(
              filled: true,
              fillColor: Colors.white,
              isDense: true,
              contentPadding:
              const EdgeInsets.symmetric(
                horizontal: 5,
                vertical: 1,
              ),
            ),
          ),

          popupProps: PopupProps.menu(
            showSearchBox: true,
            fit: FlexFit.loose,
            constraints: BoxConstraints(
              maxHeight: 300,
              minWidth: ResponsiveLayout.isMobile(context)
                  ? 200
                  : MediaQuery.of(context).size.width * 0.15,
            ),
            menuProps:
            const MenuProps(backgroundColor: Colors.white),
          ),

          onChanged: (val) {
            if (val == null) return;

            selectedEndorsementTypeVal = val['id'];
            // refresh();
          },
        ),
      ),
    );
  }

  Widget buildSelectInsurer(BuildContext context) {
    // Ensure this list has data BEFORE building dropdown
    final List<Map<String, dynamic>> insurerOptions =
    List<Map<String, dynamic>>.from(filteredInsurerData);

    // Selected item logic
    Map<String, dynamic>? selectedItem;

    if (selectedInsurerVal != null &&
        selectedInsurerVal.toString().isNotEmpty &&
        insurerOptions.isNotEmpty) {
      try {
        selectedItem = insurerOptions.firstWhere(
              (e) => e['id'].toString() == selectedInsurerVal.toString(),
        );
      } catch (e) {
        selectedItem = null;
      }
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        SizedBox(
          height: 33,
          child: Container(
            width: ResponsiveLayout.isMobile(context)
                ? null
                : MediaQuery.of(context).size.width * 0.10,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(10 ),
              border: Border.all(color: const Color(0xFFE2E8F0)),
            ),
            child: DropdownSearch<Map<String, dynamic>>(
              selectedItem: selectedItem,

              // FILTER LOGIC: This filters the list as the user types
              items: (filter, infiniteScrollProps) {
                if (filter.isEmpty) {
                  return insurerOptions;
                }
                return insurerOptions
                    .where((item) => item['short_name']
                    .toString()
                    .toLowerCase()
                    .contains(filter.toLowerCase()))
                    .toList();
              },

              itemAsString: (item) => item['short_name']?.toString() ?? '',

              compareFn: (item, selected) {
                if (selected == null) return false;
                return item['id'].toString() == selected['id'].toString();
              },

              // FIELD UI (The collapsed state)
              dropdownBuilder: (context, selectedItem) {
                return Align(
                  alignment: Alignment.centerLeft,
                  child: Text(
                    selectedItem != null
                        ? selectedItem['short_name'].toString()
                        : '',
                    style: GoogleFonts.poppins(
                      fontSize: 11,
                      color: Colors.black,
                    ),
                    maxLines: 1,
                    overflow: TextOverflow.ellipsis,
                  ),
                );
              },

              decoratorProps: DropDownDecoratorProps(
                decoration: AppInputDecorations.dropdownDecoration(
                  label: "Select Insurer",
                ).copyWith(
                  filled: true,
                  fillColor: Colors.white,
                  isDense: true,
                  contentPadding: const EdgeInsets.symmetric(
                    horizontal: 5,
                    vertical: 1,
                  ),
                ),
              ),

              // POPUP UI (The expanded state with search)
              popupProps: PopupProps.menu(
                showSearchBox: true, // Enabled searching
                fit: FlexFit.loose,
                constraints: BoxConstraints(
                  maxHeight: 300,
                  minWidth: ResponsiveLayout.isMobile(context)
                      ? 200
                      : MediaQuery.of(context).size.width * 0.10,
                ),
                menuProps: const MenuProps(backgroundColor: Colors.white),

                // Customizing the search field appearance
                searchFieldProps: TextFieldProps(
                  style: GoogleFonts.poppins(fontSize: 13),
                  decoration: InputDecoration(
                    hintText: "Search insurer...",
                    hintStyle: GoogleFonts.poppins(fontSize: 12),
                    contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
                  ),
                ),

                itemBuilder: (context, item, isDisabled, isSelected) {
                  return Container(
                    padding: const EdgeInsets.symmetric(
                      horizontal: 12,
                      vertical: 10,
                    ),
                    decoration: BoxDecoration(
                      color: isSelected ? Colors.blue.withOpacity(0.1) : Colors.transparent,
                    ),
                    child: Text(
                      item['short_name'].toString(),
                      style: GoogleFonts.inter(
                        fontSize: 13,
                        color: Colors.black,
                      ),
                    ),
                  );
                },
              ),

              // ON CHANGE
              onChanged: (val) {
                if (val == null) return;

                selectedInsurerVal = val['id'];
                // refresh();
              },
            ),
          ),
        ),
      ],
    );
  }

  

  Widget buildplan(BuildContext context) {
    final List<Map<String, dynamic>> verificationOptions = [
      {'id': 2, 'status': 'All'},
      {'id': 0, 'status': 'To Verify'},
      {'id': 1, 'status': 'Verified'},
    ];

    Map<String, dynamic>? selectedItem;

    if (selectedVerificationVal != null) {
      try {
        selectedItem = verificationOptions.firstWhere(
              (e) => e['id'] == selectedVerificationVal,
        );
      } catch (_) {
        selectedItem = null;
      }
    }

    return SizedBox(
      height: 33,
      child: Container(
        width: ResponsiveLayout.isMobile(context)
            ? null
            : MediaQuery.of(context).size.width * 0.10,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(10),
          border: Border.all(color: const Color(0xFFE2E8F0)),
        ),
        child: DropdownSearch<Map<String, dynamic>>(
          selectedItem: selectedItem,
          items: (filter, infiniteScrollProps) => verificationOptions,

          itemAsString: (val) => val['status'].toString(),

          compareFn: (item, selected) {
            if (selected == null) return false;
            return item['id'] == selected['id'];
          },

          dropdownBuilder: (context, selectedItem) {
            return Align(
              alignment: Alignment.centerLeft,
              child: Text(
                selectedItem != null
                    ? selectedItem['status'].toString()
                    : '',
                style: GoogleFonts.poppins(
                  fontSize: 11,
                  color: Colors.black,
                ),
                maxLines: 1,
                overflow: TextOverflow.ellipsis,
              ),
            );
          },

          decoratorProps: DropDownDecoratorProps(
            decoration: AppInputDecorations.dropdownDecoration(
              label: "Select Verification",
            ).copyWith(
              filled: true,
              fillColor: Colors.white,
              isDense: true,
              contentPadding: const EdgeInsets.symmetric(
                horizontal: 5,
                vertical: 1,
              ),
            ),
          ),

          popupProps: PopupProps.menu(
            showSearchBox: false,
            fit: FlexFit.loose,
            constraints: BoxConstraints(
              maxHeight: 300,
              minWidth: ResponsiveLayout.isMobile(context)
                  ? 200
                  : MediaQuery.of(context).size.width * 0.10,
            ),
            menuProps: const MenuProps(backgroundColor: Colors.white),
          ),

          onChanged: (val) {
            if (val == null) return;

            selectedVerificationVal = val['id'];
            // refresh();
          },
        ),
      ),
    );
  }

  Widget _iconButton(
      IconData icon, VoidCallback? onTap) {
    return InkWell(
      onTap: onTap,
      child: Container(
        width: 36,
        height: 36,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(8),
          border: Border.all(
              color: const Color(0xFFE5E7EB)),
          color: Colors.white,
        ),
        child: Icon(icon,
            size: 18, color: Colors.grey[700]),
      ),
    );
  }

  Widget _rightSearchField() {
    return Container(
      width: 220,
      height: 36,
      padding: const EdgeInsets.symmetric(horizontal: 12),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(8),
        border: Border.all(color: const Color(0xFFE5E7EB)),
        color: Colors.white,
      ),
      child: Row(
        children: [
          const Icon(Icons.search, size: 18, color: Colors.grey),
          const SizedBox(width: 8),
          Expanded(
            child: TextField(
              controller: rightSearchController,
              decoration: InputDecoration(
                hintText: "Search...",
                border: InputBorder.none,
                isDense: true,
                hintStyle: GoogleFonts.poppins(fontSize: 11),
              ),
              style: GoogleFonts.poppins(fontSize: 11),
              onChanged: (val) {
                filterData(val);
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _exportButton() {
    return InkWell(
      onTap: () async {
        await fetchGRidExcelReport();
      },
      child: Container(
        width: 40,
        height: 36,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(8),
          color: const Color(0xFF2E7D6E),
        ),
        child:Tooltip(
          message: 'Export',
          child: Image.asset(
            "assets/miscellaneous/export.png",
            height: 13,
            width: 13,
          ),
        ),
      ),
    );
  }

  Widget _actionIconButton({
    required BuildContext context,
    IconData? icon,
    Widget? customIcon,
    Widget Function(BuildContext buttonContext)? builderIcon,
    required String tooltip,
    required Color iconColor,
    required VoidCallback? onTap,
    Color? hoverColor,                        // ✅ Add this parameter
  }) {
    if (builderIcon != null) {
      return Builder(builder: (buttonContext) => builderIcon(buttonContext));
    }

    return Material(
      color: Colors.transparent,
      child: Tooltip(
        message: tooltip,
        waitDuration: const Duration(milliseconds: 300),
        showDuration: const Duration(seconds: 2),
        child: InkWell(
          onTap: onTap,
          borderRadius: BorderRadius.circular(20),
          hoverColor: hoverColor ?? Colors.grey.shade200,  // ✅ default grey
          child: Padding(
            padding: const EdgeInsets.all(5),
            child: customIcon ?? Icon(icon, size: 15, color: iconColor),
          ),
        ),
      ),
    );
  }

void _openViewModal(Map<String, dynamic> row) {
    showDialog(
      context: context,
      builder: (context) => _PayoutRowViewDialog(row: row),
    );
  }

  void _openEditModal(Map<String, dynamic> row) {
    showDialog(
      context: context,
      builder: (context) => _PayoutRowEditDialog(
        initialRow: row,
        canEdit: true,
        onSave: (updated) {
          setState(() {
            final id = updated['id'];
            final idx = _rows.indexWhere(
                (e) => e['id']?.toString() == id?.toString());
            if (idx >= 0) {
              _rows[idx] = updated;
            } else {
              _rows.insert(0, updated);
            }
          });
          ToastHelper.showSuccessToast(context, 'Updated successfully');
        },
      ),
    );
  }

  void _openAddModal() {
    showDialog(
      context: context,
      builder: (context) => const UploadGridModal(),
    ).then((result) async {
      // `UploadGridModal` will pop with `true` after successful upload.
      if (result == true && mounted) {
        await _fetchGrid();
      }
    });
  }

  Future<void> _exportExcel() async {
    setState(() => _loading = true);
    try {
      await _apiService.downloadgridViewInExcel(
        startDate: null,
        endDate: null,
        endorsementType: _selectedEndorsementType,
        insurer: _selectedInsurer,
        vehicleNo: _selectedVehicle,
        search: _searchValue.trim().isEmpty ? null : _searchValue.trim(),
      );
    } catch (e) {
      ToastHelper.showErrorToast(context, e.toString());
    } finally {
      if (mounted) setState(() => _loading = false);
    }
  }

  final queryRole = Uri.base.queryParameters['role'];
    final canEdit =
        (queryRole?.toLowerCase() == 'manager') || _isManagerOrAccount;


  
  

  String formatDateForList(String? dateStr) {
    if (dateStr == null || dateStr.isEmpty || dateStr == '-') return '-';

    try {
      // Catch invalid dates like "0000-00-00" or "30-11--0001"
      if (dateStr.contains('0000') || dateStr.startsWith('30-11--')) return '-';

      DateTime parsed = DateTime.parse(dateStr);

      // Validate year is reasonable
      if (parsed.year < 2000 || parsed.year > 2100) return '-';

      return DateFormat('dd-MM-yyyy').format(parsed);
    } catch (e) {
      return '-';
    }
  }

  
  static final _dataBold = GoogleFonts.inter(
    fontSize: 11,

    fontWeight: FontWeight.w400,
    color: Color(0xFF000000),
  );

  static final _dataSub = GoogleFonts.inter(
    fontSize: 10,
    fontWeight: FontWeight.w300,
    color: Color(0xFF585757),
  );

  static final _headerStyle = GoogleFonts.poppins(
    fontSize: 11.2,
    fontWeight: FontWeight.w500,
    color: Color(0xFF1E293B),
  );
  static final _cardheaderStyle = GoogleFonts.inter(
    color: Colors.black,
    fontWeight: FontWeight.w600,
    fontSize: 12,
  );

  static final _cardBodyStyle = GoogleFonts.inter(
    color: const Color(0xFF545454),
    fontWeight: FontWeight.w400,
    fontSize: 12,
  );
}



// ══════════════════════════════════════════════════════════════════════════════
// ADD PAYOUT GRID DIALOG  –  matches Image 1 (Incentive Files modal style)
// ══════════════════════════════════════════════════════════════════════════════
class _gridViewAddDialog extends ConsumerStatefulWidget {
  final Future<void> Function() onAdded;

  const _gridViewAddDialog({required this.onAdded});

  @override
  ConsumerState<_gridViewAddDialog> createState() =>
      _gridViewAddDialogState();
}

class _gridViewAddDialogState
    extends ConsumerState<_gridViewAddDialog> {
  final ApiService _apiService = ApiService();

  bool _submitting = false;
  DateTime? _validFrom;
  PlatformFile? _selectedFile;

  final TextEditingController _filesSearchController =
      TextEditingController();
  String _filesSearchValue = '';

  void _refresh() {
    if (_submitting) return;
    setState(() {
      _validFrom = null;
      _selectedFile = null;
      _filesSearchValue = '';
      _filesSearchController.clear();
    });
  }

  String _formatDateForApi(DateTime date) =>
      date.toIso8601String().split('T').first;

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

  Future<void> _pickDate() async {
    final picked = await showDatePicker(
      context: context,
      firstDate: DateTime(2000),
      lastDate: DateTime(2100),
      initialDate: _validFrom ?? DateTime.now(),
    );
    if (picked == null) return;
    setState(() => _validFrom = picked);
  }

  Future<void> _pickXLFile() async {
    final picked = await FilePicker.platform.pickFiles(
      allowMultiple: false,
      type: FileType.custom,
      allowedExtensions: const ['xls', 'xlsx', 'csv'],
      withData: true,
    );
    if (picked == null || picked.files.isEmpty) return;
    setState(() => _selectedFile = picked.files.first);
  }

  Future<void> _submit() async {
    if (_validFrom == null) {
      ToastHelper.showErrorToast(context, 'Select valid from date');
      return;
    }
    if (_selectedFile == null) {
      ToastHelper.showErrorToast(context, 'Upload an XL file');
      return;
    }

    setState(() => _submitting = true);
    try {
      // Requirement: hardcode agent_id to 1 for payout grid upload.
      final agentId = 1;
      final currentUserId = ref.read(userIdProvider);

      final payload = <String, dynamic>{
        'agent_id': agentId,
          // Backend expects the uploader/creator user id.
          // (Other uploads like incentive use the logged-in user id.)
          'created_by': currentUserId ?? agentId,
        // Backend expects file_type as "grid" only.
        'file_type': 'grid',
        // Backend expects date under `incentive_month`.
        'incentive_month': _formatDateForApi(_validFrom!),
      };

      final res = await _apiService.uploadgridViewFile(
        file: _selectedFile!,
        data: payload,
      );

      if ((res['status'] ?? '').toString().toLowerCase() == 'success') {
        Navigator.pop(context);
        await widget.onAdded();
      } else {
        ToastHelper.showErrorToast(
            context, res['data']?.toString() ?? 'Upload failed');
      }
    } catch (e) {
      ToastHelper.showErrorToast(context, e.toString());
    } finally {
      if (mounted) setState(() => _submitting = false);
    }
  }

  
  
  

  Widget _buildSelectedFilesGrid() {
    final files = _getSelectedFiles();
    final q = _filesSearchValue.trim().toLowerCase();

    final filtered = q.isEmpty
        ? files
        : files.where((f) {
            final name = (f['file_name'] ?? '').toString().toLowerCase();
            final month = (f['month'] ?? '').toString().toLowerCase();
            return name.contains(q) || month.contains(q);
          }).toList();

    if (filtered.isEmpty) {
      return const Center(child: Text('No files found'));
    }

    return LayoutBuilder(
      builder: (context, constraints) {
        final fileAreaWidth = constraints.maxWidth;
        final crossAxisCount = fileAreaWidth < 520 ? 1 : 2;
        const spacing = 10.0;
        const targetTileHeight = 70.0;

        final tileWidth = (fileAreaWidth -
                spacing * (crossAxisCount - 1) -
                16) /
            crossAxisCount;
        final aspectRatio = (tileWidth / targetTileHeight).clamp(3.2, 12.0);

        return GridView.builder(
          padding: const EdgeInsets.all(8),
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: crossAxisCount,
            crossAxisSpacing: spacing,
            mainAxisSpacing: spacing,
            childAspectRatio: aspectRatio,
          ),
          itemCount: filtered.length,
          itemBuilder: (context, index) {
            final f = filtered[index];
            return gridViewFileRow(
              fileName: f['file_name']?.toString() ?? 'Unknown',
              date: f['month']?.toString() ?? '-',
              onUpload: () async {
                try {
                  await _apiService.downloadLatestgridView();
                } catch (_) {}
              },
              onDelete: _refresh,
            );
          },
        );
      },
    );
  }

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

final _labelStyle = GoogleFonts.poppins(
  color: Colors.black,
  fontWeight: FontWeight.w400,
  fontSize: 12,
);

class gridViewFileRow extends StatelessWidget {
  final String fileName;
  final String date;
  final VoidCallback? onUpload;
  final VoidCallback? onDelete;

  const gridViewFileRow({
    super.key,
    required this.fileName,
    required this.date,
    this.onUpload,
    this.onDelete,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
      decoration: BoxDecoration(
        border: Border.all(color: const Color(0xFFE3E3E3)),
        borderRadius: BorderRadius.circular(6),
      ),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Container(
            padding: const EdgeInsets.all(6.0),
            decoration: BoxDecoration(
              color: const Color(0xFFF4F6F8),
              borderRadius: BorderRadius.circular(6.0),
              border: Border.all(color: const Color(0xFFE3E3E3)),
            ),
            child: const Icon(
              Icons.file_present,
              color: Color(0xFF838587),
              size: 18,
            ),
          ),
          const SizedBox(width: 10),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: [
                Text(
                  fileName,
                  style: GoogleFonts.poppins(
                    fontWeight: FontWeight.w400,
                    fontSize: 12,
                  ),
                  overflow: TextOverflow.ellipsis,
                  maxLines: 1,
                ),
                const SizedBox(height: 2),
                Text(
                  date,
                  style: GoogleFonts.poppins(
                    color: const Color(0xFF6E6E6E),
                    fontSize: 10,
                  ),
                ),
              ],
            ),
          ),
          const SizedBox(width: 8),
          Material(
            color: Colors.transparent,
            child: InkWell(
              onTap: onUpload,
              borderRadius: BorderRadius.circular(20),
              child: const Padding(
                padding: EdgeInsets.all(6),
                child: Icon(
                  Icons.file_download_outlined,
                  color: Color(0xFF6E6E6E),
                  size: 20,
                ),
              ),
            ),
          ),
          Material(
            color: Colors.transparent,
            child: InkWell(
              onTap: onDelete,
              borderRadius: BorderRadius.circular(20),
              child: const Padding(
                padding: EdgeInsets.all(6),
                child: Icon(
                  Icons.delete_outlined,
                  color: Color(0xFF6E6E6E),
                  size: 20,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

// ══════════════════════════════════════════════════════════════════════════════
// VIEW DIALOG  
// ══════════════════════════════════════════════════════════════════════════════
class _PayoutRowViewDialog extends StatelessWidget {
  final Map<String, dynamic> row;

  const _PayoutRowViewDialog({required this.row});

  String _val(dynamic v) {
    final s = v?.toString().trim() ?? '';
    return s.isEmpty ? '-' : s;
  }

  @override
  Widget build(BuildContext context) {
    const fields = [
      'id', 'vehicle_type', 'fuel', 'insurer', 'rto', 'broker_name',
      'segment', 'comp', 'tp', 'od', 'remarks',
      'partner_comp', 'partner_tp', 'partner_od',
    ];

    final labels = {
      'id': 'ID', 'vehicle_type': 'Vehicle Type', 'fuel': 'Fuel',
      'insurer': 'Insurer', 'rto': 'RTO', 'broker_name': 'Broker',
      'segment': 'Segment', 'comp': 'Comp', 'tp': 'TP', 'od': 'OD',
      'remarks': 'Remarks', 'partner_comp': 'Partner Comp',
      'partner_tp': 'Partner TP', 'partner_od': 'Partner OD',
    };

    return AlertDialog(
      backgroundColor: Colors.white,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
      title: Text('Payout Grid Details',
          style: GoogleFonts.poppins(
              fontSize: 14,
              fontWeight: FontWeight.w500,
              color: const Color(0xFF50A398))),
      content: ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: 500),
        child: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: fields.map((k) {
              return Padding(
                padding: const EdgeInsets.symmetric(vertical: 5),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    SizedBox(
                      width: 110,
                      child: Text('${labels[k] ?? k}:',
                          style: GoogleFonts.inter(
                              fontSize: 12,
                              fontWeight: FontWeight.w500,
                              color: const Color(0xFF475569))),
                    ),
                    Expanded(
                      child: Text(_val(row[k]),
                          style: GoogleFonts.inter(
                              fontSize: 12, color: Colors.black87)),
                    ),
                  ],
                ),
              );
            }).toList(),
          ),
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: Text('Close',
              style: GoogleFonts.inter(
                  fontSize: 12, color: const Color(0xFF2E7D6E))),
        ),
      ],
    );
  }
}

// ══════════════════════════════════════════════════════════════════════════════
// EDIT DIALOG  
// ══════════════════════════════════════════════════════════════════════════════
class _PayoutRowEditDialog extends StatefulWidget {
  final Map<String, dynamic> initialRow;
  final bool isNew;
  final bool canEdit;
  final ValueChanged<Map<String, dynamic>> onSave;

  const _PayoutRowEditDialog({
    super.key,
    required this.initialRow,
    this.isNew = false,
    required this.canEdit,
    required this.onSave,
  });

  @override
  State<_PayoutRowEditDialog> createState() => _PayoutRowEditDialogState();
}

class _PayoutRowEditDialogState extends State<_PayoutRowEditDialog> {
  late final Map<String, TextEditingController> _ctrls;

  @override
  void initState() {
    super.initState();
    final r = widget.initialRow;
    _ctrls = {
      'id': TextEditingController(
          text: r['id']?.toString().trim().isNotEmpty == true
              ? r['id'].toString()
              : DateTime.now().millisecondsSinceEpoch.toString()),
      'vehicle_type': TextEditingController(
          text: r['vehicle_type']?.toString() ?? ''),
      'fuel': TextEditingController(text: r['fuel']?.toString() ?? ''),
      'insurer': TextEditingController(
          text: r['insurer']?.toString() ?? ''),
      'rto': TextEditingController(text: r['rto']?.toString() ?? ''),
      'broker_name': TextEditingController(
          text: r['broker_name']?.toString() ?? ''),
      'segment': TextEditingController(
          text: r['segment']?.toString() ?? ''),
      'comp': TextEditingController(text: r['comp']?.toString() ?? ''),
      'tp': TextEditingController(text: r['tp']?.toString() ?? ''),
      'od': TextEditingController(text: r['od']?.toString() ?? ''),
      'remarks': TextEditingController(
          text: r['remarks']?.toString() ?? ''),
      'partner_comp': TextEditingController(
          text: r['partner_comp']?.toString() ?? ''),
      'partner_tp': TextEditingController(
          text: r['partner_tp']?.toString() ?? ''),
      'partner_od': TextEditingController(
          text: r['partner_od']?.toString() ?? ''),
    };
  }

  @override
  void dispose() {
    for (final c in _ctrls.values) {
      c.dispose();
    }
    super.dispose();
  }

  dynamic _val(String key) {
    final t = _ctrls[key]!.text.trim();
    return t.isEmpty ? null : t;
  }

  @override
  Widget build(BuildContext context) {
    final title =
        widget.isNew ? 'Add Payout Grid' : 'Edit Payout Grid';

    final fieldDefs = [
      ('ID', 'id', false, 1),
      ('Vehicle Type', 'vehicle_type', true, 1),
      ('Fuel', 'fuel', true, 1),
      ('Insurer', 'insurer', true, 1),
      ('RTO', 'rto', true, 1),
      ('Broker', 'broker_name', true, 1),
      ('Segment', 'segment', true, 1),
      ('Comp', 'comp', true, 1),
      ('TP', 'tp', true, 1),
      ('OD', 'od', true, 1),
      ('Remarks', 'remarks', true, 3),
      ('Partner Comp', 'partner_comp', true, 1),
      ('Partner TP', 'partner_tp', true, 1),
      ('Partner OD', 'partner_od', true, 1),
    ];

    return AlertDialog(
      backgroundColor: Colors.white,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
      title: Text(title,
          style: GoogleFonts.poppins(
              fontSize: 14,
              fontWeight: FontWeight.w500,
              color: const Color(0xFF50A398))),
      content: ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: 500, maxHeight: 500),
        child: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: fieldDefs.map((def) {
              final (label, key, enabled, maxLines) = def;
              return Padding(
                padding: const EdgeInsets.only(bottom: 10),
                child: TextField(
                  controller: _ctrls[key],
                  enabled: enabled,
                  maxLines: maxLines,
                  style: GoogleFonts.inter(fontSize: 12),
                  decoration: InputDecoration(
                    labelText: label,
                    labelStyle: GoogleFonts.inter(fontSize: 12),
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(6)),
                    isDense: true,
                  ),
                ),
              );
            }).toList(),
          ),
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: Text('Cancel',
              style: GoogleFonts.inter(
                  fontSize: 12, color: const Color(0xFF64748B))),
        ),
        ElevatedButton(
          style: ElevatedButton.styleFrom(
            backgroundColor: const Color(0xFF2E7D6E),
            foregroundColor: Colors.white,
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(6)),
          ),
          onPressed: widget.canEdit
              ? () {
                  final updated = {
                    for (final k in _ctrls.keys) k: _val(k),
                  };
                  widget.onSave(updated);
                  Navigator.pop(context);
                }
              : null,
          child:
              Text('Save', style: GoogleFonts.inter(fontSize: 12)),
        ),
      ],
    );
  }
}
*/