// lib/screens/marine/investigative/marine_investigative_data_status_log.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:environment_monitoring_app/auth_provider.dart';
import 'package:environment_monitoring_app/models/marine_inves_manual_sampling_data.dart';
import 'package:environment_monitoring_app/services/local_storage_service.dart';
import 'package:environment_monitoring_app/services/marine_investigative_sampling_service.dart';
import 'dart:convert';

/// A simple class to hold an image file and its associated remark.
class ImageLogEntry {
  final File file;
  final String? remark;
  ImageLogEntry({required this.file, this.remark});
}

class SubmissionLogEntry {
  final String type;
  final String title;
  final String stationCode;
  final DateTime submissionDateTime;
  final String? reportId;
  final String status;
  final String message;
  final Map<String, dynamic> rawData;
  final String serverName;
  final String? apiStatusRaw;
  final String? ftpStatusRaw;
  bool isResubmitting;

  SubmissionLogEntry({
    required this.type,
    required this.title,
    required this.stationCode,
    required this.submissionDateTime,
    this.reportId,
    required this.status,
    required this.message,
    required this.rawData,
    required this.serverName,
    this.apiStatusRaw,
    this.ftpStatusRaw,
    this.isResubmitting = false,
  });
}

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

  @override
  State<MarineInvestigativeDataStatusLog> createState() =>
      _MarineInvestigativeDataStatusLogState();
}

