// lib/models/marine_manual_npe_report_data.dart

import 'dart:io';
import 'dart:convert';

/// A dedicated data model for the Marine Manual Notification of Pollution Event (NPE) report.
class MarineManualNpeReportData {
  // --- Reporter & Event Info ---
  String? firstSamplerName;
  int? firstSamplerUserId;
  String? eventDate;
  String? eventTime;

  // --- Source Origin (Kept for internal tracking, but not displayed) ---
  String? sourceOrigin;

  // --- Location Info ---
  String? locationDescription; // For new locations
  String? stateName;           // For new locations or tarball stations
  Map<String, dynamic>? selectedStation; // For existing stations
  String? latitude;
  String? longitude;

  // --- In-Situ Measurements ---
  double? oxygenSaturation;
  double? electricalConductivity;
  double? oxygenConcentration;
  double? turbidity;
  double? ph;
  double? temperature;

  // --- NPE Observations ---
  Map<String, bool> fieldObservations = {
    'Oil slick on the water surface/ Oil spill': false,
    'Discoloration of the sea water': false,
    'Formation of foam on the surface': false,
    'Coral bleaching or dead corals': false,
    'Observation of tar balls': false,
    'Excessive debris': false,
    'Red tides or algae blooms': false,
    'Silt plume': false,
    'Foul smell': false,
    'Others': false,
  };
  String? othersObservationRemark;
  String? possibleSource;

  // --- Attachments ---
  File? image1;
  File? image2;
  File? image3;
  File? image4;
  String? image1Remark;
  String? image2Remark;
  String? image3Remark;
  String? image4Remark;

  // --- Tarball Classification Fields ---
  int? tarballClassificationId;
  Map<String, dynamic>? selectedTarballClassification;

  // --- Submission Status ---
  String? submissionStatus;
  String? submissionMessage;
  String? reportId;

  MarineManualNpeReportData(); // Constructor

  /// Creates a JSON object for offline database storage.
  Map<String, dynamic> toDbJson() {
    return {
      'firstSamplerName': firstSamplerName,
      'firstSamplerUserId': firstSamplerUserId,
      'eventDate': eventDate,
      'eventTime': eventTime,
      'sourceOrigin': sourceOrigin,
      'locationDescription': locationDescription,
      'stateName': stateName,
      'selectedStation': selectedStation,
      'latitude': latitude,
      'longitude': longitude,
      'oxygenSaturation': oxygenSaturation,
      'electricalConductivity': electricalConductivity,
      'oxygenConcentration': oxygenConcentration,
      'turbidity': turbidity,
      'ph': ph,
      'temperature': temperature,
      'fieldObservations': fieldObservations,
      'othersObservationRemark': othersObservationRemark,
      'possibleSource': possibleSource,
      'image1Remark': image1Remark,
      'image2Remark': image2Remark,
      'image3Remark': image3Remark,
      'image4Remark': image4Remark,
      'tarballClassificationId': tarballClassificationId,
      'selectedTarballClassification': selectedTarballClassification,
      'submissionStatus': submissionStatus,
      'submissionMessage': submissionMessage,
      'reportId': reportId,
    };
  }

