// lib/services/marine_manual_equipment_maintenance_service.dart

import 'dart:async';
import 'dart:io';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:connectivity_plus/connectivity_plus.dart';

import '../auth_provider.dart';
import '../models/marine_manual_equipment_maintenance_data.dart';
import 'api_service.dart';
import 'package:environment_monitoring_app/services/database_helper.dart';
import 'package:environment_monitoring_app/services/local_storage_service.dart';
import 'package:environment_monitoring_app/services/server_config_service.dart';
import 'package:environment_monitoring_app/services/retry_service.dart';
import 'package:environment_monitoring_app/services/submission_api_service.dart';

import 'base_api_service.dart'; // Import for SessionExpiredException

class MarineManualEquipmentMaintenanceService {
  // Use the new generic submission service
  final SubmissionApiService _submissionApiService = SubmissionApiService();
  final LocalStorageService _localStorageService = LocalStorageService();
  final ServerConfigService _serverConfigService = ServerConfigService();
  final DatabaseHelper _dbHelper = DatabaseHelper();
  final RetryService _retryService = RetryService();

  // Keep ApiService for getPreviousMaintenanceLogs
  final ApiService _apiService;
  MarineManualEquipmentMaintenanceService(this._apiService);

  // *** START: Renamed this method ***
  /// Main submission method with online/offline branching logic
  Future<Map<String, dynamic>> submitMaintenanceReport({
    // *** END: Renamed this method ***
    required MarineManualEquipmentMaintenanceData data,
    required AuthProvider authProvider,
    List<Map<String, dynamic>>? appSettings, // Added for consistency
    BuildContext? context, // Added for consistency
    String? logDirectory,
  }) async {
    const String moduleName = 'marine_equipment_maintenance';

    // --- START: ADDED LINE ---
    // Populate the user name from the AuthProvider
    data.conductedByUserName = authProvider.profileData?['first_name'] as String?;
    // --- END: ADDED LINE ---

    final connectivityResult = await Connectivity().checkConnectivity();
    bool isOnline = connectivityResult != ConnectivityResult.none;
    bool isOfflineSession = authProvider.isLoggedIn &&
        (authProvider.profileData?['token']
            ?.startsWith("offline-session-") ??
            false);

    if (isOnline && isOfflineSession) {
      debugPrint(
          "$moduleName submission online during offline session. Attempting auto-relogin...");
      final bool transitionSuccess =
      await authProvider.checkAndTransitionToOnlineSession();
      if (transitionSuccess) {
        isOfflineSession = false;
      } else {
        isOnline = false;
      }
    }

    if (isOnline && !isOfflineSession) {
      debugPrint("Proceeding with direct ONLINE $moduleName submission...");
      return await _performOnlineSubmission(
        data: data,
        moduleName: moduleName,
        authProvider: authProvider,
        logDirectory: logDirectory,
      );
    } else {
      debugPrint("Proceeding with OFFLINE $moduleName queuing mechanism...");
      return await _performOfflineQueuing(
        data: data,
        moduleName: moduleName,
      );
    }
  }

  /// Handles the direct online submission.
  Future<Map<String, dynamic>> _performOnlineSubmission({
    required MarineManualEquipmentMaintenanceData data,
    required String moduleName,
    required AuthProvider authProvider,
    String? logDirectory,
  }) async {
    final serverName =
        (await _serverConfigService.getActiveApiConfig())?['config_name']
        as String? ??
            'Default';
    Map<String, dynamic> apiResult;

    try {
      apiResult = await _submissionApiService.submitPost(
        moduleName: moduleName,
        endpoint: 'marine/maintenance', // Endpoint from marine_api_service.dart
        body: data.toApiFormData(),
      );
    } on SessionExpiredException {
      final bool reloginSuccess = await authProvider.attemptSilentRelogin();
      if (reloginSuccess) {
        apiResult = await _submissionApiService.submitPost(
          moduleName: moduleName,
          endpoint: 'marine/maintenance',
          body: data.toApiFormData(),
        );
      } else {
        apiResult = {
          'success': false,
          'message': 'Session expired. Please log in again.'
        };
      }
    } on SocketException catch (e) {
      apiResult = {
        'success': false,
        'message': "API submission failed with network error: $e"
      };
      // submission_api_service will queue this failure
    } on TimeoutException catch (e) {
      apiResult = {
        'success': false,
        'message': "API submission timed out: $e"
      };
      // submission_api_service will queue this failure
    } catch (e) {
      apiResult = {
        'success': false,
        'message': 'An unexpected error occurred: $e'
      };
    }

    // Log the final result
    final bool overallSuccess = apiResult['success'] == true;
    final String finalMessage =
        apiResult['message'] ?? (overallSuccess ? 'Submission successful.' : 'Submission failed.');
    final String finalStatus = overallSuccess ? 'S4' : 'L1'; // S4 = API Success

    if (overallSuccess) {
      // Assuming the API returns an ID. Adjust 'maintenance_id' if needed.
      data.reportId = apiResult['data']?['maintenance_id']?.toString();
    }

    await _logAndSave(
      data: data,
      status: finalStatus,
      message: finalMessage,
      apiResult: apiResult,
      serverName: serverName,
      logDirectory: logDirectory,
    );

    return apiResult;
  }

