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

import 'package:environment_monitoring_app/auth_provider.dart';
import 'package:environment_monitoring_app/models/tarball_data.dart';
import 'package:environment_monitoring_app/screens/marine/manual/tarball_sampling_step2.dart';

class TarballSamplingStep1 extends StatefulWidget {
  const TarballSamplingStep1({super.key});

  @override
  State<TarballSamplingStep1> createState() => _TarballSamplingStep1State();
}

class _TarballSamplingStep1State extends State<TarballSamplingStep1> {
  final _formKey = GlobalKey<FormState>();
  // MODIFIED: A single data object is managed for the entire form.
  final _data = TarballSamplingData();
  bool _isLoading = false;

  // --- Controllers for UI fields ---
  final TextEditingController _firstSamplerController = TextEditingController();
  final TextEditingController _dateController = TextEditingController();
  final TextEditingController _timeController = TextEditingController();
  final TextEditingController _stationLatController = TextEditingController();
  final TextEditingController _stationLonController = TextEditingController();
  final TextEditingController _currentLatController = TextEditingController();
  final TextEditingController _currentLonController = TextEditingController();

  // --- State for Dropdowns ---
  List<String> _statesList = [];
  List<String> _categoriesForState = [];
  List<Map<String, dynamic>> _stationsForCategory = [];

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

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

