// lib/screens/marine/manual/widgets/in_situ_step_3_data_capture.dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
import 'package:usb_serial/usb_serial.dart';

import '../../../../auth_provider.dart';
import '../../../../models/in_situ_sampling_data.dart';
import '../../../../services/marine_in_situ_sampling_service.dart';
import '../../../../bluetooth/bluetooth_manager.dart'; // For connection state enum
import '../../../../serial/serial_manager.dart';     // For connection state enum
import '../../../../bluetooth/widgets/bluetooth_device_list_dialog.dart';
import '../../../../serial/widget/serial_port_list_dialog.dart';

class InSituStep3DataCapture extends StatefulWidget {
  final InSituSamplingData data;
  final VoidCallback onNext;

  const InSituStep3DataCapture({
    super.key,
    required this.data,
    required this.onNext,
  });

  @override
  State<InSituStep3DataCapture> createState() => _InSituStep3DataCaptureState();
}

class _InSituStep3DataCaptureState extends State<InSituStep3DataCapture> with WidgetsBindingObserver {
  final _formKey = GlobalKey<FormState>();
  bool _isLoading = false;
  bool _isAutoReading = false;
  StreamSubscription? _dataSubscription;

  // --- START MODIFICATION: Countdown Timer State ---
  Timer? _lockoutTimer;
  int _lockoutSecondsRemaining = 30;
  bool _isLockedOut = false;
  // --- END MODIFICATION ---

  // --- START FIX: Declare service variable ---
  late final MarineInSituSamplingService _samplingService;
  // --- END FIX ---

  Map<String, double>? _previousReadingsForComparison;
  Set<String> _outOfBoundsKeys = {};

  /// Maps the app's internal parameter keys to the names used in the
  /// 'param_parameter_list' column from the server.
  final Map<String, String> _parameterKeyToLimitName = const {
    'oxygenConcentration': 'Oxygen Conc',
    'oxygenSaturation': 'Oxygen Sat',
    'ph': 'pH',
    'salinity': 'Salinity',
    'electricalConductivity': 'Conductivity',
    'temperature': 'Temperature',
    'tds': 'TDS',
    'turbidity': 'Turbidity',
    'tss': 'TSS',
    'batteryVoltage': 'Battery',
  };

  final List<Map<String, dynamic>> _parameters = [];

  final _sondeIdController = TextEditingController();
  final _dateController = TextEditingController();
  final _timeController = TextEditingController();
  final _oxyConcController = TextEditingController();
  final _oxySatController = TextEditingController();
  final _phController = TextEditingController();
  final _salinityController = TextEditingController();
  final _ecController = TextEditingController();
  final _tempController = TextEditingController();
  final _tdsController = TextEditingController();
  final _turbidityController = TextEditingController();
  final _tssController = TextEditingController();
  final _batteryController = TextEditingController();

