// lib/screens/marine/investigative/marine_investigative_image_request.dart

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';
import '../../../services/marine_api_service.dart';

// Keys for investigative images, matching the local DB/JSON keys
const List<String> _investigativeImageKeys = [
  'inves_left_side_land_view',
  'inves_right_side_land_view',
  'inves_filling_water_into_sample_bottle',
  'inves_seawater_in_clear_glass_bottle',
  'inves_examine_preservative_ph_paper',
  'inves_optional_photo_01',
  'inves_optional_photo_02',
  'inves_optional_photo_03',
  'inves_optional_photo_04',
];

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

  @override
  State<MarineInvestigativeImageRequestScreen> createState() =>
      _MarineInvestigativeImageRequestScreenState();
}

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

  // Based on the Investigative data model, users can sample at Manual or Tarball stations
  String? _selectedStationType = 'Existing Manual Station';
  final List<String> _stationTypes = [
    'Existing Manual Station',
    'Existing Tarball Station'
  ];

  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();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (mounted) {
        _initializeStationFilters();
      }
    });
  }

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

  List<Map<String, dynamic>> _getStationsForType(AuthProvider auth) {
    switch (_selectedStationType) {
      case 'Existing Manual Station':
        return auth.manualStations ?? [];
      case 'Existing Tarball Station':
        return auth.tarballStations ?? [];
      default:
        return [];
    }
  }

  String _getStationIdKey() {
    switch (_selectedStationType) {
      case 'Existing Manual Station':
      case 'Existing Tarball Station':
      default:
        return 'station_id'; // Both use 'station_id'
    }
  }

  String _getStationCodeKey() {
    switch (_selectedStationType) {
      case 'Existing Manual Station':
        return 'man_station_code';
      case 'Existing Tarball Station':
        return 'tbl_station_code';
      default:
        return 'man_station_code';
    }
  }

  String _getStationNameKey() {
    switch (_selectedStationType) {
      case 'Existing Manual Station':
        return 'man_station_name';
      case 'Existing Tarball Station':
        return 'tbl_station_name';
      default:
        return 'man_station_name';
    }
  }

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

    if (allStations.isNotEmpty) {
      final states = allStations
          .map((s) => s['state_name'] as String?)
          .whereType<String>()
          .toSet()
          .toList();
      states.sort();
      setState(() {
        _statesList = states;
        _selectedStateName = null;
        _selectedCategoryName = null;
        _selectedStation = null;
        _categoriesForState = [];
        _stationsForCategory = [];
      });
    } else {
      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("[Investigative Image Request] Search button pressed.");
      debugPrint("[Investigative Image Request] Selected Station: ${_selectedStation}");
      debugPrint("[Investigative Image Request] Date: ${_selectedDate}");
      debugPrint("[Investigative Image Request] Station Type: $_selectedStationType");

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

      final stationIdKey = _getStationIdKey();
      final stationId = _selectedStation![stationIdKey];

      if (stationId == null) {
        debugPrint("[Investigative 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(
            "[Investigative Image Request] Calling API with Station ID: $stationId, Type: $_selectedStationType");

        // *** NOTE: This assumes you have created 'getInvestigativeSamplingImages' in MarineApiService ***
        final result = await apiService.marine.getInvestigativeSamplingImages(
          stationId: stationId as int,
          samplingDate: _selectedDate!,
          stationType: _selectedStationType!,
        );

        if (mounted && result['success'] == true) {
          final List<Map<String, dynamic>> records =
          List<Map<String, dynamic>>.from(result['data'] ?? []);
          final List<String> fetchedUrls = [];

          // For investigative, we only use one set of keys
          final List<String> imageKeys = _investigativeImageKeys;

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

                final fullUrl = imagePathFromServer.startsWith('http')
                    ? imagePathFromServer
                    : ApiService.imageBaseUrl + imagePathFromServer;

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

          setState(() {
            _imageUrls = fetchedUrls.toSet().toList();
          });
          debugPrint(
              "[Investigative Image Request] Successfully processed ${_imageUrls.length} image URLs.");
        } else if (mounted) {
          debugPrint(
              "[Investigative Image Request] API call failed. Message: ${result['message']}");
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
                content: Text(result['message'] ?? 'Failed to fetch images.')),
          );
        }
      } catch (e) {
        debugPrint(
            "[Investigative 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("[Investigative 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(
          "[Investigative Image Request] Sending email request to server for recipient: $toEmail");

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

      // *** NOTE: This assumes you have created 'sendInvestigativeImageRequestEmail' in MarineApiService ***
      final result = await apiService.marine.sendInvestigativeImageRequestEmail(
        recipientEmail: toEmail,
        imageUrls: _selectedImageUrls.toList(),
        stationName: fullStationIdentifier,
        samplingDate: _dateController.text,
      );

      if (mounted) {
        if (result['success'] == true) {
          debugPrint(
              "[Investigative 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(
              "[Investigative 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(
          "[Investigative 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 Investigative 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: _selectedStationType,
              items: _stationTypes
                  .map((type) => DropdownMenuItem(value: type, child: Text(type)))
                  .toList(),
              onChanged: (value) => setState(() {
                _selectedStationType = value;
                _initializeStationFilters();
              }),
              decoration: const InputDecoration(
                  labelText: 'Station 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);
                  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);
                  final allStations = _getStationsForType(auth);
                  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,
              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),
                    ),
                ],
              ),
            ),
          ),
        );
      },
    );
  }
}