// lib\screens\marine\manual\widgets\in_situ_step_1_sampling_info.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:dropdown_search/dropdown_search.dart';
import 'package:intl/intl.dart';
import 'package:simple_barcode_scanner/simple_barcode_scanner.dart';

import '../../../../auth_provider.dart';
import '../../../../models/in_situ_sampling_data.dart';
import '../../../../services/marine_in_situ_sampling_service.dart';

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

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

  @override
  State<InSituStep1SamplingInfo> createState() => _InSituStep1SamplingInfoState();
}

class _InSituStep1SamplingInfoState extends State<InSituStep1SamplingInfo> {
  final _formKey = GlobalKey<FormState>();
  bool _isLoadingLocation = false;

  late final TextEditingController _firstSamplerController;
  late final TextEditingController _dateController;
  late final TextEditingController _timeController;
  late final TextEditingController _barcodeController;
  late final TextEditingController _stationLatController;
  late final TextEditingController _stationLonController;
  late final TextEditingController _currentLatController;
  late final TextEditingController _currentLonController;

  List<String> _statesList = [];
  List<String> _categoriesForState = [];
  List<Map<String, dynamic>> _stationsForCategory = [];
  final List<String> _samplingTypes = ['Schedule'];

  @override
  void initState() {
    super.initState();
    _initializeControllers();
    _initializeForm();
  }

  @override
  void dispose() {
    _firstSamplerController.dispose();
    _dateController.dispose();
    _timeController.dispose();
    _barcodeController.dispose();
    _stationLatController.dispose();
    _stationLonController.dispose();
    _currentLatController.dispose();
    _currentLonController.dispose();
    super.dispose();
  }

  void _initializeControllers() {
    _firstSamplerController = TextEditingController();
    _dateController = TextEditingController();
    _timeController = TextEditingController();
    _barcodeController = TextEditingController(text: widget.data.sampleIdCode);
    _stationLatController = TextEditingController(text: widget.data.stationLatitude);
    _stationLonController = TextEditingController(text: widget.data.stationLongitude);
    _currentLatController = TextEditingController(text: widget.data.currentLatitude);
    _currentLonController = TextEditingController(text: widget.data.currentLongitude);
  }

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

    widget.data.firstSamplerName = auth.profileData?['first_name'] ?? 'Current User';
    widget.data.firstSamplerUserId = auth.profileData?['user_id'];
    _firstSamplerController.text = widget.data.firstSamplerName!;

    final now = DateTime.now();
    if (widget.data.samplingDate == null || widget.data.samplingDate!.isEmpty) {
      widget.data.samplingDate = DateFormat('yyyy-MM-dd').format(now);
      widget.data.samplingTime = DateFormat('HH:mm:ss').format(now);
    }
    _dateController.text = widget.data.samplingDate!;
    _timeController.text = widget.data.samplingTime!;

    if (widget.data.samplingType == null) {
      widget.data.samplingType = 'Schedule';
    }