  @override
  void initState() {
    super.initState();
    // --- START FIX: Initialize service variable safely ---
    _samplingService = Provider.of<MarineInSituSamplingService>(context, listen: false);
    // --- END FIX ---
    _initializeControllers();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    _dataSubscription?.cancel();
    _lockoutTimer?.cancel(); // --- MODIFICATION: Cancel timer on dispose ---

    // --- START FIX: Use the pre-fetched service instance ---
    if (_samplingService.bluetoothConnectionState.value != BluetoothConnectionState.disconnected) {
      _samplingService.disconnectFromBluetooth();
    }
    if (_samplingService.serialConnectionState.value != SerialConnectionState.disconnected) {
      _samplingService.disconnectFromSerial();
    }
    // --- END FIX ---

    _disposeControllers();
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  // --- START: MODIFIED LIFECYCLE METHOD ---
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      // --- FIX: Check if mounted before performing logic or calling setState ---
      if (mounted) {
        // Use the member variable, not context
        final service = _samplingService;
        final btConnecting = service.bluetoothConnectionState.value == BluetoothConnectionState.connecting;
        final serialConnecting = service.serialConnectionState.value == SerialConnectionState.connecting;

        // If the widget's local state is loading OR the service's state is stuck connecting
        if (_isLoading || btConnecting || serialConnecting) {
          // Force-call disconnect to reset both the service's state
          // and the local _isLoading flag (inside _disconnect).
          _disconnectFromAll();
        } else {
          // If not stuck, just a normal refresh
          setState(() {});
        }
      }
    }
  }
  // --- END: MODIFIED LIFECYCLE METHOD ---

  void _initializeControllers() {
    widget.data.dataCaptureDate = widget.data.samplingDate;
    widget.data.dataCaptureTime = widget.data.samplingTime;

    _sondeIdController.text = widget.data.sondeId ?? '';
    _dateController.text = widget.data.dataCaptureDate ?? '';
    _timeController.text = widget.data.dataCaptureTime ?? '';

    widget.data.oxygenConcentration ??= -999.0;
    widget.data.oxygenSaturation ??= -999.0;
    widget.data.ph ??= -999.0;
    widget.data.salinity ??= -999.0;
    widget.data.electricalConductivity ??= -999.0;
    widget.data.temperature ??= -999.0;
    widget.data.tds ??= -999.0;
    widget.data.turbidity ??= -999.0;
    widget.data.tss ??= -999.0;
    widget.data.batteryVoltage ??= -999.0;

    _oxyConcController.text = widget.data.oxygenConcentration!.toString();
    _oxySatController.text = widget.data.oxygenSaturation!.toString();
    _phController.text = widget.data.ph!.toString();
    _salinityController.text = widget.data.salinity!.toString();
    _ecController.text = widget.data.electricalConductivity!.toString();
    _tempController.text = widget.data.temperature!.toString();
    _tdsController.text = widget.data.tds!.toString();
    _turbidityController.text = widget.data.turbidity!.toString();
    _tssController.text = widget.data.tss!.toString();
    _batteryController.text = widget.data.batteryVoltage!.toString();

    if (_parameters.isEmpty) {
      _parameters.addAll([
        {'key': 'oxygenConcentration', 'icon': Icons.air, 'label': 'Oxygen Conc.', 'unit': 'mg/L', 'controller': _oxyConcController},
        {'key': 'oxygenSaturation', 'icon': Icons.percent, 'label': 'Oxygen Sat.', 'unit': '%', 'controller': _oxySatController},
        {'key': 'ph', 'icon': Icons.science_outlined, 'label': 'pH', 'unit': '', 'controller': _phController},
        {'key': 'salinity', 'icon': Icons.waves, 'label': 'Salinity', 'unit': 'ppt', 'controller': _salinityController},
        {'key': 'electricalConductivity', 'icon': Icons.flash_on, 'label': 'Conductivity', 'unit': 'µS/cm', 'controller': _ecController},
        {'key': 'temperature', 'icon': Icons.thermostat, 'label': 'Temperature', 'unit': '°C', 'controller': _tempController},
        {'key': 'tds', 'icon': Icons.grain, 'label': 'TDS', 'unit': 'mg/L', 'controller': _tdsController},
        {'key': 'turbidity', 'icon': Icons.opacity, 'label': 'Turbidity', 'unit': 'NTU', 'controller': _turbidityController},
        {'key': 'tss', 'icon': Icons.filter_alt_outlined, 'label': 'TSS', 'unit': 'mg/L', 'controller': _tssController},
        {'key': 'batteryVoltage', 'icon': Icons.battery_charging_full, 'label': 'Battery', 'unit': 'V', 'controller': _batteryController},
      ]);
    }
  }

  void _disposeControllers() {
    _sondeIdController.dispose();
    _dateController.dispose();
    _timeController.dispose();
    _oxyConcController.dispose();
    _oxySatController.dispose();
    _phController.dispose();
    _salinityController.dispose();
    _ecController.dispose();
    _tempController.dispose();
    _tdsController.dispose();
    _turbidityController.dispose();
    _tssController.dispose();
    _batteryController.dispose();
  }

  Future<void> _handleConnectionAttempt(String type) async {
    final service = context.read<MarineInSituSamplingService>();
    final hasPermissions = await service.requestDevicePermissions();
    if (!mounted) return; // --- FIX: Prevent context usage if unmounted ---

    if (!hasPermissions && mounted) {
      _showSnackBar("Bluetooth & Location permissions are required to connect.", isError: true);
      return;
    }
    _disconnectFromAll();
    await Future.delayed(const Duration(milliseconds: 250));
    if (!mounted) return; // --- FIX ---

    final bool connectionSuccess = await _connectToDevice(type);
    if (connectionSuccess && mounted) {
      _dataSubscription?.cancel();
      final stream = type == 'bluetooth' ? service.bluetoothDataStream : service.serialDataStream;
      _dataSubscription = stream.listen((readings) {
        if (mounted) _updateTextFields(readings);
      });
    }
  }

  Future<bool> _connectToDevice(String type) async {
    setState(() => _isLoading = true);
    final service = context.read<MarineInSituSamplingService>();
    bool success = false;
    try {
      if (type == 'bluetooth') {
        final devices = await service.getPairedBluetoothDevices();
        if (!mounted) return false; // --- FIX ---

        if (devices.isEmpty && mounted) {
          _showSnackBar('No paired Bluetooth devices found.', isError: true);
          return false;
        }
        final selectedDevice = await showBluetoothDeviceListDialog(context: context, devices: devices);
        if (selectedDevice != null) {
          await service.connectToBluetoothDevice(selectedDevice);
          success = true;
        }
      } else if (type == 'serial') {
        final devices = await service.getAvailableSerialDevices();
        if (!mounted) return false; // --- FIX ---

        if (devices.isEmpty && mounted) {
          _showSnackBar('No USB Serial devices found.', isError: true);
          return false;
        }
        final selectedDevice = await showSerialPortListDialog(context: context, devices: devices);
        if (selectedDevice != null) {
          await service.connectToSerialDevice(selectedDevice);
          success = true;
        }
      }
    } catch (e) {
      debugPrint("Connection failed: $e");
      if (mounted) _showConnectionFailedDialog();
    } finally {
      if (mounted) setState(() => _isLoading = false);
    }
    return success;
  }

  Future<void> _showConnectionFailedDialog() async {
    if (!mounted) return;
    return showDialog<void>(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Connection Failed'),
          content: const SingleChildScrollView(
            child: Text('Could not connect to the device. Please check that the device is turned on, within range, and not connected to another application.'),
          ),
          actions: <Widget>[
            TextButton(
              child: const Text('OK'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }

  // --- START MODIFICATION: Countdown Timer Logic ---
  void _startLockoutTimer() {
    _lockoutTimer?.cancel();
    setState(() {
      _isLockedOut = true;
      _lockoutSecondsRemaining = 30;
    });

    _lockoutTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
      if (_lockoutSecondsRemaining > 0) {
        if (mounted) {
          setState(() {
            _lockoutSecondsRemaining--;
          });
        }
      } else {
        timer.cancel();
        if (mounted) {
          setState(() {
            _isLockedOut = false;
          });
        }
      }
    });
  }
  // --- END MODIFICATION ---

  void _toggleAutoReading(String activeType) {
    final service = context.read<MarineInSituSamplingService>();
    setState(() {
      _isAutoReading = !_isAutoReading;
      if (_isAutoReading) {
        if (activeType == 'bluetooth') service.startBluetoothAutoReading(); else service.startSerialAutoReading();
        _startLockoutTimer(); // --- MODIFICATION: Start countdown
      } else {
        if (activeType == 'bluetooth') service.stopBluetoothAutoReading(); else service.stopSerialAutoReading();
      }
    });
  }

  // --- START: MODIFIED DISCONNECT METHOD ---
  void _disconnect(String type) {
    // Use the member variable, not context, for lifecycle safety
    final service = _samplingService;
    if (type == 'bluetooth') {
      service.disconnectFromBluetooth();
    } else {
      service.disconnectFromSerial();
    }
    _dataSubscription?.cancel();
    _dataSubscription = null;
    _lockoutTimer?.cancel(); // --- MODIFICATION: Cancel timer on disconnect ---
    if (mounted) {
      setState(() {
        _isAutoReading = false;
        _isLockedOut = false; // --- MODIFICATION: Reset lockout state ---
        _isLoading = false;   // <-- CRITICAL: Also reset the loading flag
      });
    }
  }
  // --- END: MODIFIED DISCONNECT METHOD ---

  // --- START: MODIFIED DISCONNECT_ALL METHOD ---
  void _disconnectFromAll() {
    // Use the member variable, not context, for lifecycle safety
    final service = _samplingService;
    if (service.bluetoothConnectionState.value != BluetoothConnectionState.disconnected) {
      _disconnect('bluetooth');
    }
    if (service.serialConnectionState.value != SerialConnectionState.disconnected) {
      _disconnect('serial');
    }
  }
  // --- END: MODIFIED DISCONNECT_ALL METHOD ---

  void _updateTextFields(Map<String, double> readings) {
    const defaultValue = -999.0;
    setState(() {
      _oxyConcController.text = (readings['Optical Dissolved Oxygen: Compensated mg/L'] ?? defaultValue).toStringAsFixed(5);
      _oxySatController.text = (readings['Optical Dissolved Oxygen: Compensated % Saturation'] ?? defaultValue).toStringAsFixed(5);
      _phController.text = (readings['PH: PH units'] ?? defaultValue).toStringAsFixed(5);
      _tempController.text = (readings['External Temp: Degrees Celcius'] ?? defaultValue).toStringAsFixed(5);
      _ecController.text = (readings['Conductivity: us/cm'] ?? defaultValue).toStringAsFixed(5);
      _salinityController.text = (readings['Conductivity: Salinity'] ?? defaultValue).toStringAsFixed(5);
      _tdsController.text = (readings['Conductivity:TDS mg/L'] ?? defaultValue).toStringAsFixed(5);
      _tssController.text = (readings['Turbidity: TSS'] ?? defaultValue).toStringAsFixed(5);
      _turbidityController.text = (readings['Turbidity: FNU'] ?? defaultValue).toStringAsFixed(5);
      _batteryController.text = (readings['Sonde: Battery Voltage'] ?? defaultValue).toStringAsFixed(5);
    });
  }

  void _validateAndProceed() {
    // --- START MODIFICATION: Add lockout check ---
    if (_isLockedOut) {
      _showSnackBar("Please wait for the initial reading period to complete.", isError: true);
      return;
    }
    // --- END MODIFICATION ---

    if (_isAutoReading) {
      _showStopReadingDialog();
      return;
    }
    if (!_formKey.currentState!.validate()) {
      return;
    }
    _formKey.currentState!.save();

    final currentReadings = _captureReadingsToMap();
    final authProvider = Provider.of<AuthProvider>(context, listen: false);
    final marineLimits = authProvider.marineParameterLimits ?? [];
    final outOfBoundsParams = _validateParameters(currentReadings, marineLimits);

    setState(() {
      _outOfBoundsKeys = outOfBoundsParams.map((p) => _parameters.firstWhere((param) => param['label'] == p['label'])['key'] as String).toSet();
    });

    if (outOfBoundsParams.isNotEmpty) {
      _showParameterLimitDialog(outOfBoundsParams, currentReadings);
    } else {
      _saveDataAndMoveOn(currentReadings);
    }
  }

  Map<String, double> _captureReadingsToMap() {
    final Map<String, double> readings = {};
    for (var param in _parameters) {
      final key = param['key'] as String;
      final controller = param['controller'] as TextEditingController;
      readings[key] = double.tryParse(controller.text) ?? -999.0;
    }
    return readings;
  }

  List<Map<String, dynamic>> _validateParameters(Map<String, double> readings, List<Map<String, dynamic>> limits) {
    final List<Map<String, dynamic>> invalidParams = [];
    // --- FIX: Try both station_id and man_station_id from the data object ---
    final dynamic stationId = widget.data.selectedStation?['station_id'] ?? widget.data.selectedStation?['man_station_id'];

    debugPrint("--- Parameter Validation Start ---");
    debugPrint("Selected Station ID: $stationId");
    debugPrint("Total Marine Limits Loaded: ${limits.length}");

    double? _parseLimitValue(dynamic value) {
      if (value == null) return null;
      if (value is num) return value.toDouble();
      if (value is String) return double.tryParse(value);
      return null;
    }

    readings.forEach((key, value) {
      if (value == -999.0) return;

      final limitName = _parameterKeyToLimitName[key];
      if (limitName == null) return;

      debugPrint("Checking parameter: '$limitName' (key: '$key')");

      Map<String, dynamic> limitData = {};

      if (stationId != null) {
        // --- START FIX: Use robust string comparison to handle data type differences ---
        limitData = limits.firstWhere(
              (l) => l['param_parameter_list'] == limitName &&
              (l['station_id']?.toString() == stationId.toString() || l['man_station_id']?.toString() == stationId.toString()),
          orElse: () => {},
        );
        // --- END FIX ---
      }

      if (limitData.isNotEmpty) {
        debugPrint("  > Found station-specific limit: $limitData");
        final lowerLimit = _parseLimitValue(limitData['param_lower_limit']);
        final upperLimit = _parseLimitValue(limitData['param_upper_limit']);

        if ((lowerLimit != null && value < lowerLimit) || (upperLimit != null && value > upperLimit)) {
          final paramInfo = _parameters.firstWhere((p) => p['key'] == key, orElse: () => {});
          invalidParams.add({
            'label': paramInfo['label'] ?? key,
            'value': value,
            'lower_limit': lowerLimit,
            'upper_limit': upperLimit,
          });
        }
      } else {
        debugPrint("  > No station-specific limit found for $limitName.");
      }
    });

    debugPrint("--- Parameter Validation End ---");

    return invalidParams;
  }

  void _saveDataAndMoveOn(Map<String, double> readings) {
    try {
      const defaultValue = -999.0;
      widget.data.temperature = readings['temperature'] ?? defaultValue;
      widget.data.ph = readings['ph'] ?? defaultValue;
      widget.data.salinity = readings['salinity'] ?? defaultValue;
      widget.data.electricalConductivity = readings['electricalConductivity'] ?? defaultValue;
      widget.data.oxygenConcentration = readings['oxygenConcentration'] ?? defaultValue;
      widget.data.oxygenSaturation = readings['oxygenSaturation'] ?? defaultValue;
      widget.data.tds = readings['tds'] ?? defaultValue;
      widget.data.turbidity = readings['turbidity'] ?? defaultValue;
      widget.data.tss = readings['tss'] ?? defaultValue;
      widget.data.batteryVoltage = readings['batteryVoltage'] ?? defaultValue;
    } catch (e) {
      _showSnackBar("Could not save parameters due to a data format error.", isError: true);
      return;
    }

    setState(() {
      _outOfBoundsKeys.clear();
      if (_previousReadingsForComparison != null) {
        _previousReadingsForComparison = null;
      }
    });

    widget.onNext();
  }

  void _showStopReadingDialog() {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Data Collection Active'),
          content: const Text('Please stop the live data collection before proceeding.'),
          actions: <Widget>[
            TextButton(
              child: const Text('OK'),
              onPressed: () => Navigator.of(context).pop(),
            ),
          ],
        );
      },
    );
  }

  void _showSnackBar(String message, {bool isError = false}) {
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(
        content: Text(message),
        backgroundColor: isError ? Colors.red : null,
      ));
    }
  }

  Map<String, dynamic>? _getActiveConnectionDetails() {
    final service = context.watch<MarineInSituSamplingService>();
    if (service.bluetoothConnectionState.value != BluetoothConnectionState.disconnected) {
      return {'type': 'bluetooth', 'state': service.bluetoothConnectionState.value, 'name': service.connectedBluetoothDeviceName};
    }
    if (service.serialConnectionState.value != SerialConnectionState.disconnected) {
      return {'type': 'serial', 'state': service.serialConnectionState.value, 'name': service.connectedSerialDeviceName};
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    final service = context.watch<MarineInSituSamplingService>();
    final activeConnection = _getActiveConnectionDetails();
    final String? activeType = activeConnection?['type'] as String?;

    // --- START MODIFICATION: Add WillPopScope to block back navigation ---
    return WillPopScope(
      onWillPop: () async {
        if (_isLockedOut) {
          _showSnackBar("Please wait for the initial reading period to complete.", isError: true);
          return false; // Prevent back navigation
        }
        return true; // Allow back navigation
      },
      child: Form(
        key: _formKey,
        child: ListView(
          padding: const EdgeInsets.all(24.0),
          children: [
            Text("Data Capture", style: Theme.of(context).textTheme.headlineSmall),
            const SizedBox(height: 16),
            Row(
              children: [
                Expanded(
                  child: activeType == 'bluetooth'
                      ? FilledButton.icon(icon: const Icon(Icons.bluetooth_connected), label: const Text("Bluetooth"), onPressed: _isLoading ? null : () => _handleConnectionAttempt('bluetooth'))
                      : OutlinedButton.icon(icon: const Icon(Icons.bluetooth), label: const Text("Bluetooth"), onPressed: _isLoading ? null : () => _handleConnectionAttempt('bluetooth')),
                ),
                const SizedBox(width: 16),
                Expanded(
                  child: activeType == 'serial'
                      ? FilledButton.icon(icon: const Icon(Icons.usb), label: const Text("USB Serial"), onPressed: _isLoading ? null : () => _handleConnectionAttempt('serial'))
                      : OutlinedButton.icon(icon: const Icon(Icons.usb), label: const Text("USB Serial"), onPressed: _isLoading ? null : () => _handleConnectionAttempt('serial')),
                ),
              ],
            ),
            const SizedBox(height: 16),
            if (activeConnection != null)
              _buildConnectionCard(type: activeConnection['type'], connectionState: activeConnection['state'], deviceName: activeConnection['name']),
            const SizedBox(height: 24),
            // START FIX: Restored ValueListenableBuilder to listen for Sonde ID updates.
            ValueListenableBuilder<String?>(
              valueListenable: service.sondeId,
              builder: (context, sondeId, child) {
                final newSondeId = sondeId ?? '';
                // Use a post-frame callback to safely update the controller after the build.
                WidgetsBinding.instance.addPostFrameCallback((_) {
                  if (mounted && _sondeIdController.text != newSondeId) {
                    _sondeIdController.text = newSondeId;
                    widget.data.sondeId = newSondeId;
                  }
                });
                return TextFormField(
                  controller: _sondeIdController,
                  decoration: const InputDecoration(labelText: 'Sonde ID *', hintText: 'Connect device or enter manually'),
                  validator: (v) => v == null || v.isEmpty ? 'Sonde ID is required' : null,
                  onChanged: (value) => widget.data.sondeId = value,
                  onSaved: (v) => widget.data.sondeId = v,
                );
              },
            ),
            // END FIX
            const SizedBox(height: 16),
            Row(
              children: [
                Expanded(child: TextFormField(controller: _dateController, readOnly: true, decoration: const InputDecoration(labelText: 'Date'))),
                const SizedBox(width: 16),
                Expanded(child: TextFormField(controller: _timeController, readOnly: true, decoration: const InputDecoration(labelText: 'Time'))),
              ],
            ),

            if (_previousReadingsForComparison != null)
              _buildComparisonView(),

            const Divider(height: 32),
            Column(
              children: _parameters.map((param) {
                return _buildParameterListItem(
                  icon: param['icon'] as IconData,
                  label: param['label'] as String,
                  unit: param['unit'] as String,
                  controller: param['controller'] as TextEditingController,
                  isOutOfBounds: _outOfBoundsKeys.contains(param['key']),
                );
              }).toList(),
            ),
            const SizedBox(height: 32),
            // --- START MODIFICATION: Add countdown to Next button ---
            ElevatedButton(
              onPressed: _isLockedOut ? null : _validateAndProceed,
              style: ElevatedButton.styleFrom(padding: const EdgeInsets.symmetric(vertical: 16)),
              child: Text(_isLockedOut ? 'Next ($_lockoutSecondsRemaining\s)' : 'Next'),
            ),
            // --- END MODIFICATION ---
          ],
        ),
      ),
    );
    // --- END MODIFICATION ---
  }

  Widget _buildComparisonView() {
    final previousReadings = _previousReadingsForComparison!;
    final isDarkTheme = Theme.of(context).brightness == Brightness.dark;

    return Card(
      margin: const EdgeInsets.only(top: 24.0),
      color: Theme.of(context).cardColor,
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: DefaultTextStyle(
          style: TextStyle(color: Theme.of(context).textTheme.bodyLarge?.color),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                "Resample Comparison",
                style: Theme.of(context).textTheme.titleLarge?.copyWith(color: Theme.of(context).primaryColor),
              ),
              const SizedBox(height: 8),
              Table(
                columnWidths: const {
                  0: FlexColumnWidth(2),
                  1: FlexColumnWidth(1.5),
                  2: FlexColumnWidth(1.5),
                },
                border: TableBorder(
                  horizontalInside: BorderSide(width: 1, color: Colors.grey.shade700, style: BorderStyle.solid),
                  verticalInside: BorderSide(width: 1, color: Colors.grey.shade700, style: BorderStyle.solid),
                  top: BorderSide(width: 1.5, color: Colors.grey.shade500),
                  bottom: BorderSide(width: 1.5, color: Colors.grey.shade500),
                ),
                children: [
                  TableRow(
                    decoration: BoxDecoration(color: isDarkTheme ? Colors.grey.shade800 : Colors.grey.shade200),
                    children: [
                      Padding(padding: const EdgeInsets.all(8.0), child: Text('Parameter', style: TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).textTheme.titleMedium?.color))),
                      Padding(padding: const EdgeInsets.all(8.0), child: Text('Previous', style: TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).textTheme.titleMedium?.color))),
                      Padding(padding: const EdgeInsets.all(8.0), child: Text('Current', style: TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).textTheme.titleMedium?.color))),
                    ],
                  ),
                  ..._parameters.map((param) {
                    final key = param['key'] as String;
                    final label = param['label'] as String;
                    final controller = param['controller'] as TextEditingController;
                    final previousValue = previousReadings[key];
                    final bool isCurrentValueOutOfBounds = _outOfBoundsKeys.contains(key);

                    return TableRow(
                      children: [
                        Padding(padding: const EdgeInsets.all(8.0), child: Text(label)),
                        Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: Text(
                            previousValue == -999.0 ? '-.--' : previousValue!.toStringAsFixed(5),
                            style: TextStyle(color: isDarkTheme ? Colors.orange.shade200 : Colors.orange.shade700),
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: Text(
                            controller.text.contains('-999') ? '-.--' : (double.tryParse(controller.text) ?? 0).toStringAsFixed(5),
                            style: TextStyle(
                                color: isCurrentValueOutOfBounds
                                    ? Colors.red
                                    : (isDarkTheme ? Colors.green.shade200 : Colors.green.shade700),
                                fontWeight: FontWeight.bold
                            ),
                          ),
                        ),
                      ],
                    );
                  }).toList(),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _showParameterLimitDialog(List<Map<String, dynamic>> invalidParams, Map<String, double> readings) async {
    return showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
        return AlertDialog(
          title: const Text('Parameter Limit Warning'),
          content: SingleChildScrollView(
            child: DefaultTextStyle(
              style: TextStyle(color: Theme.of(context).textTheme.bodyMedium?.color),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const Text('The following parameters are outside the standard limits:'),
                  const SizedBox(height: 16),
                  Table(
                    columnWidths: const {
                      0: FlexColumnWidth(2),
                      1: FlexColumnWidth(2.5),
                      2: FlexColumnWidth(1.5),
                    },
                    border: TableBorder(
                      horizontalInside: BorderSide(width: 0.5, color: isDarkTheme ? Colors.grey.shade700 : Colors.grey.shade300),
                      verticalInside: BorderSide(width: 0.5, color: isDarkTheme ? Colors.grey.shade700 : Colors.grey.shade300),
                      top: BorderSide(width: 1, color: isDarkTheme ? Colors.grey.shade600 : Colors.grey.shade400),
                      bottom: BorderSide(width: 1, color: isDarkTheme ? Colors.grey.shade600 : Colors.grey.shade400),
                    ),
                    children: [
                      TableRow(
                        decoration: BoxDecoration(color: isDarkTheme ? Colors.grey.shade800 : Colors.grey.shade200),
                        children: [
                          Padding(padding: const EdgeInsets.all(6.0), child: Text('Parameter', style: TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).textTheme.titleSmall?.color))),
                          Padding(padding: const EdgeInsets.all(6.0), child: Text('Limit Range', style: TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).textTheme.titleSmall?.color))),
                          Padding(padding: const EdgeInsets.all(6.0), child: Text('Current', style: TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).textTheme.titleSmall?.color))),
                        ],
                      ),
                      ...invalidParams.map((p) => TableRow(
                        children: [
                          Padding(padding: const EdgeInsets.all(6.0), child: Text(p['label'])),
                          Padding(padding: const EdgeInsets.all(6.0), child: Text('${p['lower_limit']?.toStringAsFixed(5) ?? 'N/A'} - ${p['upper_limit']?.toStringAsFixed(5) ?? 'N/A'}')),
                          Padding(
                            padding: const EdgeInsets.all(6.0),
                            child: Text(
                              p['value'].toStringAsFixed(5),
                              style: const TextStyle(color: Colors.redAccent, fontWeight: FontWeight.bold),
                            ),
                          ),
                        ],
                      )).toList(),
                    ],
                  ),
                  const SizedBox(height: 16),
                  const Text('Please verify with standard solutions. Do you want to resample or proceed with the current values?'),
                ],
              ),
            ),
          ),
          actions: <Widget>[
            TextButton(
              child: const Text('Resample'),
              onPressed: () {
                setState(() {
                  _previousReadingsForComparison = readings;
                });
                Navigator.of(context).pop();
              },
            ),
            FilledButton(
              child: const Text('Proceed Anyway'),
              onPressed: () {
                Navigator.of(context).pop();
                _saveDataAndMoveOn(readings);
              },
            ),
          ],
        );
      },
    );
  }

  Widget _buildParameterListItem({required IconData icon, required String label, required String unit, required TextEditingController controller, bool isOutOfBounds = false}) {
    final bool isMissing = controller.text.isEmpty || controller.text.contains('-999');
    final String displayValue = isMissing ? '-.--' : controller.text;
    final String displayLabel = unit.isEmpty ? label : '$label ($unit)';

    final Color valueColor = isOutOfBounds
        ? Colors.red
        : (isMissing ? Colors.grey : Theme.of(context).colorScheme.primary);

    return Card(
      margin: const EdgeInsets.symmetric(vertical: 4.0),
      child: ListTile(
        leading: Icon(icon, color: Theme.of(context).primaryColor, size: 32),
        title: Text(displayLabel),
        trailing: Text(
          displayValue,
          style: Theme.of(context).textTheme.titleMedium?.copyWith(
              fontWeight: FontWeight.bold,
              color: valueColor),
        ),
      ),
    );
  }

  Widget _buildConnectionCard({required String type, required dynamic connectionState, String? deviceName}) {
    final isConnected = connectionState == BluetoothConnectionState.connected || connectionState == SerialConnectionState.connected;
    final isConnecting = connectionState == BluetoothConnectionState.connecting || connectionState == SerialConnectionState.connecting;
    Color statusColor = isConnected ? Colors.green : Colors.red;
    String statusText = isConnected ? 'Connected to ${deviceName ?? 'device'}' : 'Disconnected';
    if (isConnecting) {
      statusColor = Colors.orange;
      statusText = 'Connecting...';
    }
    return Card(
      elevation: 2,
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            Text(statusText, style: TextStyle(color: statusColor, fontWeight: FontWeight.bold, fontSize: 16)),
            const SizedBox(height: 16),
            if (isConnecting || _isLoading)
              const CircularProgressIndicator()
            else if (isConnected)
            // --- START MODIFICATION: Replaced Row with Wrap to fix overflow ---
              Wrap(
                alignment: WrapAlignment.spaceEvenly, // Lays them out with space
                crossAxisAlignment: WrapCrossAlignment.center,
                spacing: 8.0, // Horizontal space between buttons
                runSpacing: 4.0, // Vertical space if it wraps
                children: [
                  ElevatedButton.icon(
                    icon: Icon(_isAutoReading ? Icons.stop_circle_outlined : Icons.play_circle_outlined),
                    label: Text(_isAutoReading
                        ? (_isLockedOut ? 'Stop Reading ($_lockoutSecondsRemaining\s)' : 'Stop Reading')
                        : 'Start Reading'),
                    onPressed: (_isAutoReading && _isLockedOut) ? null : () => _toggleAutoReading(type),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: _isAutoReading
                          ? (_isLockedOut ? Colors.grey.shade600 : Colors.orange)
                          : Colors.green,
                      foregroundColor: Colors.white,
                    ),
                  ),
                  TextButton.icon(
                    icon: const Icon(Icons.link_off),
                    label: const Text('Disconnect'),
                    onPressed: () => _disconnect(type),
                    style: TextButton.styleFrom(foregroundColor: Colors.red),
                  )
                ],
              )
            // --- END MODIFICATION ---
          ],
        ),
      ),
    );
  }
}