  void _initializeForm() {
    final auth = Provider.of<AuthProvider>(context, listen: false);
    _data.firstSampler = auth.profileData?['first_name'] ?? 'Current User';
    _data.firstSamplerUserId = auth.profileData?['user_id'];
    _firstSamplerController.text = _data.firstSampler!;

    final now = DateTime.now();
    _data.samplingDate = DateFormat('yyyy-MM-dd').format(now);
    _data.samplingTime = DateFormat('HH:mm:ss').format(now);
    _dateController.text = _data.samplingDate!;
    _timeController.text = _data.samplingTime!;

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

  Future<void> _getCurrentLocation() async {
    bool serviceEnabled;
    LocationPermission permission;

    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      _showSnackBar('Location services are disabled. Please enable them.');
      return;
    }

    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        _showSnackBar('Location permissions are denied.');
        return;
      }
    }

    if (permission == LocationPermission.deniedForever) {
      _showSnackBar('Location permissions are permanently denied. We cannot request permissions.');
      return;
    }

    setState(() => _isLoading = true);

    try {
      Position? position = await Geolocator.getLastKnownPosition();
      position ??= await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);

      if (mounted) {
        setState(() {
          _data.currentLatitude = position!.latitude.toString();
          _data.currentLongitude = position.longitude.toString();
          _currentLatController.text = _data.currentLatitude!;
          _currentLonController.text = _data.currentLongitude!;
          _calculateDistance();
        });
      }
    } catch (e) {
      _showSnackBar('Failed to get location: $e');
    } finally {
      if (mounted) {
        setState(() => _isLoading = false);
      }
    }
  }

  void _calculateDistance() {
    if (_stationLatController.text.isNotEmpty && _currentLatController.text.isNotEmpty) {
      final double lat1 = double.parse(_stationLatController.text);
      final double lon1 = double.parse(_stationLonController.text);
      final double lat2 = double.parse(_currentLatController.text);
      final double lon2 = double.parse(_currentLonController.text);

      double distanceInMeters = Geolocator.distanceBetween(lat1, lon1, lat2, lon2);
      setState(() {
        _data.distanceDifference = distanceInMeters / 1000; // Convert to km
      });
    }
  }

  // --- START: New function to find and show nearby stations ---
  Future<void> _findAndShowNearbyStations() async {
    if (_data.currentLatitude == null || _data.currentLatitude!.isEmpty) {
      await _getCurrentLocation();
      if (!mounted || _data.currentLatitude == null || _data.currentLatitude!.isEmpty) {
        return;
      }
    }

    final auth = Provider.of<AuthProvider>(context, listen: false);
    final allStations = auth.tarballStations ?? [];
    if (allStations.isEmpty) {
      _showSnackBar("Station list is not available.");
      return;
    }

    final currentLat = double.parse(_data.currentLatitude!);
    final currentLon = double.parse(_data.currentLongitude!);
    final List<Map<String, dynamic>> nearbyStations = [];

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

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

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

    if (selectedStation != null) {
      _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).tarballStations ?? [];
    setState(() {
      // Update State
      _data.selectedStateName = station['state_name'];

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

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

      // Update Station List based on new State and Category
      _stationsForCategory = allStations
          .where((s) =>
      s['state_name'] == _data.selectedStateName &&
          s['category_name'] == _data.selectedCategoryName)
          .toList();

      // Update Selected Station and its coordinates
      _data.selectedStation = station;
      _data.stationLatitude = station['tbl_latitude']?.toString();
      _data.stationLongitude = station['tbl_longitude']?.toString();
      _stationLatController.text = _data.stationLatitude ?? '';
      _stationLonController.text = _data.stationLongitude ?? '';

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

  // MODIFIED: This function now validates distance and shows a dialog if needed
  void _goToNextStep() {
    if (_formKey.currentState!.validate()) {
      _formKey.currentState!.save();
      final distanceInMeters = (_data.distanceDifference ?? 0) * 1000;

      // START MODIFICATION: Distance reduced to 50m
      if (distanceInMeters > 50) {
        // END MODIFICATION
        _showDistanceRemarkDialog();
      } else {
        _data.distanceDifferenceRemarks = null; // Clear old remarks if within range
        Navigator.push(
          context,
          MaterialPageRoute(builder: (context) => TarballSamplingStep2(data: _data)),
        );
      }
    }
  }

  // NEW: This function displays the mandatory remarks dialog
  Future<void> _showDistanceRemarkDialog() async {
    final remarkController = TextEditingController(text: _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: [
                  // START MODIFICATION: Text updated for 50m
                  const Text('Your current location is more than 50m away from the station.'),
                  // END MODIFICATION
                  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()) {
                  _data.distanceDifferenceRemarks = remarkController.text;
                  Navigator.of(context).pop();
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => TarballSamplingStep2(data: _data)),
                  );
                }
              },
            ),
          ],
        );
      },
    );
  }

  void _showSnackBar(String message) {
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(message)));
    }
  }

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

    return Scaffold(
      appBar: AppBar(title: const Text("Tarball Sampling (1/3)")),
      body: 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>>(
              key: ValueKey(allUsers.length),
              items: secondSamplersList,
              selectedItem: _data.secondSampler, // Bind to the data model
              itemAsString: (sampler) => "${sampler['first_name']} ${sampler['last_name']}",
              onChanged: (sampler) => setState(() => _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),
            DropdownSearch<String>(
              items: _statesList,
              selectedItem: _data.selectedStateName, // Bind to the data model
              popupProps: const PopupProps.menu(showSearchBox: true, searchFieldProps: TextFieldProps(decoration: InputDecoration(hintText: "Search State..."))),
              dropdownDecoratorProps: const DropDownDecoratorProps(dropdownSearchDecoration: InputDecoration(labelText: "Select State *")),
              onChanged: (state) {
                setState(() {
                  _data.selectedStateName = state;
                  _data.selectedCategoryName = null;
                  _data.selectedStation = null;
                  _stationLatController.clear();
                  _stationLonController.clear();
                  _data.distanceDifference = null;

                  if (state != null) {
                    _categoriesForState = allStations.where((s) => s['state_name'] == state).map((s) => s['category_name'] as String?).whereType<String>().toSet().toList();
                    _categoriesForState.sort();
                  } else {
                    _categoriesForState = [];
                  }
                  _stationsForCategory = [];
                });
              },
              validator: (val) => val == null ? "State is required" : null,
            ),
            const SizedBox(height: 16),
            DropdownSearch<String>(
              items: _categoriesForState,
              selectedItem: _data.selectedCategoryName, // Bind to the data model
              enabled: _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(() {
                  _data.selectedCategoryName = category;
                  _data.selectedStation = null;
                  _stationLatController.clear();
                  _stationLonController.clear();
                  _data.distanceDifference = null;

                  if (category != null) {
                    _stationsForCategory = allStations.where((s) => s['state_name'] == _data.selectedStateName && s['category_name'] == category).toList();
                  } else {
                    _stationsForCategory = [];
                  }
                });
              },
              validator: (val) => _data.selectedStateName != null && val == null ? "Category is required" : null,
            ),
            const SizedBox(height: 16),
            DropdownSearch<Map<String, dynamic>>(
              items: _stationsForCategory,
              selectedItem: _data.selectedStation, // Bind to the data model
              enabled: _data.selectedCategoryName != null,
              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(() {
                _data.selectedStation = station;
                _data.stationLatitude = station?['tbl_latitude']?.toString();
                _data.stationLongitude = station?['tbl_longitude']?.toString();
                _stationLatController.text = _data.stationLatitude ?? '';
                _stationLonController.text = _data.stationLongitude ?? '';
                _calculateDistance();
              }),
              validator: (val) => _data.selectedCategoryName != null && val == null ? "Station is required" : null,
              onSaved: (station) => _data.selectedStation = station,
            ),
            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: _isLoading ? 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 (_data.distanceDifference != null)
              Padding(
                padding: const EdgeInsets.only(top: 16.0),
                // MODIFIED: This UI now better reflects the warning/ok status
                child: Container(
                  padding: const EdgeInsets.all(12),
                  // START MODIFICATION: Distance reduced to 50m
                  decoration: BoxDecoration(
                    color: ((_data.distanceDifference ?? 0) * 1000) > 50 ? Colors.red.withOpacity(0.1) : Colors.green.withOpacity(0.1),
                    borderRadius: BorderRadius.circular(8),
                    border: Border.all(color: ((_data.distanceDifference ?? 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: '),
                        TextSpan(
                          // --- THIS IS THE MODIFIED LINE ---
                          text: '${(_data.distanceDifference! * 1000).toStringAsFixed(0)} meters (${_data.distanceDifference!.toStringAsFixed(3)}km)',
                          // --- END OF MODIFIED LINE ---
                          style: TextStyle(
                              fontWeight: FontWeight.bold,
                              color: ((_data.distanceDifference ?? 0) * 1000) > 50 ? Colors.red : Colors.green),
                        ),
                      ],
                    ),
                  ),
                  // END MODIFICATION
                ),
              ),
            const SizedBox(height: 16),
            OutlinedButton.icon(
              onPressed: _isLoading ? null : _getCurrentLocation,
              icon: _isLoading ? const SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2)) : const Icon(Icons.location_searching),
              label: const Text("Get Current Location"),
            ),
            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;

            return Card(
              child: ListTile(
                title: Text("${station['tbl_station_code'] ?? 'N/A'}"),
                subtitle: Text("${station['tbl_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'),
        ),
      ],
    );
  }
}
// --- END: New Dialog Widget ---