class _MarineInvestigativeDataStatusLogState
    extends State<MarineInvestigativeDataStatusLog> {
  final LocalStorageService _localStorageService = LocalStorageService();
  late MarineInvestigativeSamplingService _marineInvestigativeService;

  List<SubmissionLogEntry> _investigativeLogs = [];
  List<SubmissionLogEntry> _filteredInvestigativeLogs = [];

  final TextEditingController _investigativeSearchController =
  TextEditingController();

  bool _isLoading = true;
  final Map<String, bool> _isResubmitting = {};

  @override
  void initState() {
    super.initState();
    _investigativeSearchController.addListener(_filterLogs);
    _loadAllLogs();
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // Fetch the single, global instance of the service from the Provider tree.
    _marineInvestigativeService =
        Provider.of<MarineInvestigativeSamplingService>(context);
  }

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

  String _getStationName(Map<String, dynamic> log) {
    String stationType = log['stationTypeSelection'] ?? '';
    if (stationType == 'Existing Manual Station') {
      return log['selectedStation']?['man_station_name'] ?? 'Unknown Manual Station';
    } else if (stationType == 'Existing Tarball Station') {
      return log['selectedTarballStation']?['tbl_station_name'] ??
          'Unknown Tarball Station';
    } else if (stationType == 'New Location') {
      return log['newStationName'] ?? 'New Location';
    }
    return 'Unknown Station';
  }

  String _getStationCode(Map<String, dynamic> log) {
    String stationType = log['stationTypeSelection'] ?? '';
    if (stationType == 'Existing Manual Station') {
      return log['selectedStation']?['man_station_code'] ?? 'N/A';
    } else if (stationType == 'Existing Tarball Station') {
      return log['selectedTarballStation']?['tbl_station_code'] ?? 'N/A';
    } else if (stationType == 'New Location') {
      return log['newStationCode'] ?? 'NEW';
    }
    return 'N/A';
  }

  Future<void> _loadAllLogs() async {
    setState(() => _isLoading = true);

    final investigativeLogs =
    await _localStorageService.getAllInvestigativeLogs();

    final List<SubmissionLogEntry> tempInvestigative = [];

    for (var log in investigativeLogs) {
      final String dateStr = log['sampling_date'] ?? '';
      final String timeStr = log['sampling_time'] ?? '';

      final dt = DateTime.tryParse('$dateStr $timeStr');

      tempInvestigative.add(SubmissionLogEntry(
        type: 'Investigative Sampling',
        title: _getStationName(log),
        stationCode: _getStationCode(log),
        submissionDateTime: dt ?? DateTime.fromMillisecondsSinceEpoch(0),
        reportId: log['reportId']?.toString(),
        status: log['submissionStatus'] ?? 'L1',
        message: log['submissionMessage'] ?? 'No status message.',
        rawData: log,
        serverName: log['serverConfigName'] ?? 'Unknown Server',
        apiStatusRaw: log['api_status'],
        ftpStatusRaw: log['ftp_status'],
      ));
    }

    tempInvestigative
        .sort((a, b) => b.submissionDateTime.compareTo(a.submissionDateTime));

    if (mounted) {
      setState(() {
        _investigativeLogs = tempInvestigative;
        _isLoading = false;
      });
      _filterLogs();
    }
  }

  void _filterLogs() {
    final investigativeQuery =
    _investigativeSearchController.text.toLowerCase();

    setState(() {
      _filteredInvestigativeLogs = _investigativeLogs
          .where((log) => _logMatchesQuery(log, investigativeQuery))
          .toList();
    });
  }

  bool _logMatchesQuery(SubmissionLogEntry log, String query) {
    if (query.isEmpty) return true;
    return log.title.toLowerCase().contains(query) ||
        log.stationCode.toLowerCase().contains(query) ||
        log.serverName.toLowerCase().contains(query) ||
        (log.reportId?.toLowerCase() ?? '').contains(query);
  }

  Future<void> _resubmitData(SubmissionLogEntry log) async {
    final logKey = log.reportId ?? log.submissionDateTime.toIso8601String();
    if (mounted) {
      setState(() {
        _isResubmitting[logKey] = true;
      });
    }

    try {
      final authProvider = Provider.of<AuthProvider>(context, listen: false);
      final appSettings = authProvider.appSettings;

      Map<String, dynamic> result = {};

      if (log.type == 'Investigative Sampling') {
        final dataToResubmit =
        MarineInvesManualSamplingData.fromJson(log.rawData);

        result = await _marineInvestigativeService.submitInvestigativeSample(
          data: dataToResubmit,
          appSettings: appSettings,
          context: context,
          authProvider: authProvider,
          logDirectory: log.rawData['logDirectory'] as String?,
        );
      }

      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
              content:
              Text(result['message'] ?? 'Resubmission process completed.')),
        );
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Resubmission failed: $e')),
        );
      }
    } finally {
      if (mounted) {
        setState(() {
          _isResubmitting.remove(logKey);
        });
        _loadAllLogs();
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final hasAnyLogs = _investigativeLogs.isNotEmpty;

    return Scaffold(
      appBar:
      AppBar(title: const Text('Marine Investigative Data Status Log')),
      body: _isLoading
          ? const Center(child: CircularProgressIndicator())
          : RefreshIndicator(
        onRefresh: _loadAllLogs,
        child: !hasAnyLogs
            ? const Center(child: Text('No submission logs found.'))
            : ListView(
          padding: const EdgeInsets.all(8.0),
          children: [
            _buildCategorySection('Investigative Sampling',
                _filteredInvestigativeLogs, _investigativeSearchController),
          ],
        ),
      ),
    );
  }

  Widget _buildCategorySection(String category, List<SubmissionLogEntry> logs,
      TextEditingController searchController) {
    return Card(
      margin: const EdgeInsets.symmetric(vertical: 8.0),
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(category,
                style: Theme.of(context)
                    .textTheme
                    .titleLarge
                    ?.copyWith(fontWeight: FontWeight.bold)),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 8.0),
              child: TextField(
                controller: searchController,
                decoration: InputDecoration(
                  hintText: 'Search in $category...',
                  prefixIcon: const Icon(Icons.search, size: 20),
                  isDense: true,
                  border: const OutlineInputBorder(),
                  suffixIcon: searchController.text.isNotEmpty
                      ? IconButton(
                    icon: const Icon(Icons.clear),
                    onPressed: () {
                      searchController.clear();
                    },
                  )
                      : null,
                ),
              ),
            ),
            const Divider(),
            if (logs.isEmpty)
              const Padding(
                  padding: EdgeInsets.all(16.0),
                  child: Center(
                      child: Text(
                          'No logs match your search in this category.')))
            else
              ListView.builder(
                shrinkWrap: true,
                physics: const NeverScrollableScrollPhysics(),
                itemCount: logs.length,
                itemBuilder: (context, index) {
                  return _buildLogListItem(logs[index]);
                },
              ),
          ],
        ),
      ),
    );
  }

  Widget _buildLogListItem(SubmissionLogEntry log) {
    final logKey = log.reportId ?? log.submissionDateTime.toIso8601String();
    final isResubmitting = _isResubmitting[logKey] ?? false;

    final bool isFullSuccess = log.status == 'S4';
    final bool isPartialSuccess = log.status == 'S3' || log.status == 'L4';
    final bool canResubmit = !isFullSuccess;

    IconData statusIcon;
    Color statusColor;

    if (isFullSuccess) {
      statusIcon = Icons.check_circle_outline;
      statusColor = Colors.green;
    } else if (isPartialSuccess) {
      statusIcon = Icons.warning_amber_rounded;
      statusColor = Colors.orange;
    } else {
      statusIcon = Icons.error_outline;
      statusColor = Colors.red;
    }

    final titleWidget = RichText(
      text: TextSpan(
        style: Theme.of(context)
            .textTheme
            .bodyLarge
            ?.copyWith(fontWeight: FontWeight.w500),
        children: <TextSpan>[
          TextSpan(text: '${log.title} '),
          TextSpan(
            text: '(${log.stationCode})',
            style: Theme.of(context)
                .textTheme
                .bodySmall
                ?.copyWith(fontWeight: FontWeight.normal),
          ),
        ],
      ),
    );

    final bool isDateValid = !log.submissionDateTime
        .isAtSameMomentAs(DateTime.fromMillisecondsSinceEpoch(0));
    final subtitle = isDateValid
        ? '${log.serverName} - ${DateFormat('yyyy-MM-dd HH:mm').format(log.submissionDateTime)}'
        : '${log.serverName} - Invalid Date';

    return ExpansionTile(
      key: PageStorageKey(logKey),
      leading: Icon(statusIcon, color: statusColor),
      title: titleWidget,
      subtitle: Text(subtitle),
      trailing: canResubmit
          ? (isResubmitting
          ? const SizedBox(
          height: 24,
          width: 24,
          child: CircularProgressIndicator(strokeWidth: 3))
          : IconButton(
          icon: const Icon(Icons.sync, color: Colors.blue),
          tooltip: 'Resubmit',
          onPressed: () => _resubmitData(log)))
          : null,
      children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              _buildDetailRow('High-Level Status:', log.status),
              _buildDetailRow('Server:', log.serverName),
              _buildDetailRow('Report ID:', log.reportId ?? 'N/A'),
              _buildDetailRow('Submission Type:', log.type),
              Padding(
                padding: const EdgeInsets.symmetric(vertical: 8.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    TextButton.icon(
                      icon: Icon(Icons.list_alt,
                          color: Theme.of(context).colorScheme.primary),
                      label: Text('View Data',
                          style: TextStyle(
                              color: Theme.of(context).colorScheme.primary)),
                      onPressed: () => _showDataDialog(context, log),
                    ),
                    TextButton.icon(
                      icon: Icon(Icons.photo_library_outlined,
                          color: Theme.of(context).colorScheme.secondary),
                      label: Text('View Images',
                          style: TextStyle(
                              color:
                              Theme.of(context).colorScheme.secondary)),
                      onPressed: () => _showImageDialog(context, log),
                    ),
                  ],
                ),
              ),
              const Divider(height: 10),
              _buildGranularStatus('API', log.apiStatusRaw),
              _buildGranularStatus('FTP', log.ftpStatusRaw),
            ],
          ),
        )
      ],
    );
  }

  TableRow _buildCategoryRow(
      BuildContext context, String title, IconData icon) {
    return TableRow(
      decoration: BoxDecoration(
        color: Colors.grey.shade100,
      ),
      children: [
        Padding(
          padding:
          const EdgeInsets.only(top: 16.0, bottom: 8.0, left: 8.0, right: 8.0),
          child: Row(
            children: [
              Icon(icon, size: 20, color: Theme.of(context).primaryColor),
              const SizedBox(width: 8),
              Text(
                title,
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  fontSize: 16,
                  color: Theme.of(context).primaryColor,
                ),
              ),
            ],
          ),
        ),
        const SizedBox.shrink(), // Empty cell for the second column
      ],
    );
  }

  TableRow _buildDataTableRow(String label, String? value) {
    String displayValue =
    (value == null || value.isEmpty || value == 'null') ? 'N/A' : value;

    if (displayValue == '-999.0' || displayValue == '-999') {
      displayValue = 'N/A';
    }

    return TableRow(
      children: [
        Padding(
          padding: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 8.0),
          child: Text(label, style: const TextStyle(fontWeight: FontWeight.bold)),
        ),
        Padding(
          padding: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 8.0),
          child: Text(displayValue),
        ),
      ],
    );
  }

  String? _getString(Map<String, dynamic> data, String key) {
    final value = data[key];
    if (value == null) return null;
    if (value is double && value == -999.0) return 'N/A';
    return value.toString();
  }

  void _showDataDialog(BuildContext context, SubmissionLogEntry log) {
    final Map<String, dynamic> data = log.rawData;
    final List<TableRow> tableRows = [];

    // --- 1. Sampling Info ---
    tableRows.add(
        _buildCategoryRow(context, 'Sampling Info', Icons.calendar_today));
    tableRows
        .add(_buildDataTableRow('Date', _getString(data, 'sampling_date')));
    tableRows
        .add(_buildDataTableRow('Time', _getString(data, 'sampling_time')));

    String? firstSamplerName = _getString(data, 'first_sampler_name');
    tableRows.add(_buildDataTableRow('1st Sampler', firstSamplerName));

    String? secondSamplerName;
    if (data['secondSampler'] is Map) {
      secondSamplerName =
          (data['secondSampler'] as Map)['first_name']?.toString();
    }
    tableRows.add(_buildDataTableRow('2nd Sampler', secondSamplerName));
    tableRows
        .add(_buildDataTableRow('Sample ID', _getString(data, 'sample_id_code')));

    // --- 2. Station & Location ---
    tableRows.add(
        _buildCategoryRow(context, 'Station & Location', Icons.location_on_outlined));
    tableRows.add(
        _buildDataTableRow('Station', '${log.stationCode} - ${log.title}'));
    tableRows.add(_buildDataTableRow(
        'Current Latitude', _getString(data, 'current_latitude')));
    tableRows.add(_buildDataTableRow(
        'Current Longitude', _getString(data, 'current_longitude')));
    tableRows.add(_buildDataTableRow(
        'Distance (km)', _getString(data, 'distance_difference_in_km')));
    tableRows.add(_buildDataTableRow(
        'Distance Remarks', _getString(data, 'distance_difference_remarks')));

    // --- 3. Site Conditions ---
    tableRows.add(
        _buildCategoryRow(context, 'Site Conditions', Icons.wb_sunny_outlined));
    tableRows.add(_buildDataTableRow('Tide', _getString(data, 'tide_level')));
    tableRows.add(_buildDataTableRow('Sea', _getString(data, 'sea_condition')));
    tableRows.add(_buildDataTableRow('Weather', _getString(data, 'weather')));
    tableRows
        .add(_buildDataTableRow('Event Remarks', _getString(data, 'event_remarks')));
    tableRows.add(_buildDataTableRow('Lab Remarks', _getString(data, 'lab_remarks')));

    // --- 4. Parameters ---
    tableRows
        .add(_buildCategoryRow(context, 'Parameters', Icons.bar_chart));
    tableRows.add(_buildDataTableRow('Sonde ID', _getString(data, 'sonde_id')));
    tableRows.add(
        _buildDataTableRow('Capture Date', _getString(data, 'data_capture_date')));
    tableRows.add(
        _buildDataTableRow('Capture Time', _getString(data, 'data_capture_time')));
    tableRows.add(_buildDataTableRow(
        'Oxygen Conc (mg/L)', _getString(data, 'oxygen_concentration')));
    tableRows.add(_buildDataTableRow(
        'Oxygen Sat (%)', _getString(data, 'oxygen_saturation')));
    tableRows.add(_buildDataTableRow('pH', _getString(data, 'ph')));
    tableRows
        .add(_buildDataTableRow('Salinity (ppt)', _getString(data, 'salinity')));
    tableRows.add(_buildDataTableRow(
        'Conductivity (µS/cm)', _getString(data, 'electrical_conductivity')));
    tableRows.add(
        _buildDataTableRow('Temperature (°C)', _getString(data, 'temperature')));
    tableRows.add(_buildDataTableRow('TDS (mg/L)', _getString(data, 'tds')));
    tableRows
        .add(_buildDataTableRow('Turbidity (NTU)', _getString(data, 'turbidity')));
    tableRows.add(
        _buildDataTableRow('Battery (V)', _getString(data, 'battery_voltage')));

    showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          title: Text('${log.stationCode} - ${log.title}'),
          content: SizedBox(
            width: double.maxFinite,
            child: SingleChildScrollView(
              child: Table(
                columnWidths: const {
                  0: IntrinsicColumnWidth(),
                  1: FlexColumnWidth(),
                },
                border: TableBorder(
                  horizontalInside: BorderSide(
                    color: Colors.grey.shade300,
                    width: 0.5,
                  ),
                ),
                children: tableRows,
              ),
            ),
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.of(context).pop(),
              child: const Text('Close'),
            ),
          ],
        );
      },
    );
  }

  void _showImageDialog(BuildContext context, SubmissionLogEntry log) {
    final List<ImageLogEntry> imageEntries = [];

    if (log.type == 'Investigative Sampling') {
      const imageRemarkMap = {
        'inves_left_side_land_view': null,
        'inves_right_side_land_view': null,
        'inves_filling_water_into_sample_bottle': null,
        'inves_seawater_in_clear_glass_bottle': null,
        'inves_examine_preservative_ph_paper': null,
        'inves_optional_photo_01': 'inves_optional_photo_01_remarks',
        'inves_optional_photo_02': 'inves_optional_photo_02_remarks',
        'inves_optional_photo_03': 'inves_optional_photo_03_remarks',
        'inves_optional_photo_04': 'inves_optional_photo_04_remarks',
      };

      for (final entry in imageRemarkMap.entries) {
        final imageKey = entry.key;
        final remarkKey = entry.value;

        final path = log.rawData[imageKey];
        if (path != null && path is String && path.isNotEmpty) {
          final file = File(path);
          if (file.existsSync()) {
            final remark = (remarkKey != null
                ? log.rawData[remarkKey] as String?
                : null);
            imageEntries.add(ImageLogEntry(file: file, remark: remark));
          }
        }
      }
    }

    if (imageEntries.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('No images are attached to this log.'),
          backgroundColor: Colors.orange,
        ),
      );
      return;
    }

    showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          title: Text('Images for ${log.stationCode} - ${log.title}'),
          content: SizedBox(
            width: double.maxFinite,
            child: GridView.builder(
              shrinkWrap: true,
              itemCount: imageEntries.length,
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2,
                crossAxisSpacing: 8,
                mainAxisSpacing: 8,
              ),
              itemBuilder: (context, index) {
                final imageEntry = imageEntries[index];
                final bool hasRemark =
                    imageEntry.remark != null && imageEntry.remark!.isNotEmpty;

                return Card(
                  clipBehavior: Clip.antiAlias,
                  elevation: 2,
                  child: Stack(
                    fit: StackFit.expand,
                    children: [
                      Image.file(
                        imageEntry.file,
                        fit: BoxFit.cover,
                        errorBuilder: (context, error, stack) {
                          return const Center(
                            child: Icon(
                              Icons.broken_image,
                              color: Colors.grey,
                              size: 40,
                            ),
                          );
                        },
                      ),
                      if (hasRemark)
                        Positioned(
                          bottom: 0,
                          left: 0,
                          right: 0,
                          child: Container(
                            padding: const EdgeInsets.all(6.0),
                            decoration: BoxDecoration(
                              gradient: LinearGradient(
                                begin: Alignment.bottomCenter,
                                end: Alignment.topCenter,
                                colors: [
                                  Colors.black.withOpacity(0.8),
                                  Colors.black.withOpacity(0.0)
                                ],
                              ),
                            ),
                            child: Text(
                              imageEntry.remark!,
                              style: const TextStyle(
                                color: Colors.white,
                                fontSize: 12,
                                fontWeight: FontWeight.bold,
                              ),
                              maxLines: 2,
                              overflow: TextOverflow.ellipsis,
                            ),
                          ),
                        ),
                    ],
                  ),
                );
              },
            ),
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.of(context).pop(),
              child: const Text('Close'),
            ),
          ],
        );
      },
    );
  }

  Widget _buildGranularStatus(String type, String? jsonStatus) {
    if (jsonStatus == null || jsonStatus.isEmpty) {
      return Container();
    }

    List<dynamic> statuses;
    try {
      statuses = jsonDecode(jsonStatus);
    } catch (_) {
      return _buildDetailRow('$type Status:', jsonStatus);
    }

    if (statuses.isEmpty) {
      return Container();
    }

    return Padding(
      padding: const EdgeInsets.only(top: 8.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('$type Status:',
              style: const TextStyle(fontWeight: FontWeight.bold)),
          ...statuses.map((s) {
            final serverName =
                s['server_name'] ?? s['config_name'] ?? 'Server N/A';
            final status = s['message'] ?? 'N/A';
            final bool isSuccess = s['success'] as bool? ?? false;
            final IconData icon =
            isSuccess ? Icons.check_circle_outline : Icons.error_outline;
            final Color color = isSuccess ? Colors.green : Colors.red;
            String detailLabel = (s['type'] != null) ? '(${s['type']})' : '';

            return Padding(
              padding:
              const EdgeInsets.symmetric(vertical: 3.0, horizontal: 8.0),
              child: Row(
                children: [
                  Icon(icon, size: 16, color: color),
                  const SizedBox(width: 5),
                  Expanded(child: Text('$serverName $detailLabel: $status')),
                ],
              ),
            );
          }).toList(),
        ],
      ),
    );
  }

  Widget _buildDetailRow(String label, String value) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4.0),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Expanded(
              flex: 2,
              child:
              Text(label, style: const TextStyle(fontWeight: FontWeight.bold))),
          const SizedBox(width: 8),
          Expanded(flex: 3, child: Text(value)),
        ],
      ),
    );
  }
}