  /// Handles saving the submission to local storage and queuing for retry.
  Future<Map<String, dynamic>> _performOfflineQueuing({
    required MarineManualEquipmentMaintenanceData data,
    required String moduleName,
  }) async {
    final serverConfig = await _serverConfigService.getActiveApiConfig();
    final serverName =
        serverConfig?['config_name'] as String? ?? 'Default';

    data.submissionStatus = 'L1';
    data.submissionMessage = 'Equipment Maintenance queued due to being offline.';

    // This method is added to LocalStorageService
    final String? localLogPath =
    await _localStorageService.saveEquipmentMaintenanceData(data, serverName: serverName);

    if (localLogPath == null) {
      const message =
          "Failed to save Equipment Maintenance to local device storage.";
      await _logAndSave(
          data: data,
          status: 'Error',
          message: message,
          apiResult: {},
          serverName: serverName);
      return {'success': false, 'message': message};
    }

    await _retryService.queueTask(
      type: 'equipment_maintenance_submission', // New task type
      payload: {
        'module': moduleName,
        'localLogPath': localLogPath,
        'serverConfig': serverConfig,
      },
    );

    const successMessage =
        "No internet connection. Equipment Maintenance has been saved and queued for upload.";
    return {'success': true, 'message': successMessage};
  }

  /// Logs the submission to the local file system and the central SQL database.
  Future<void> _logAndSave({
    required MarineManualEquipmentMaintenanceData data,
    required String status,
    required String message,
    required Map<String, dynamic> apiResult,
    required String serverName,
    String? logDirectory,
  }) async {
    data.submissionStatus = status;
    data.submissionMessage = message;

    final fileTimestamp = data.maintenanceDate ?? DateTime.now().toIso8601String();

    if (logDirectory != null) {
      // This is an update to an existing log file
      // --- START: MODIFIED BLOCK ---
      final Map<String, dynamic> updatedLogData = data.toDbJson();
      // Add metadata
      updatedLogData['submissionStatus'] = status;
      updatedLogData['submissionMessage'] = message;
      updatedLogData['logDirectory'] = logDirectory;
      updatedLogData['serverConfigName'] = serverName;
      updatedLogData['api_status'] = jsonEncode(apiResult);
      // All other fields (ysiSondeChecks, etc.) are now in toDbJson()
      // --- END: MODIFIED BLOCK ---

      // This method is added to LocalStorageService
      await _localStorageService.updateEquipmentMaintenanceLog(updatedLogData);
    } else {
      // This is a new log
      // This method is added to LocalStorageService
      await _localStorageService.saveEquipmentMaintenanceData(data, serverName: serverName);
    }

    final logData = {
      'submission_id': data.reportId ?? fileTimestamp,
      'module': 'marine',
      'type': 'Equipment Maintenance',
      'status': data.submissionStatus,
      'message': data.submissionMessage,
      'report_id': data.reportId,
      'created_at': DateTime.now().toIso8601String(),
      // --- START: MODIFIED LINE ---
      'form_data': jsonEncode(data.toDbJson()), // Log the full DbJson
      // --- END: MODIFIED LINE ---
      'image_data': null, // No images
      'server_name': serverName,
      'api_status': jsonEncode(apiResult),
      'ftp_status': null, // No FTP
    };
    await _dbHelper.saveSubmissionLog(logData);
  }

  /// Fetches previous maintenance logs to populate the form
  /// THIS METHOD IS UNCHANGED as it's a simple GET request.
  Future<Map<String, dynamic>> getPreviousMaintenanceLogs({
    required AuthProvider authProvider,
  }) async {
    try {
      return await _apiService.marine.getPreviousMaintenanceLogs();
    } on SessionExpiredException {
      final bool reloginSuccess = await authProvider.attemptSilentRelogin();
      if (reloginSuccess) {
        return await _apiService.marine.getPreviousMaintenanceLogs();
      } else {
        return {'success': false, 'message': 'Session expired. Please log in again.'};
      }
    } on SocketException {
      return {'success': false, 'message': 'Network error. Could not fetch previous records.'};
    } on TimeoutException {
      return {'success': false, 'message': 'Request timed out. Could not fetch previous records.'};
    } catch (e) {
      return {'success': false, 'message': 'An unexpected error occurred: $e'};
    }
  }
}