    final allStations = auth.manualStations ?? [];
    if (allStations.isNotEmpty) {
      final states = allStations.map((s) => s['state_name'] as String?).whereType<String>().toSet().toList();
      states.sort();

      if (widget.data.selectedStateName != null) {
        final categories = allStations
            .where((s) => s['state_name'] == widget.data.selectedStateName)
            .map((s) => s['category_name'] as String?)
            .whereType<String>()
            .toSet()
            .toList();
        categories.sort();
        _categoriesForState = categories;
      }
      if (widget.data.selectedCategoryName != null) {
        _stationsForCategory = allStations
            .where((s) =>
        s['state_name'] == widget.data.selectedStateName &&
            s['category_name'] == widget.data.selectedCategoryName)
            .toList()
          ..sort((a, b) => (a['man_station_code'] ?? '').compareTo(b['man_station_code'] ?? ''));
      }

      setState(() {
        _statesList = states;
      });
    }
  }

  Future<void> _getCurrentLocation() async {
    setState(() => _isLoadingLocation = true);
    final service = Provider.of<MarineInSituSamplingService>(context, listen: false);

    try {
      final position = await service.getCurrentLocation();
      // --- FIX: Check if mounted after async call ---
      if (!mounted) return;

      setState(() {
        widget.data.currentLatitude = position.latitude.toString();
        widget.data.currentLongitude = position.longitude.toString();
        _currentLatController.text = widget.data.currentLatitude!;
        _currentLonController.text = widget.data.currentLongitude!;
        _calculateDistance();
      });
    } catch (e) {
      if(mounted) {
        ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Failed to get location: $e')));
      }
    } finally {
      if (mounted) {
        setState(() => _isLoadingLocation = false);
      }
    }
  }

  void _calculateDistance() {
    final lat1Str = widget.data.stationLatitude;
    final lon1Str = widget.data.stationLongitude;
    final lat2Str = widget.data.currentLatitude;
    final lon2Str = widget.data.currentLongitude;

    if (lat1Str != null && lon1Str != null && lat2Str != null && lon2Str != null) {
      final service = Provider.of<MarineInSituSamplingService>(context, listen: false);
      final lat1 = double.tryParse(lat1Str);
      final lon1 = double.tryParse(lon1Str);
      final lat2 = double.tryParse(lat2Str);
      final lon2 = double.tryParse(lon2Str);

      if (lat1 != null && lon1 != null && lat2 != null && lon2 != null) {
        final distance = service.calculateDistance(lat1, lon1, lat2, lon2);
        setState(() {
          widget.data.distanceDifferenceInKm = distance;
        });
      }
    }
  }

  Future<void> _scanBarcode() async {
    final result = await Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => const SimpleBarcodeScannerPage()),
    );
    // --- FIX: Check if mounted after returning from a new route ---
    if (result is String && result != '-1' && mounted) {
      setState(() {
        widget.data.sampleIdCode = result;
        _barcodeController.text = result;
      });
    }
  }

  // --- START: New function to find and show nearby stations ---
  Future<void> _findAndShowNearbyStations() async {
    if (widget.data.currentLatitude == null || widget.data.currentLatitude!.isEmpty) {
      await _getCurrentLocation();
      // --- FIX: Ensure we are still active after location fetch ---
      if (!mounted || widget.data.currentLatitude == null || widget.data.currentLatitude!.isEmpty) {
        return;
      }
    }

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

    final currentLat = double.parse(widget.data.currentLatitude!);
    final currentLon = double.parse(widget.data.currentLongitude!);
    final allStations = auth.manualStations ?? [];
    final List<Map<String, dynamic>> nearbyStations = [];

    for (var station in allStations) {
      final stationLat = station['man_latitude'];
      final stationLon = station['man_longitude'];

      if (stationLat is num && stationLon is num) {
        final distance = service.calculateDistance(currentLat, currentLon, stationLat.toDouble(), stationLon.toDouble());
        if (distance <= 5.0) { // 5km radius
          nearbyStations.add({'station': station, 'distance': distance});
        }
      }
    }

    nearbyStations.sort((a, b) => a['distance'].compareTo(b['distance']));

    if (!mounted) return;

    final selectedStation = await showDialog<Map<String, dynamic>>(
      context: context,
      builder: (context) => _NearbyStationsDialog(nearbyStations: nearbyStations),
    );

    // --- FIX: Verify mounted state after dialog closure ---
    if (selectedStation != null && mounted) {
      _updateFormWithSelectedStation(selectedStation);
    }
  }
  // --- END: New function ---

  // --- START: New helper to update form after selection ---
  void _updateFormWithSelectedStation(Map<String, dynamic> station) {
    final allStations = Provider.of<AuthProvider>(context, listen: false).manualStations ?? [];
    setState(() {
      // Update State
      widget.data.selectedStateName = station['state_name'];

      // Update Category List based on new State
      final categories = allStations
          .where((s) => s['state_name'] == widget.data.selectedStateName)
          .map((s) => s['category_name'] as String?)
          .whereType<String>()
          .toSet()
          .toList();
      categories.sort();
      _categoriesForState = categories;

      // Update Category
      widget.data.selectedCategoryName = station['category_name'];

      // Update Station List based on new State and Category
      _stationsForCategory = allStations
          .where((s) =>
      s['state_name'] == widget.data.selectedStateName &&
          s['category_name'] == widget.data.selectedCategoryName)
          .toList()
        ..sort((a, b) => (a['man_station_code'] ?? '').compareTo(b['man_station_code'] ?? ''));

      // Update Selected Station and its coordinates
      widget.data.selectedStation = station;
      widget.data.stationLatitude = station['man_latitude']?.toString();
      widget.data.stationLongitude = station['man_longitude']?.toString();
      _stationLatController.text = widget.data.stationLatitude ?? '';
      _stationLonController.text = widget.data.stationLongitude ?? '';

      // --- START DEBUG ---
      debugPrint("--- Nearby Station Selected in Step 1 ---");
      debugPrint("Selected Station Data: $station");
      debugPrint("Selected Station ID (man_station_id): ${station['man_station_id']}");
      // --- END DEBUG ---

      // Recalculate distance
      _calculateDistance();
    });
  }
  // --- END: New helper ---

  void _goToNextStep() {
    if (_formKey.currentState!.validate()) {
      _formKey.currentState!.save();

      final distanceInMeters = (widget.data.distanceDifferenceInKm ?? 0) * 1000;

      if (distanceInMeters > 50) {
        _showDistanceRemarkDialog();
      } else {
        widget.data.distanceDifferenceRemarks = null;
        widget.onNext();
      }
    }
  }

  Future<void> _showDistanceRemarkDialog() async {
    final remarkController = TextEditingController(text: widget.data.distanceDifferenceRemarks);
    final dialogFormKey = GlobalKey<FormState>();

    return showDialog<void>(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Distance Warning'),
          content: SingleChildScrollView(
            child: Form(
              key: dialogFormKey,
              child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const Text('Your current location is more than 50m away from the station.'),
                  const SizedBox(height: 16),
                  TextFormField(
                    controller: remarkController,
                    decoration: const InputDecoration(
                      labelText: 'Remarks *',
                      hintText: 'Please provide a reason...',
                      border: OutlineInputBorder(),
                    ),
                    validator: (value) {
                      if (value == null || value.trim().isEmpty) {
                        return 'Remarks are required to continue.';
                      }
                      return null;
                    },
                    maxLines: 3,
                  ),
                ],
              ),
            ),
          ),
          actions: <Widget>[
            TextButton(
              child: const Text('Cancel'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
            FilledButton(
              child: const Text('Confirm'),
              onPressed: () {
                if (dialogFormKey.currentState!.validate()) {
                  // --- FIX: Ensure mounted check inside dialog action ---
                  if (mounted) {
                    setState(() {
                      widget.data.distanceDifferenceRemarks = remarkController.text;
                    });
                    Navigator.of(context).pop();
                    widget.onNext();
                  }
                }
              },
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    final auth = Provider.of<AuthProvider>(context, listen: false);
    final allStations = auth.manualStations ?? [];
    final allUsers = auth.allUsers ?? [];
    final secondSamplersList = allUsers.where((user) => user['user_id'] != auth.profileData?['user_id']).toList()
      ..sort((a, b) => (a['first_name'] ?? '').compareTo(b['first_name'] ?? ''));

    return Form(
      key: _formKey,
      child: ListView(
        padding: const EdgeInsets.all(24.0),
        children: [
          Text("Sampling Information", style: Theme.of(context).textTheme.headlineSmall),
          const SizedBox(height: 24),
          TextFormField(controller: _firstSamplerController, readOnly: true, decoration: const InputDecoration(labelText: '1st Sampler')),
          const SizedBox(height: 16),
          DropdownSearch<Map<String, dynamic>>(
            items: secondSamplersList,
            selectedItem: widget.data.secondSampler,
            itemAsString: (sampler) => "${sampler['first_name']} ${sampler['last_name']}",
            onChanged: (sampler) => widget.data.secondSampler = sampler,
            popupProps: const PopupProps.menu(showSearchBox: true, searchFieldProps: TextFieldProps(decoration: InputDecoration(hintText: "Search Sampler..."))),
            dropdownDecoratorProps: const DropDownDecoratorProps(dropdownSearchDecoration: InputDecoration(labelText: '2nd Sampler (Optional)')),
          ),
          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'))),
            ],
          ),
          const SizedBox(height: 16),
          DropdownButtonFormField<String>(
            value: widget.data.samplingType,
            items: _samplingTypes.map((type) => DropdownMenuItem(value: type, child: Text(type))).toList(),
            onChanged: (value) => setState(() => widget.data.samplingType = value),
            decoration: const InputDecoration(labelText: 'Sampling Type *'),
            validator: (value) => value == null ? 'Please select a type' : null,
          ),
          const SizedBox(height: 24),

          Text("Station Selection", style: Theme.of(context).textTheme.titleLarge),
          const SizedBox(height: 16),
          DropdownSearch<String>(
            items: _statesList,
            selectedItem: widget.data.selectedStateName,
            popupProps: const PopupProps.menu(showSearchBox: true, searchFieldProps: TextFieldProps(decoration: InputDecoration(hintText: "Search State..."))),
            dropdownDecoratorProps: const DropDownDecoratorProps(dropdownSearchDecoration: InputDecoration(labelText: "Select State *")),
            onChanged: (state) {
              setState(() {
                widget.data.selectedStateName = state;
                widget.data.selectedCategoryName = null;
                widget.data.selectedStation = null;
                _stationLatController.clear();
                _stationLonController.clear();
                widget.data.distanceDifferenceInKm = null;

                final categories = state != null
                    ? allStations
                    .where((s) => s['state_name'] == state)
                    .map((s) => s['category_name'] as String?)
                    .whereType<String>()
                    .toSet()
                    .toList()
                    : <String>[];
                categories.sort();
                _categoriesForState = categories;

                _stationsForCategory = [];
              });
            },
            validator: (val) => val == null ? "State is required" : null,
          ),
          const SizedBox(height: 16),
          DropdownSearch<String>(
            items: _categoriesForState,
            selectedItem: widget.data.selectedCategoryName,
            enabled: widget.data.selectedStateName != null,
            popupProps: const PopupProps.menu(showSearchBox: true, searchFieldProps: TextFieldProps(decoration: InputDecoration(hintText: "Search Category..."))),
            dropdownDecoratorProps: const DropDownDecoratorProps(dropdownSearchDecoration: InputDecoration(labelText: "Select Category *")),
            onChanged: (category) {
              setState(() {
                widget.data.selectedCategoryName = category;
                widget.data.selectedStation = null;
                _stationLatController.clear();
                _stationLonController.clear();
                widget.data.distanceDifferenceInKm = null;
                _stationsForCategory = category != null
                    ? (allStations
                    .where((s) => s['state_name'] == widget.data.selectedStateName && s['category_name'] == category)
                    .toList()
                  ..sort((a, b) => (a['man_station_code'] ?? '').compareTo(b['man_station_code'] ?? '')))
                    : [];
              });
            },
            validator: (val) => widget.data.selectedStateName != null && val == null ? "Category is required" : null,
          ),
          const SizedBox(height: 16),
          DropdownSearch<Map<String, dynamic>>(
            items: _stationsForCategory,
            selectedItem: widget.data.selectedStation,
            enabled: widget.data.selectedCategoryName != null,
            itemAsString: (station) => "${station['man_station_code']} - ${station['man_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(() {
              widget.data.selectedStation = station;
              widget.data.stationLatitude = station?['man_latitude']?.toString();
              widget.data.stationLongitude = station?['man_longitude']?.toString();
              _stationLatController.text = widget.data.stationLatitude ?? '';
              _stationLonController.text = widget.data.stationLongitude ?? '';

              // --- START DEBUG ---
              if (station != null) {
                debugPrint("--- Station Selected in Step 1 ---");
                debugPrint("Selected Station Data: $station");
                debugPrint("Selected Station ID (man_station_id): ${station['man_station_id']}");
              } else {
                debugPrint("--- Station Deselected in Step 1 ---");
              }
              // --- END DEBUG ---

              _calculateDistance();
            }),
            validator: (val) => widget.data.selectedCategoryName != null && val == null ? "Station is required" : null,
          ),
          const SizedBox(height: 16),
          TextFormField(controller: _stationLatController, readOnly: true, decoration: const InputDecoration(labelText: 'Station Latitude')),
          const SizedBox(height: 16),
          TextFormField(controller: _stationLonController, readOnly: true, decoration: const InputDecoration(labelText: 'Station Longitude')),

          // --- START: Added Nearby Station Button ---
          const SizedBox(height: 16),
          ElevatedButton.icon(
            icon: const Icon(Icons.explore_outlined),
            label: const Text("NEARBY STATION"),
            onPressed: _isLoadingLocation ? null : _findAndShowNearbyStations,
            style: ElevatedButton.styleFrom(
              padding: const EdgeInsets.symmetric(vertical: 12),
            ),
          ),
          // --- END: Added Nearby Station Button ---

          const SizedBox(height: 24),
          Text("Location Verification", style: Theme.of(context).textTheme.titleLarge),
          const SizedBox(height: 16),
          TextFormField(controller: _currentLatController, readOnly: true, decoration: const InputDecoration(labelText: 'Current Latitude')),
          const SizedBox(height: 16),
          TextFormField(controller: _currentLonController, readOnly: true, decoration: const InputDecoration(labelText: 'Current Longitude')),
          if (widget.data.distanceDifferenceInKm != null)
            Padding(
              padding: const EdgeInsets.only(top: 16.0),
              child: Container(
                padding: const EdgeInsets.all(12),
                decoration: BoxDecoration(
                  color: ((widget.data.distanceDifferenceInKm ?? 0) * 1000) > 50 ? Colors.red.withOpacity(0.1) : Colors.green.withOpacity(0.1),
                  borderRadius: BorderRadius.circular(8),
                  border: Border.all(color: ((widget.data.distanceDifferenceInKm ?? 0) * 1000) > 50 ? Colors.red : Colors.green),
                ),
                child: RichText(
                  textAlign: TextAlign.center,
                  text: TextSpan(
                    style: Theme.of(context).textTheme.bodyLarge,
                    children: <TextSpan>[
                      const TextSpan(text: 'Distance from Station: '),
                      // --- START MODIFICATION ---
                      TextSpan(
                        text: '${(widget.data.distanceDifferenceInKm! * 1000).toStringAsFixed(0)} meters (${widget.data.distanceDifferenceInKm!.toStringAsFixed(3)} KM)',
                        style: TextStyle(
                            fontWeight: FontWeight.bold,
                            color: ((widget.data.distanceDifferenceInKm ?? 0) * 1000) > 50 ? Colors.red : Colors.green
                        ),
                      ),
                      // --- END MODIFICATION ---
                    ],
                  ),
                ),
              ),
            ),
          const SizedBox(height: 16),
          OutlinedButton.icon(
            onPressed: _isLoadingLocation ? null : _getCurrentLocation,
            icon: _isLoadingLocation ? const SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2)) : const Icon(Icons.location_searching),
            label: const Text("Get Current Location"),
          ),
          const SizedBox(height: 16),

          TextFormField(
            controller: _barcodeController,
            decoration: InputDecoration(
              labelText: 'Sample ID Code *',
              suffixIcon: IconButton(
                icon: const Icon(Icons.qr_code_scanner),
                onPressed: _scanBarcode,
              ),
            ),
            validator: (val) => val == null || val.isEmpty ? "Sample ID is required" : null,
            onSaved: (val) => widget.data.sampleIdCode = val,
            onChanged: (val) => widget.data.sampleIdCode = val,
          ),
          const SizedBox(height: 32),
          ElevatedButton(
            onPressed: _goToNextStep,
            style: ElevatedButton.styleFrom(padding: const EdgeInsets.symmetric(vertical: 16)),
            child: const Text('Next'),
          ),
        ],
      ),
    );
  }
}

// --- START: New Dialog Widget for Nearby Stations ---
class _NearbyStationsDialog extends StatelessWidget {
  final List<Map<String, dynamic>> nearbyStations;

  const _NearbyStationsDialog({required this.nearbyStations});

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: const Text('Nearby Stations (within 5km)'),
      content: SizedBox(
        width: double.maxFinite,
        child: nearbyStations.isEmpty
            ? const Center(child: Text('No stations found.'))
            : ListView.builder(
          shrinkWrap: true,
          itemCount: nearbyStations.length,
          itemBuilder: (context, index) {
            final item = nearbyStations[index];
            final station = item['station'] as Map<String, dynamic>;
            final distanceInMeters = (item['distance'] as double) * 1000;

            return Card(
              child: ListTile(
                title: Text("${station['man_station_code'] ?? 'N/A'}"),
                subtitle: Text("${station['man_station_name'] ?? 'N/A'}"),
                trailing: Text("${distanceInMeters.toStringAsFixed(0)} m"),
                onTap: () {
                  Navigator.of(context).pop(station);
                },
              ),
            );
          },
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.of(context).pop(),
          child: const Text('Cancel'),
        ),
      ],
    );
  }
}