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

import '../../../auth_provider.dart';
import '../../../services/api_service.dart';
// --- FIX: Import the new dedicated service ---
import '../../../services/marine_api_service.dart';

// --- FIX: Define image key lists ---
const List<String> _inSituImageKeys = [
  'man_left_side_land_view_path',
  'man_right_side_land_view_path',
  'man_filling_water_into_sample_bottle_path',
  'man_seawater_in_clear_glass_bottle_path',
  'man_examine_preservative_ph_paper_path',
  'man_optional_photo_01_path',
  'man_optional_photo_02_path',
  'man_optional_photo_03_path',
  'man_optional_photo_04_path',
];


// --- START: MODIFIED TO FIX 0 IMAGE URLS ---
// These keys are now an exact match for the keys in your server log
const List<String> _tarballImageKeys = [
  'left_side_coastal_view',
  'right_side_coastal_view',
  'drawing_vertical_lines',
  'drawing_horizontal_line',
  'optional_photo_01',
  'optional_photo_02',
  'optional_photo_03',
  'optional_photo_04',
];
// --- END: MODIFIED TO FIX 0 IMAGE URLS ---


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

  @override
  State<MarineImageRequestScreen> createState() => _MarineImageRequestScreenState();
}

class _MarineImageRequestScreenState extends State<MarineImageRequestScreen> {
  final _formKey = GlobalKey<FormState>();
  final _dateController = TextEditingController();

  // --- FIX: Default to a specific type, not 'All' ---
  String? _selectedSamplingType = 'In-Situ Sampling';
  final List<String> _samplingTypes = ['In-Situ Sampling', 'Tarball Sampling', 'All Manual Sampling'];

  String? _selectedStateName;
  String? _selectedCategoryName;
  Map<String, dynamic>? _selectedStation;
  DateTime? _selectedDate;

  List<String> _statesList = [];
  List<String> _categoriesForState = [];
  List<Map<String, dynamic>> _stationsForCategory = [];

  bool _isLoading = false;
  List<String> _imageUrls = [];
  final Set<String> _selectedImageUrls = {};