  /// Formats the data for the API POST request body.
  Map<String, String> toApiFormData() {
    final Map<String, String> map = {};
    void add(String key, dynamic value) {
      if (value != null && value.toString().isNotEmpty) {
        map[key] = value.toString();
      }
    }

    add('npe_date', eventDate);
    add('npe_time', eventTime);
    add('first_sampler_user_id', firstSamplerUserId);

    // --- FIX START: Correctly map 'station_id' to specific API fields ---
    if (selectedStation != null) {
      // Check if it is a Manual Station (has 'man_station_code')
      if (selectedStation!.containsKey('man_station_code')) {
        // Map generic 'station_id' to API's expected 'man_station_id'
        add('man_station_id', selectedStation!['station_id'] ?? selectedStation!['man_station_id']);
        add('station_code', selectedStation!['man_station_code']);
        add('station_name', selectedStation!['man_station_name']);
      }
      // Check if it is a Tarball Station (has 'tbl_station_code')
      else if (selectedStation!.containsKey('tbl_station_code')) {
        // Map generic 'station_id' to API's expected 'tbl_station_id'
        add('tbl_station_id', selectedStation!['station_id'] ?? selectedStation!['tbl_station_id']);
        add('station_code', selectedStation!['tbl_station_code']);
        add('station_name', selectedStation!['tbl_station_name']);
      }
    } else {
      // New Location: Use description
      add('location_description', locationDescription);
      add('state_name', stateName);
    }
    // --- FIX END ---

    add('latitude', latitude);
    add('longitude', longitude);
    add('npe_oxygen_sat', oxygenSaturation);
    add('npe_conductivity', electricalConductivity);
    add('npe_oxygen_conc', oxygenConcentration);
    add('npe_turbidity', turbidity);
    add('npe_ph', ph);
    add('npe_temperature', temperature);

    final selectedObs = fieldObservations.entries
        .where((entry) => entry.value)
        .map((entry) => entry.key)
        .toList();
    add('npe_observations', jsonEncode(selectedObs));
    if (fieldObservations['Others'] == true) {
      add('npe_others_remarks', othersObservationRemark);
    }
    add('npe_possible_source', possibleSource);

    add('npe_image_1_remarks', image1Remark);
    add('npe_image_2_remarks', image2Remark);
    add('npe_image_3_remarks', image3Remark);
    add('npe_image_4_remarks', image4Remark);

    add('classification_id', tarballClassificationId);

    return map;
  }

  /// Gathers all image files for the multipart API request.
  Map<String, File?> toApiImageFiles() {
    return {
      'npe_image_1': image1,
      'npe_image_2': image2,
      'npe_image_3': image3,
      'npe_image_4': image4,
    };
  }

  /// Generates the Telegram alert message for this NPE report.
  String generateTelegramAlertMessage() {
    String locationDesc;

    if (selectedStation != null) {
      final code = selectedStation!['man_station_code'] ?? selectedStation!['tbl_station_code'] ?? 'N/A';
      final name = selectedStation!['man_station_name'] ?? selectedStation!['tbl_station_name'] ?? 'N/A';
      locationDesc = '$code - $name';
    } else {
      locationDesc = locationDescription ?? 'A custom location';
    }

    final buffer = StringBuffer()
      ..writeln('🚨 *Notification of Pollution Event (NPE) Submitted:*')
      ..writeln()
      ..writeln('*Location:* $locationDesc')
      ..writeln('*Event Date:* $eventDate $eventTime')
      ..writeln('*Submitted by:* ${firstSamplerName ?? "N/A"}')
      ..writeln('*Status of Submission:* Successful');

    final observations = fieldObservations.entries
        .where((e) => e.value)
        .map((e) => '- ${e.key}')
        .toList();

    if (observations.isNotEmpty) {
      buffer
        ..writeln()
        ..writeln('📋 *Observations:*');
      buffer.writeAll(observations, '\n');
      if (fieldObservations['Others'] == true && othersObservationRemark != null && othersObservationRemark!.isNotEmpty) {
        buffer.writeln('\n  - Remarks: $othersObservationRemark');
      }
    }

    if (possibleSource != null && possibleSource!.isNotEmpty) {
      buffer
        ..writeln()
        ..writeln('*Possible Source:* $possibleSource');
    }

    if (selectedTarballClassification != null) {
      buffer
        ..writeln()
        ..writeln('*Tarball Classification:* ${selectedTarballClassification!['classification_name']}');
    }

    final remarks = [
      if (image1Remark != null && image1Remark!.isNotEmpty) '*Fig 1:* $image1Remark',
      if (image2Remark != null && image2Remark!.isNotEmpty) '*Fig 2:* $image2Remark',
      if (image3Remark != null && image3Remark!.isNotEmpty) '*Fig 3:* $image3Remark',
      if (image4Remark != null && image4Remark!.isNotEmpty) '*Fig 4:* $image4Remark',
    ];

    if (remarks.isNotEmpty) {
      buffer
        ..writeln()
        ..writeln('📸 *Attachment Remarks:*');
      buffer.writeAll(remarks, '\n');
    }

    return buffer.toString();
  }
}