import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:geolocator/geolocator.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:dropdown_search/dropdown_search.dart';

import '../../../../auth_provider.dart';
import '../../../../models/in_situ_sampling_data.dart';
import '../../../../models/marine_manual_npe_report_data.dart';
import '../../../../services/marine_in_situ_sampling_service.dart';
import '../../../../services/marine_npe_report_service.dart';
import '../../../../services/local_storage_service.dart';
import '../../../../bluetooth/bluetooth_manager.dart';
import '../../../../serial/serial_manager.dart';
import '../../../../bluetooth/widgets/bluetooth_device_list_dialog.dart';
import '../../../../serial/widget/serial_port_list_dialog.dart';

class MarineManualNPEReport extends StatefulWidget {
  final InSituSamplingData? initialData;

  const MarineManualNPEReport({super.key, this.initialData});

  @override
  State<MarineManualNPEReport> createState() => _MarineManualNPEReportState();
}

class _MarineManualNPEReportState extends State<MarineManualNPEReport> with WidgetsBindingObserver {
  final _formKey = GlobalKey<FormState>();

  String? _locationDataSourceOption;
  static const String optionUseExisting = 'Use existing sampling information and data from manual station';
  static const String optionNewLocation = 'new location pollution event observe';
  static const String optionSelectStation = 'Select sampling information from tarball station';

  final List<String> _locationOptions = [
    optionUseExisting,
    optionNewLocation,
    optionSelectStation,
  ];
  bool _areLocationFieldsLocked = false;
  bool _isFetchingLocation = false;

  bool _isLoadingRecentSamples = false;
  List<InSituSamplingData> _recentNearbySamples = [];
  InSituSamplingData? _selectedRecentSample;

  String? _selectedState;
  String? _selectedCategory;
  Map<String, dynamic>? _selectedStationMap;
  List<String> _statesList = [];
  List<String> _categoriesForState = [];
  List<Map<String, dynamic>> _stationsForCategory = [];

  File? _image1;
  File? _image2;
  File? _image3;
  File? _image4;
  bool _isPickingImage = false;

  bool _isLoading = false;
  bool _isAutoReading = false;
  StreamSubscription? _dataSubscription;
  Timer? _lockoutTimer;
  int _lockoutSecondsRemaining = 30;
  bool _isLockedOut = false;
  late final MarineInSituSamplingService _samplingService;
  final List<Map<String, dynamic>> _npeParameters = [];

  final _latController = TextEditingController();
  final _longController = TextEditingController();
  final _stationIdController = TextEditingController();
  final _locationController = TextEditingController();
  final _eventDateTimeController = TextEditingController();
  final _doPercentController = TextEditingController();
  final _doMgLController = TextEditingController();
  final _phController = TextEditingController();
  final _condController = TextEditingController();
  final _turbController = TextEditingController();
  final _tempController = TextEditingController();
  final _othersObservationController = TextEditingController();
  final _possibleSourceController = TextEditingController();

  final Map<String, bool> _observations = {
    'Oil slick on the water surface/ Oil spill': false,
    'Discoloration of the sea water': false,
    'Formation of foam on the surface': false,
    'Coral bleaching or dead corals': false,
    'Observation of tar balls': false,
    'Excessive debris': false,
    'Red tides or algae blooms': false,
    'Silt plume': false,
    'Foul smell': false,
    'Others': false,
  };

  @override
  void initState() {
    super.initState();
    _samplingService = Provider.of<MarineInSituSamplingService>(context, listen: false);

    if (widget.initialData != null) {
      _locationDataSourceOption = optionUseExisting;
      _recentNearbySamples = [widget.initialData!];
      _selectedRecentSample = widget.initialData!;
      _populateFormFromData(widget.initialData!);
      _setDefaultDateTime();
    } else {
      _locationDataSourceOption = optionNewLocation;
      _handleLocationOptionChange(_locationDataSourceOption);
    }
    _loadAllStatesFromProvider();
    _initializeNpeParameters();
    WidgetsBinding.instance.addObserver(this);
  }