  @override
  void initState() {
    super.initState();
    // --- FIX: Use addPostFrameCallback to ensure provider is ready ---
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if(mounted) {
        _initializeStationFilters();
      }
    });
  }

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

  // --- FIX: New function to get the correct station list from AuthProvider ---
  List<Map<String, dynamic>> _getStationsForType(AuthProvider auth) {
    switch (_selectedSamplingType) {
      case 'In-Situ Sampling':
        return auth.manualStations ?? [];
      case 'Tarball Sampling':
        return auth.tarballStations ?? [];
      case 'All Manual Sampling':
      // 'All' is complex. Defaulting to manual stations as a fallback.
        return auth.manualStations ?? [];
      default:
        return [];
    }
  }

  // --- FIX: New function to get the correct station ID key ---
  String _getStationIdKey() {
    switch (_selectedSamplingType) {
      case 'In-Situ Sampling':
        return 'station_id'; // from manualStations
      case 'Tarball Sampling':
        return 'station_id'; // from tarballStations (assuming 'station_id')
      default:
        return 'station_id';
    }
  }

  // --- FIX: New function to get the correct station code key ---
  String _getStationCodeKey() {
    switch (_selectedSamplingType) {
      case 'In-Situ Sampling':
        return 'man_station_code';
      case 'Tarball Sampling':
        return 'tbl_station_code'; // Please verify this key
      default:
        return 'man_station_code';
    }
  }

  // --- FIX: New function to get the correct station name key ---
  String _getStationNameKey() {
    switch (_selectedSamplingType) {
      case 'In-Situ Sampling':
        return 'man_station_name';
      case 'Tarball Sampling':
        return 'tbl_station_name'; // Please verify this key
      default:
        return 'man_station_name';
    }
  }

  // --- FIX: Function modified to be dynamic ---
  void _initializeStationFilters() {
    final auth = Provider.of<AuthProvider>(context, listen: false);
    // --- FIX: Use helper to get dynamic station list ---
    final allStations = _getStationsForType(auth);

    if (allStations.isNotEmpty) {
      // Assuming 'state_name' exists on all station types
      final states = allStations.map((s) => s['state_name'] as String?).whereType<String>().toSet().toList();
      states.sort();
      setState(() {
        _statesList = states;
        // --- FIX: Reset dependent fields on change ---
        _selectedStateName = null;
        _selectedCategoryName = null;
        _selectedStation = null;
        _categoriesForState = [];
        _stationsForCategory = [];
      });
    } else {
      // --- FIX: Handle empty list ---
      setState(() {
        _statesList = [];
        _selectedStateName = null;
        _selectedCategoryName = null;
        _selectedStation = null;
        _categoriesForState = [];
        _stationsForCategory = [];
      });
    }
  }

  Future<void> _selectDate() async {
    final picked = await showDatePicker(
      context: context,
      initialDate: _selectedDate ?? DateTime.now(),
      firstDate: DateTime(2020),
      lastDate: DateTime.now(),
    );

    if (picked != null && picked != _selectedDate) {
      setState(() {
        _selectedDate = picked;
        _dateController.text = DateFormat('yyyy-MM-dd').format(_selectedDate!);
      });
    }
  }

  Future<void> _searchImages() async {
    if (_formKey.currentState!.validate()) {
      setState(() {
        _isLoading = true;
        _imageUrls = [];
        _selectedImageUrls.clear();
      });

      debugPrint("[Image Request] Search button pressed. Starting validation.");
      debugPrint("[Image Request] Selected Station: ${_selectedStation}");
      debugPrint("[Image Request] Date: ${_selectedDate}");
      debugPrint("[Image Request] Sampling Type: $_selectedSamplingType");

      if (_selectedStation == null || _selectedDate == null || _selectedSamplingType == null) {
        debugPrint("[Image Request] ERROR: Station, date, or sampling type is missing. Aborting search.");
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text('Error: Station, date, or sampling type is missing.'),
              backgroundColor: Colors.red,
            ),
          );
          setState(() => _isLoading = false);
        }
        return;
      }

      // --- FIX: Get the correct station ID key ---
      final stationIdKey = _getStationIdKey();
      final stationId = _selectedStation![stationIdKey];

      if (stationId == null) {
        debugPrint("[Image Request] ERROR: Station ID is null.");
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text('Error: Invalid station data.'),
              backgroundColor: Colors.red,
            ),
          );
          setState(() => _isLoading = false);
        }
        return;
      }

      final apiService = Provider.of<ApiService>(context, listen: false);

      try {
        debugPrint("[Image Request] All checks passed. Calling API with Station ID: $stationId, Type: $_selectedSamplingType");

        // This call is correct, as apiService.marine holds the MarineApiService
        final result = await apiService.marine.getManualSamplingImages(
          stationId: stationId as int, // Ensure it's passed as int
          samplingDate: _selectedDate!,
          samplingType: _selectedSamplingType!, // This is now used by the API service
        );

        if (mounted && result['success'] == true) {
          // --- FIX: The data key from your new log is just 'data' ---
          final List<Map<String, dynamic>> records = List<Map<String, dynamic>>.from(result['data'] ?? []);
          final List<String> fetchedUrls = [];

          // --- FIX: Determine which set of keys to use ---
          List<String> imageKeys;
          switch (_selectedSamplingType) {
            case 'In-Situ Sampling':
              imageKeys = _inSituImageKeys;
              break;
            case 'Tarball Sampling':
              imageKeys = _tarballImageKeys; // Now uses the corrected list
              break;
            case 'All Manual Sampling':
            default:
            // Default to In-Situ keys as a fallback
              imageKeys = _inSituImageKeys;
              break;
          }
          // If 'All Manual Sampling' is selected, you could merge keys:
          // imageKeys = [..._inSituImageKeys, ..._tarballImageKeys];

          for (final record in records) {
            for (final key in imageKeys) {
              if (record[key] != null && (record[key] as String).isNotEmpty) {
                final String imagePathFromServer = record[key];

                // --- FIX: Make URL construction robust ---
                final fullUrl = imagePathFromServer.startsWith('http')
                    ? imagePathFromServer
                    : ApiService.imageBaseUrl + imagePathFromServer;

                fetchedUrls.add(fullUrl);
                debugPrint("[Image Request] Found and constructed URL: $fullUrl");
              }
            }
          }

          setState(() {
            // --- FIX: Use toSet() to remove potential duplicates ---
            _imageUrls = fetchedUrls.toSet().toList();
          });
          debugPrint("[Image Request] Successfully processed and constructed ${_imageUrls.length} image URLs.");
        } else if (mounted) {
          debugPrint("[Image Request] API call failed. Message: ${result['message']}");
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text(result['message'] ?? 'Failed to fetch images.')),
          );
        }
      } catch (e) {
        debugPrint("[Image Request] An exception occurred during API call: $e");
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text('An error occurred: $e')),
          );
        }
      } finally {
        if (mounted) {
          setState(() {
            _isLoading = false;
          });
        }
      }
    } else {
      debugPrint("[Image Request] Form validation failed.");
    }
  }

  Future<void> _showEmailDialog() async {
    final emailController = TextEditingController();
    final dialogFormKey = GlobalKey<FormState>();

    return showDialog<void>(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return StatefulBuilder(
          builder: (context, setDialogState) {
            bool isSending = false;

            return AlertDialog(
              title: const Text('Send Images via Email'),
              content: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  if (isSending)
                    const Padding(
                      padding: EdgeInsets.all(16.0),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          CircularProgressIndicator(),
                          SizedBox(width: 24),
                          Text("Sending..."),
                        ],
                      ),
                    )
                  else
                    Form(
                      key: dialogFormKey,
                      child: TextFormField(
                        controller: emailController,
                        keyboardType: TextInputType.emailAddress,
                        decoration: const InputDecoration(
                          labelText: 'Recipient Email Address',
                          hintText: 'user@example.com',
                        ),
                        validator: (value) {
                          if (value == null || value.isEmpty || !RegExp(r'\S+@\S+\.\S+').hasMatch(value)) {
                            return 'Please enter a valid email address.';
                          }
                          return null;
                        },
                      ),
                    ),
                ],
              ),
              actions: <Widget>[
                TextButton(
                  onPressed: isSending ? null : () => Navigator.of(context).pop(),
                  child: const Text('Cancel'),
                ),
                FilledButton(
                  onPressed: isSending ? null : () async {
                    if (dialogFormKey.currentState!.validate()) {
                      setDialogState(() => isSending = true);
                      await _sendEmailRequestToServer(emailController.text);
                      if (mounted) Navigator.of(context).pop();
                    }
                  },
                  child: const Text('Send'),
                ),
              ],
            );
          },
        );
      },
    );
  }

  Future<void> _sendEmailRequestToServer(String toEmail) async {
    final apiService = Provider.of<ApiService>(context, listen: false);

    try {
      debugPrint("[Image Request] Sending email request to server for recipient: $toEmail");

      // --- FIX: Use dynamic keys ---
      final stationCode = _selectedStation?[_getStationCodeKey()] ?? 'N/A';
      final stationName = _selectedStation?[_getStationNameKey()] ?? 'N/A';
      final fullStationIdentifier = '$stationCode - $stationName';

      final result = await apiService.marine.sendImageRequestEmail(
        recipientEmail: toEmail,
        imageUrls: _selectedImageUrls.toList(),
        stationName: fullStationIdentifier,
        samplingDate: _dateController.text,
      );

      if(mounted) {
        if (result['success'] == true) {
          debugPrint("[Image Request] Server responded with success for email request.");
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text('Success! Email is being sent by the server.'),
              backgroundColor: Colors.green,
            ),
          );
        } else {
          debugPrint("[Image Request] Server responded with failure for email request. Message: ${result['message']}");
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text('Error: ${result['message']}'),
              backgroundColor: Colors.red,
            ),
          );
        }
      }
    } catch (e) {
      debugPrint("[Image Request] An exception occurred while sending email request: $e");
      if(mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('An error occurred: $e'),
            backgroundColor: Colors.red,
          ),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Marine Image Request")),
      body: Form(
        key: _formKey,
        child: ListView(
          padding: const EdgeInsets.all(24.0),
          children: [
            Text("Image Search Filters", style: Theme.of(context).textTheme.headlineSmall),
            const SizedBox(height: 24),
            DropdownButtonFormField<String>(
              value: _selectedSamplingType,
              items: _samplingTypes.map((type) => DropdownMenuItem(value: type, child: Text(type))).toList(),
              onChanged: (value) => setState(() {
                _selectedSamplingType = value;
                // --- FIX: Re-initialize filters when type changes ---
                _initializeStationFilters();
              }),
              decoration: const InputDecoration(labelText: 'Sampling Type *', border: OutlineInputBorder()),
              validator: (value) => value == null ? 'Please select a type' : null,
            ),
            const SizedBox(height: 16),
            DropdownSearch<String>(
              items: _statesList,
              selectedItem: _selectedStateName,
              popupProps: const PopupProps.menu(showSearchBox: true, searchFieldProps: TextFieldProps(decoration: InputDecoration(hintText: "Search State..."))),
              dropdownDecoratorProps: const DropDownDecoratorProps(dropdownSearchDecoration: InputDecoration(labelText: "Select State *", border: OutlineInputBorder())),
              onChanged: (state) {
                setState(() {
                  _selectedStateName = state;
                  _selectedCategoryName = null;
                  _selectedStation = null;
                  final auth = Provider.of<AuthProvider>(context, listen: false);
                  // --- FIX: Use helper to get dynamic station list ---
                  final allStations = _getStationsForType(auth);
                  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: _selectedCategoryName,
              enabled: _selectedStateName != null,
              popupProps: const PopupProps.menu(showSearchBox: true, searchFieldProps: TextFieldProps(decoration: InputDecoration(hintText: "Search Category..."))),
              dropdownDecoratorProps: const DropDownDecoratorProps(dropdownSearchDecoration: InputDecoration(labelText: "Select Category *", border: OutlineInputBorder())),
              onChanged: (category) {
                setState(() {
                  _selectedCategoryName = category;
                  _selectedStation = null;
                  final auth = Provider.of<AuthProvider>(context, listen: false);
                  // --- FIX: Use helper to get dynamic station list ---
                  final allStations = _getStationsForType(auth);
                  // --- FIX: Use dynamic key for sorting ---
                  final stationCodeKey = _getStationCodeKey();
                  _stationsForCategory = category != null ? (allStations.where((s) => s['state_name'] == _selectedStateName && s['category_name'] == category).toList()..sort((a, b) => (a[stationCodeKey] ?? '').compareTo(b[stationCodeKey] ?? ''))) : [];
                });
              },
              validator: (val) => _selectedStateName != null && val == null ? "Category is required" : null,
            ),
            const SizedBox(height: 16),
            DropdownSearch<Map<String, dynamic>>(
              items: _stationsForCategory,
              selectedItem: _selectedStation,
              enabled: _selectedCategoryName != null,
              // --- FIX: Use dynamic keys for display string ---
              itemAsString: (station) {
                final code = station[_getStationCodeKey()] ?? 'N/A';
                final name = station[_getStationNameKey()] ?? 'N/A';
                return "$code - $name";
              },
              popupProps: const PopupProps.menu(showSearchBox: true, searchFieldProps: TextFieldProps(decoration: InputDecoration(hintText: "Search Station..."))),
              dropdownDecoratorProps: const DropDownDecoratorProps(dropdownSearchDecoration: InputDecoration(labelText: "Select Station *", border: OutlineInputBorder())),
              onChanged: (station) => setState(() => _selectedStation = station),
              validator: (val) => _selectedCategoryName != null && val == null ? "Station is required" : null,
            ),
            const SizedBox(height: 16),
            TextFormField(
              controller: _dateController,
              readOnly: true,
              decoration: InputDecoration(
                labelText: 'Select Date *',
                hintText: 'Tap to pick a date',
                border: const OutlineInputBorder(),
                suffixIcon: IconButton(
                  icon: const Icon(Icons.calendar_today),
                  onPressed: _selectDate,
                ),
              ),
              onTap: _selectDate,
              validator: (val) => val == null || val.isEmpty ? "Date is required" : null,
            ),
            const SizedBox(height: 32),
            ElevatedButton.icon(
              icon: const Icon(Icons.search),
              label: const Text('Search Images'),
              onPressed: _isLoading ? null : _searchImages,
              style: ElevatedButton.styleFrom(
                padding: const EdgeInsets.symmetric(vertical: 16),
                textStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
              ),
            ),
            const SizedBox(height: 24),
            const Divider(thickness: 1),
            const SizedBox(height: 16),
            Text("Results", style: Theme.of(context).textTheme.headlineSmall),
            const SizedBox(height: 16),
            _buildResults(),
            if (_selectedImageUrls.isNotEmpty) ...[
              const SizedBox(height: 24),
              ElevatedButton.icon(
                icon: const Icon(Icons.email_outlined),
                label: Text('Send (${_selectedImageUrls.length}) Selected Image(s)'),
                onPressed: _showEmailDialog,
                style: ElevatedButton.styleFrom(
                  backgroundColor: Theme.of(context).colorScheme.secondary,
                  foregroundColor: Theme.of(context).colorScheme.onSecondary,
                  padding: const EdgeInsets.symmetric(vertical: 16),
                ),
              ),
            ],
          ],
        ),
      ),
    );
  }

  Widget _buildResults() {
    if (_isLoading) {
      return const Center(child: CircularProgressIndicator());
    }
    if (_imageUrls.isEmpty) {
      return const Center(
        child: Text(
          'No images found. Please adjust your filters and search again.',
          textAlign: TextAlign.center,
        ),
      );
    }
    return GridView.builder(
      shrinkWrap: true,
      physics: const NeverScrollableScrollPhysics(),
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 4,
        crossAxisSpacing: 8,
        mainAxisSpacing: 8,
        childAspectRatio: 1.0,
      ),
      itemCount: _imageUrls.length,
      itemBuilder: (context, index) {
        final imageUrl = _imageUrls[index];
        final isSelected = _selectedImageUrls.contains(imageUrl);

        return GestureDetector(
          onTap: () {
            setState(() {
              if (isSelected) {
                _selectedImageUrls.remove(imageUrl);
              } else {
                _selectedImageUrls.add(imageUrl);
              }
            });
          },
          child: Card(
            clipBehavior: Clip.antiAlias,
            elevation: 2.0,
            child: GridTile(
              child: Stack(
                fit: StackFit.expand,
                children: [
                  Image.network(
                    imageUrl,
                    fit: BoxFit.cover,
                    loadingBuilder: (context, child, loadingProgress) {
                      if (loadingProgress == null) return child;
                      return const Center(child: CircularProgressIndicator(strokeWidth: 2));
                    },
                    errorBuilder: (context, error, stackTrace) {
                      return const Icon(Icons.broken_image, color: Colors.grey, size: 40);
                    },
                  ),
                  if (isSelected)
                    Container(
                      color: Colors.black.withOpacity(0.6),
                      child: const Icon(Icons.check_circle, color: Colors.white, size: 40),
                    ),
                ],
              ),
            ),
          ),
        );
      },
    );
  }
}