  void _initializeNpeParameters() {
    if (_npeParameters.isEmpty) {
      _npeParameters.addAll([
        {'key': 'oxygenSaturation', 'icon': Icons.percent, 'label': 'DO %', 'unit': '%', 'controller': _doPercentController},
        {'key': 'electricalConductivity', 'icon': Icons.flash_on, 'label': 'Cond', 'unit': 'µS/cm', 'controller': _condController},
        {'key': 'oxygenConcentration', 'icon': Icons.air, 'label': 'DO mg/l', 'unit': 'mg/L', 'controller': _doMgLController},
        {'key': 'turbidity', 'icon': Icons.opacity, 'label': 'Turb (NTU)', 'unit': 'NTU', 'controller': _turbController},
        {'key': 'ph', 'icon': Icons.science_outlined, 'label': 'PH', 'unit': '', 'controller': _phController},
        {'key': 'temperature', 'icon': Icons.thermostat, 'label': 'Temp (°C)', 'unit': '°C', 'controller': _tempController},
      ]);
    }
  }

  @override
  void dispose() {
    _dataSubscription?.cancel();
    _lockoutTimer?.cancel();

    if (_samplingService.bluetoothConnectionState.value != BluetoothConnectionState.disconnected) {
      _samplingService.disconnectFromBluetooth();
    }
    if (_samplingService.serialConnectionState.value != SerialConnectionState.disconnected) {
      _samplingService.disconnectFromSerial();
    }

    _latController.dispose();
    _longController.dispose();
    _stationIdController.dispose();
    _locationController.dispose();
    _eventDateTimeController.dispose();
    _doPercentController.dispose();
    _doMgLController.dispose();
    _phController.dispose();
    _condController.dispose();
    _turbController.dispose();
    _tempController.dispose();
    _othersObservationController.dispose();
    _possibleSourceController.dispose();

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

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      if (mounted) {
        setState(() {});
      }
    }
  }

  void _setDefaultDateTime() {
    final now = DateTime.now();
    _eventDateTimeController.text = DateFormat('yyyy-MM-dd HH:mm').format(now);
  }

  void _clearInSituFields() {
    _doPercentController.clear();
    _doMgLController.clear();
    _phController.clear();
    _condController.clear();
    _turbController.clear();
    _tempController.clear();
  }

  void _populateFormFromData(InSituSamplingData data) {
    _stationIdController.text = data.selectedStation?['man_station_code'] ?? 'N/A';
    _locationController.text = data.selectedStation?['man_station_name'] ?? 'N/A';
    _latController.text = data.currentLatitude ?? data.stationLatitude ?? '';
    _longController.text = data.currentLongitude ?? data.stationLongitude ?? '';

    if (data.oxygenSaturation != null && data.oxygenSaturation != -999) _doPercentController.text = data.oxygenSaturation!.toStringAsFixed(5);
    if (data.oxygenConcentration != null && data.oxygenConcentration != -999) _doMgLController.text = data.oxygenConcentration!.toStringAsFixed(5);
    if (data.ph != null && data.ph != -999) _phController.text = data.ph!.toStringAsFixed(5);
    if (data.electricalConductivity != null && data.electricalConductivity != -999) _condController.text = data.electricalConductivity!.toStringAsFixed(5);
    if (data.turbidity != null && data.turbidity != -999) _turbController.text = data.turbidity!.toStringAsFixed(5);
    if (data.temperature != null && data.temperature != -999) _tempController.text = data.temperature!.toStringAsFixed(5);

    setState(() {
      _areLocationFieldsLocked = true;
    });
  }

  void _loadAllStatesFromProvider() {
    final auth = Provider.of<AuthProvider>(context, listen: false);
    final manualStations = auth.manualStations ?? [];
    final tarballStations = auth.tarballStations ?? [];

    final states = <String>{};
    for (var station in manualStations) {
      if (station['state_name'] != null) states.add(station['state_name']);
    }
    for (var station in tarballStations) {
      if (station['state_name'] != null) states.add(station['state_name']);
    }

    final sortedStates = states.toList()..sort();
    setState(() {
      _statesList = sortedStates;
    });
  }

  Future<void> _fetchRecentNearbySamples() async {
    setState(() {
      _isLoadingRecentSamples = true;
      _recentNearbySamples = [];
      _selectedRecentSample = null;
    });

    try {
      final localDbService = Provider.of<LocalStorageService>(context, listen: false);
      final Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);

      final samples = await localDbService.getRecentNearbySamples(
        latitude: position.latitude,
        longitude: position.longitude,
        radiusKm: 3,
        withinHours: 30 * 24,
      );

      if (mounted) {
        setState(() {
          _recentNearbySamples = samples;
        });
      }
    } catch (e) {
      if (mounted) {
        _showSnackBar("Failed to fetch recent samples: ${e.toString()}", isError: true);
      }
    } finally {
      if (mounted) {
        setState(() {
          _isLoadingRecentSamples = false;
        });
      }
    }
  }

  void _handleLocationOptionChange(String? value) {
    setState(() {
      _locationDataSourceOption = value;
      _clearLocationFields();
      _clearInSituFields();
      _selectedState = null;
      _selectedCategory = null;
      _selectedStationMap = null;
      _categoriesForState = [];
      _stationsForCategory = [];
      _recentNearbySamples = [];
      _selectedRecentSample = null;
      _setDefaultDateTime();

      if (value == optionUseExisting) {
        _areLocationFieldsLocked = true;
        _fetchRecentNearbySamples();
      } else {
        _areLocationFieldsLocked = (value == optionSelectStation);
      }
    });
  }

  void _clearLocationFields() {
    _stationIdController.clear();
    _locationController.clear();
    _latController.clear();
    _longController.clear();
    _eventDateTimeController.clear();
  }

  Future<void> _getCurrentLocation() async {
    var status = await Permission.location.request();
    if (!status.isGranted) {
      _showSnackBar('Location permission is required to fetch coordinates.', isError: true);
      return;
    }

    bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      _showSnackBar('Location services are disabled.', isError: true);
      return;
    }

    setState(() {
      _isFetchingLocation = true;
    });
    try {
      Position position = await Geolocator.getCurrentPosition(
          desiredAccuracy: LocationAccuracy.high);
      _latController.text = position.latitude.toStringAsFixed(6);
      _longController.text = position.longitude.toStringAsFixed(6);
    } catch (e) {
      _showSnackBar('Failed to get location: ${e.toString()}', isError: true);
    } finally {
      if (mounted) {
        setState(() {
          _isFetchingLocation = false;
        });
      }
    }
  }

  Future<void> _processAndSetImage(ImageSource source, int imageNumber) async {
    if (_isPickingImage) return;
    setState(() => _isPickingImage = true);

    final watermarkData = InSituSamplingData()
      ..samplingDate = _eventDateTimeController.text.split(' ')[0]
      ..samplingTime = _eventDateTimeController.text.split(' ').length > 1 ? _eventDateTimeController.text.split(' ')[1] : ''
      ..currentLatitude = _latController.text
      ..currentLongitude = _longController.text
      ..selectedStation = {'man_station_name': _locationController.text};

    final file = await _samplingService.pickAndProcessImage(
      source,
      data: watermarkData,
      imageInfo: 'NPE ATTACHMENT $imageNumber',
      isRequired: false,
    );

    if (file != null) {
      setState(() {
        switch (imageNumber) {
          case 1: _image1 = file; break;
          case 2: _image2 = file; break;
          case 3: _image3 = file; break;
          case 4: _image4 = file; break;
        }
      });
    } else if (mounted) {
      _showSnackBar('Image selection failed. Please ensure photos are taken in landscape mode.', isError: true);
    }

    if (mounted) {
      setState(() => _isPickingImage = false);
    }
  }

  Future<void> _submitNpeReport() async {
    if (!_formKey.currentState!.validate()) {
      _showSnackBar('Please fill in all required fields.', isError: true);
      return;
    }

    setState(() => _isLoading = true);

    final auth = Provider.of<AuthProvider>(context, listen: false);
    final service = Provider.of<MarineNpeReportService>(context, listen: false);

    final MarineManualNpeReportData data = MarineManualNpeReportData()
      ..firstSamplerName = auth.profileData?['user_name']
      ..firstSamplerUserId = auth.profileData?['user_id']
      ..eventDate = _eventDateTimeController.text.split(' ')[0]
      ..eventTime = _eventDateTimeController.text.split(' ').length > 1 ? _eventDateTimeController.text.split(' ')[1] : ''
      ..latitude = _latController.text
      ..longitude = _longController.text
      ..selectedStation = _selectedStationMap ?? _selectedRecentSample?.selectedStation
      ..locationDescription = _locationController.text
      ..stateName = _selectedState
      ..oxygenSaturation = double.tryParse(_doPercentController.text)
      ..electricalConductivity = double.tryParse(_condController.text)
      ..oxygenConcentration = double.tryParse(_doMgLController.text)
      ..turbidity = double.tryParse(_turbController.text)
      ..ph = double.tryParse(_phController.text)
      ..temperature = double.tryParse(_tempController.text)
      ..fieldObservations = _observations
      ..othersObservationRemark = _othersObservationController.text
      ..possibleSource = _possibleSourceController.text
      ..image1 = _image1
      ..image2 = _image2
      ..image3 = _image3
      ..image4 = _image4;

    final result = await service.submitNpeReport(
      data: data,
      authProvider: auth,
    );

    setState(() => _isLoading = false);

    if (mounted) {
      _showSnackBar(result['message'], isError: result['success'] != true);
      if (result['success'] == true) {
        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,
      ));
    }
  }

  Future<void> _handleConnectionAttempt(String type) async {
    final hasPermissions = await _samplingService.requestDevicePermissions();
    if (!hasPermissions && mounted) {
      _showSnackBar("Bluetooth & Location permissions are required.", isError: true);
      return;
    }
    _disconnectFromAll();
    await Future.delayed(const Duration(milliseconds: 250));
    final bool connectionSuccess = await _connectToDevice(type);
    if (connectionSuccess && mounted) {
      _dataSubscription?.cancel();
      final stream = type == 'bluetooth' ? _samplingService.bluetoothDataStream : _samplingService.serialDataStream;
      _dataSubscription = stream.listen((readings) {
        if (mounted) _updateTextFields(readings);
      });
    }
  }

  Future<bool> _connectToDevice(String type) async {
    setState(() => _isLoading = true);
    bool success = false;
    try {
      if (type == 'bluetooth') {
        final devices = await _samplingService.getPairedBluetoothDevices();
        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 _samplingService.connectToBluetoothDevice(selectedDevice);
          success = true;
        }
      } else if (type == 'serial') {
        final devices = await _samplingService.getAvailableSerialDevices();
        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 _samplingService.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();
              },
            ),
          ],
        );
      },
    );
  }

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

  void _toggleAutoReading(String activeType) {
    setState(() {
      _isAutoReading = !_isAutoReading;
      if (_isAutoReading) {
        if (activeType == 'bluetooth') _samplingService.startBluetoothAutoReading(); else _samplingService.startSerialAutoReading();
        _startLockoutTimer();
      } else {
        if (activeType == 'bluetooth') _samplingService.stopBluetoothAutoReading(); else _samplingService.stopSerialAutoReading();
      }
    });
  }

  void _disconnect(String type) {
    if (type == 'bluetooth') {
      _samplingService.disconnectFromBluetooth();
    } else {
      _samplingService.disconnectFromSerial();
    }
    _dataSubscription?.cancel();
    _dataSubscription = null;
    _lockoutTimer?.cancel();
    if (mounted) {
      setState(() {
        _isAutoReading = false;
        _isLockedOut = false;
      });
    }
  }

  void _disconnectFromAll() {
    if (_samplingService.bluetoothConnectionState.value != BluetoothConnectionState.disconnected) _disconnect('bluetooth');
    if (_samplingService.serialConnectionState.value != SerialConnectionState.disconnected) _disconnect('serial');
  }

  void _updateTextFields(Map<String, double> readings) {
    const defaultValue = -999.0;
    setState(() {
      _doMgLController.text = (readings['Optical Dissolved Oxygen: Compensated mg/L'] ?? defaultValue).toStringAsFixed(5);
      _doPercentController.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);
      _condController.text = (readings['Conductivity: us/cm'] ?? defaultValue).toStringAsFixed(5);
      _turbController.text = (readings['Turbidity: FNU'] ?? defaultValue).toStringAsFixed(5);
    });
  }

  Map<String, dynamic>? _getActiveConnectionDetails() {
    final service = Provider.of<MarineInSituSamplingService>(context, listen: false);
    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) {
    return Scaffold(
      appBar: AppBar(title: const Text("Notification of Pollution Event")),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(20.0),
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              _buildSectionTitle("Location Information Source"),
              DropdownButtonFormField<String>(
                value: _locationDataSourceOption,
                items: _locationOptions
                    .map((option) =>
                    DropdownMenuItem(value: option, child: Text(option)))
                    .toList(),
                onChanged: _handleLocationOptionChange,
                decoration:
                const InputDecoration(labelText: 'Select Data Source'),
              ),
              const SizedBox(height: 16),
              _buildLocationSection(),
              const SizedBox(height: 24),
              _buildSectionTitle("In-situ Measurements"),
              _buildInSituSection(),
              const SizedBox(height: 24),
              _buildSectionTitle("Field Observations*"),
              ..._buildObservationsCheckboxes(),
              const Text("*tick wherever applicable",
                  style: TextStyle(fontStyle: FontStyle.italic, fontSize: 12)),
              const SizedBox(height: 24),
              _buildSectionTitle("Possible Source"),
              _buildTextFormField(
                  controller: _possibleSourceController,
                  label: "Possible Source",
                  maxLines: 3),
              const SizedBox(height: 24),
              _buildSectionTitle("Attachments (Figures)"),
              _buildImageAttachmentSection(),
              const SizedBox(height: 32),
              Center(
                child: ElevatedButton(
                  style: ElevatedButton.styleFrom(
                      padding: const EdgeInsets.symmetric(
                          horizontal: 40, vertical: 15)),
                  onPressed: _isLoading ? null : _submitNpeReport,
                  child: _isLoading
                      ? const CircularProgressIndicator(color: Colors.white)
                      : const Text("Submit Report"),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildLocationSection() {
    final auth = Provider.of<AuthProvider>(context, listen: false);

    switch (_locationDataSourceOption) {
      case optionUseExisting:
        return Column(
          children: [
            if (_isLoadingRecentSamples)
              const Center(child: Padding(padding: EdgeInsets.all(8.0), child: CircularProgressIndicator()))
            else
              DropdownSearch<InSituSamplingData>(
                items: _recentNearbySamples,
                selectedItem: _selectedRecentSample,
                itemAsString: (sample) {
                  final stationCode = sample.selectedStation?['man_station_code'] ?? 'N/A';
                  final stationName = sample.selectedStation?['man_station_name'] ?? 'Unknown';
                  final date = sample.samplingDate ?? '';
                  final time = sample.samplingTime ?? '';
                  return "$stationCode ($stationName) at $date $time";
                },
                popupProps: PopupProps.menu(
                  showSearchBox: true,
                  searchFieldProps: const TextFieldProps(decoration: InputDecoration(hintText: "Search by station or time...")),
                  emptyBuilder: (context, searchEntry) => const Center(child: Text("No recent nearby samples found.")),
                ),
                dropdownDecoratorProps: const DropDownDecoratorProps(dropdownSearchDecoration: InputDecoration(labelText: "Select a recent sample *")),
                onChanged: (sample) {
                  if (sample != null) {
                    setState(() {
                      _selectedRecentSample = sample;
                      _populateFormFromData(sample);
                    });
                  }
                },
                validator: (val) => val == null ? "Please select a sample" : null,
              ),
            const SizedBox(height: 12),
            _buildTextFormField(controller: _stationIdController, label: "Station ID", readOnly: true),
            const SizedBox(height: 12),
            _buildTextFormField(controller: _locationController, label: "Location", readOnly: true),
            const SizedBox(height: 12),
            _buildTextFormField(controller: _latController, label: "Latitude", readOnly: true),
            const SizedBox(height: 12),
            _buildTextFormField(controller: _longController, label: "Longitude", readOnly: true),
            const SizedBox(height: 12),
            _buildTextFormField(controller: _eventDateTimeController, label: "Event Date/Time", readOnly: true),
          ],
        );
      case optionNewLocation:
        return Column(
          children: [
            DropdownSearch<String>(
              items: _statesList,
              selectedItem: _selectedState,
              popupProps: const PopupProps.menu(showSearchBox: true, searchFieldProps: TextFieldProps(decoration: InputDecoration(hintText: "Search State..."))),
              dropdownDecoratorProps: const DropDownDecoratorProps(dropdownSearchDecoration: InputDecoration(labelText: "Select State *")),
              onChanged: (state) {
                setState(() {
                  _selectedState = state;
                });
              },
              validator: (val) => val == null ? "State is required" : null,
            ),
            const SizedBox(height: 12),
            _buildTextFormField(
                controller: _locationController,
                label: "Location Description *"),
            const SizedBox(height: 12),
            Row(
              children: [
                Expanded(
                    child: _buildTextFormField(
                        controller: _latController,
                        label: "Latitude *",
                        keyboardType: TextInputType.number)),
                const SizedBox(width: 8),
                if (_isFetchingLocation)
                  const SizedBox(
                      width: 24,
                      height: 24,
                      child: CircularProgressIndicator())
                else
                  IconButton(
                      icon: const Icon(Icons.my_location),
                      onPressed: _getCurrentLocation,
                      tooltip: "Get Current Location"),
              ],
            ),
            const SizedBox(height: 12),
            _buildTextFormField(
                controller: _longController,
                label: "Longitude *",
                keyboardType: TextInputType.number),
            const SizedBox(height: 12),
            _buildTextFormField(
                controller: _eventDateTimeController,
                label: "Event Date/Time",
                readOnly: true),
          ],
        );
      case optionSelectStation:
        final allTarballStations = auth.tarballStations ?? [];
        return Column(
          children: [
            DropdownSearch<String>(
              items: allTarballStations.map((s) => s['state_name'] as String?).whereType<String>().toSet().toList()..sort(),
              selectedItem: _selectedState,
              popupProps: const PopupProps.menu(
                  showSearchBox: true,
                  searchFieldProps: TextFieldProps(
                      decoration: InputDecoration(hintText: "Search State..."))),
              dropdownDecoratorProps: const DropDownDecoratorProps(
                  dropdownSearchDecoration:
                  InputDecoration(labelText: "Select State *")),
              onChanged: (state) {
                setState(() {
                  _selectedState = state;
                  _selectedCategory = null;
                  _selectedStationMap = null;
                  final categories = state != null
                      ? allTarballStations
                      .where((s) => s['state_name'] == state)
                      .map((s) => s['category_name'] as String?)
                      .whereType<String>()
                      .toSet()
                      .toList()
                      : <String>[];
                  categories.sort();
                  _categoriesForState = categories;
                  _stationsForCategory = [];
                  _clearLocationFields();
                  _setDefaultDateTime();
                });
              },
              validator: (val) => val == null ? "State is required" : null,
            ),
            const SizedBox(height: 12),
            DropdownSearch<String>(
              items: _categoriesForState,
              selectedItem: _selectedCategory,
              enabled: _categoriesForState.isNotEmpty,
              popupProps: const PopupProps.menu(
                  showSearchBox: true,
                  searchFieldProps: TextFieldProps(
                      decoration:
                      InputDecoration(hintText: "Search Category..."))),
              dropdownDecoratorProps: const DropDownDecoratorProps(
                  dropdownSearchDecoration:
                  InputDecoration(labelText: "Select Category *")),
              onChanged: (category) {
                setState(() {
                  _selectedCategory = category;
                  _selectedStationMap = null;
                  final stations = category != null
                      ? allTarballStations
                      .where((s) =>
                  s['state_name'] == _selectedState &&
                      s['category_name'] == category)
                      .toList()
                      : <Map<String, dynamic>>[];
                  stations.sort((a, b) => (a['tbl_station_code'] ?? '')
                      .compareTo(b['tbl_station_code'] ?? ''));
                  _stationsForCategory = stations;
                  _stationIdController.clear();
                  _locationController.clear();
                  _latController.clear();
                  _longController.clear();
                });
              },
              validator: (val) =>
              val == null && _categoriesForState.isNotEmpty
                  ? "Category is required"
                  : null,
            ),
            const SizedBox(height: 12),
            DropdownSearch<Map<String, dynamic>>(
              items: _stationsForCategory,
              selectedItem: _selectedStationMap,
              enabled: _stationsForCategory.isNotEmpty,
              itemAsString: (station) =>
              "${station['tbl_station_code']} - ${station['tbl_station_name']}",
              popupProps: const PopupProps.menu(
                  showSearchBox: true,
                  searchFieldProps: TextFieldProps(
                      decoration:
                      InputDecoration(hintText: "Search Station..."))),
              dropdownDecoratorProps: const DropDownDecoratorProps(
                  dropdownSearchDecoration:
                  InputDecoration(labelText: "Select Station *")),
              onChanged: (station) => setState(() {
                _selectedStationMap = station;
                _stationIdController.text = station?['tbl_station_code'] ?? '';
                _locationController.text =
                    station?['tbl_station_name'] ?? '';
                _latController.text =
                    station?['tbl_latitude']?.toString() ?? '';
                _longController.text =
                    station?['tbl_longitude']?.toString() ?? '';
              }),
              validator: (val) =>
              val == null && _stationsForCategory.isNotEmpty
                  ? "Station is required"
                  : null,
            ),
            const SizedBox(height: 12),
            _buildTextFormField(
                controller: _eventDateTimeController,
                label: "Event Date/Time",
                readOnly: true),
          ],
        );
      default:
        return const SizedBox.shrink();
    }
  }

  Widget _buildSectionTitle(String title) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 12.0),
      child: Text(
        title,
        style: Theme.of(context)
            .textTheme
            .titleLarge
            ?.copyWith(fontWeight: FontWeight.bold),
      ),
    );
  }

  Widget _buildInSituSection() {
    final activeConnection = _getActiveConnectionDetails();
    final String? activeType = activeConnection?['type'] as String?;

    return Column(
      children: [
        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: 16),
        ..._npeParameters.map((param) {
          return _buildParameterListItem(
            icon: param['icon'] as IconData,
            label: param['label'] as String,
            unit: param['unit'] as String,
            controller: param['controller'] as TextEditingController,
          );
        }).toList(),
      ],
    );
  }

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

    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: isMissing ? Colors.grey : Theme.of(context).colorScheme.primary),
        ),
      ),
    );
  }

  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)
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                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),
                  )
                ],
              )
          ],
        ),
      ),
    );
  }

  List<Widget> _buildObservationsCheckboxes() {
    List<Widget> checkboxList = [];
    _observations.forEach((key, value) {
      checkboxList.add(
        CheckboxListTile(
          title: Text(key),
          value: value,
          onChanged: (newValue) {
            setState(() {
              _observations[key] = newValue!;
            });
          },
          controlAffinity: ListTileControlAffinity.leading,
          contentPadding: EdgeInsets.zero,
        ),
      );
    });
    if (_observations['Others'] == true) {
      checkboxList.add(
        Padding(
          padding: const EdgeInsets.only(left: 16.0, right: 8.0, bottom: 8.0),
          child: _buildTextFormField(
              controller: _othersObservationController,
              label: "Please specify"),
        ),
      );
    }
    return checkboxList;
  }

  Widget _buildImageAttachmentSection() {
    return Column(
      children: [
        _buildNPEImagePicker(
          title: 'Figure 1',
          imageFile: _image1,
          onClear: (_) => setState(() => _image1 = null),
          imageNumber: 1,
        ),
        _buildNPEImagePicker(
          title: 'Figure 2',
          imageFile: _image2,
          onClear: (_) => setState(() => _image2 = null),
          imageNumber: 2,
        ),
        _buildNPEImagePicker(
          title: 'Figure 3',
          imageFile: _image3,
          onClear: (_) => setState(() => _image3 = null),
          imageNumber: 3,
        ),
        _buildNPEImagePicker(
          title: 'Figure 4',
          imageFile: _image4,
          onClear: (_) => setState(() => _image4 = null),
          imageNumber: 4,
        ),
      ],
    );
  }

  Widget _buildNPEImagePicker({
    required String title,
    required File? imageFile,
    required Function(File?) onClear,
    required int imageNumber,
  }) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 8.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(title, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
          const SizedBox(height: 8),
          if (imageFile != null)
            Stack(
              alignment: Alignment.topRight,
              children: [
                ClipRRect(
                  borderRadius: BorderRadius.circular(8.0),
                  child: Image.file(
                    imageFile,
                    key: UniqueKey(),
                    height: 150,
                    width: double.infinity,
                    fit: BoxFit.cover,
                  ),
                ),
                Container(
                  margin: const EdgeInsets.all(4),
                  decoration: BoxDecoration(color: Colors.black.withOpacity(0.6), shape: BoxShape.circle),
                  child: IconButton(
                    visualDensity: VisualDensity.compact,
                    icon: const Icon(Icons.close, color: Colors.white, size: 20),
                    onPressed: () => onClear(null),
                  ),
                ),
              ],
            )
          else
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                ElevatedButton.icon(
                  onPressed: _isPickingImage ? null : () => _processAndSetImage(ImageSource.camera, imageNumber),
                  icon: const Icon(Icons.camera_alt),
                  label: const Text("Camera"),
                ),
                ElevatedButton.icon(
                  onPressed: _isPickingImage ? null : () => _processAndSetImage(ImageSource.gallery, imageNumber),
                  icon: const Icon(Icons.photo_library),
                  label: const Text("Gallery"),
                ),
              ],
            ),
        ],
      ),
    );
  }

  TextFormField _buildTextFormField({
    required TextEditingController controller,
    required String label,
    int? maxLines = 1,
    bool readOnly = false,
    VoidCallback? onTap,
    IconData? icon,
    TextInputType? keyboardType,
  }) {
    return TextFormField(
      controller: controller,
      decoration: InputDecoration(
        labelText: label,
        border: const OutlineInputBorder(),
        suffixIcon: icon != null ? Icon(icon) : null,
      ),
      maxLines: maxLines,
      readOnly: readOnly,
      onTap: onTap,
      keyboardType: keyboardType,
      validator: (value) {
        if (!label.contains('*')) return null;
        if (!readOnly && (value == null || value.trim().isEmpty)) {
          return 'This field cannot be empty';
        }
        return null;
      },
    );
  }
}