package com.grigowashere.aismap;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.util.Printer;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.view.ViewGroup;
import android.graphics.Color;
import android.view.WindowManager;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.material.bottomsheet.BottomSheetDialog;

import com.grigowashere.aismap.controllers.AppController;
import com.grigowashere.aismap.controllers.MapController;
import com.grigowashere.aismap.controllers.VesselPathController;
import com.grigowashere.aismap.maps.MapInterface;
import com.grigowashere.aismap.models.Vessel;
import com.grigowashere.aismap.models.AISVessel;
import com.grigowashere.aismap.sensors.CompassSensor;
import com.grigowashere.aismap.view.CompassView;
import com.grigowashere.aismap.view.CoordinatesDockWidget;
import com.grigowashere.aismap.view.BaseDockWidget;
import com.grigowashere.aismap.utils.SettingsManager;
import com.grigowashere.aismap.utils.LogSender;
import com.grigowashere.aismap.utils.MIDToCountry;
import com.grigowashere.aismap.ui.UIRenderingCoordinator;
import com.grigowashere.aismap.ui.UIDataChangeNotifier;
// import com.yandex.mapkit.mapview.MapView;
import org.maplibre.android.maps.MapView;
import org.maplibre.android.MapLibre;
import java.util.List;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    
    private static final String TAG = "MainActivity";
    private static final int PERMISSION_REQUEST_CODE = 1001;
    private static final int SETTINGS_REQUEST_CODE = 1002;
    private static final int NOTIFICATION_PERMISSION_REQUEST_CODE = 1003;
    
    // Статическая переменная для отслеживания инициализации Яндекс.Карт
    private static boolean isYandexMapsInitialized = false;
    
    private AppController appController;
    private MapController mapController;
    private MapInterface mapInterface;
    private UIRenderingCoordinator uiCoordinator;
    private MapView mapView;
    private SettingsManager settingsManager;
    
    private Button btnCenterOnVessel;
    private Button btnMapOrientation;
    private Button btnSettings;
    private Button btnAisTargets;
    private LinearLayout controlPanel;
    private CompassView compassView;
    private CompassSensor compassSensor;
    private CoordinatesDockWidget coordinatesWidget;
    
    // Троттлинг для UI обновлений
    private android.os.Handler uiThrottleHandler;
    private Runnable compassUpdateRunnable;
    private Runnable coordinatesUpdateRunnable;
    private Vessel lastCompassVessel;
    private Vessel lastCoordinatesVessel;
    private static final long UI_UPDATE_THROTTLE_MS = 200; // 5 FPS максимум
    private TextView tvGpsAge;
    private TextView tvAisAge;
    private android.os.Handler messageAgeHandler;
    private Runnable messageAgeRunnable;
    
    
    // BottomSheet для отображения информации о нашем судне
    private BottomSheetDialog ownVesselBottomSheet;
    private View bottomSheetView;
    
    // BottomSheet для отображения информации об AIS судне
    private BottomSheetDialog aisVesselBottomSheet;
    private View aisBottomSheetView;
    private AISVessel currentAISVessel; // Текущее AIS судно в BottomSheet
    private android.os.Handler timeUpdateHandler; // Handler для обновления времени
    private Runnable timeUpdateRunnable; // Runnable для обновления времени
    
    // Автоматическое обновление BottomSheet
    private android.os.Handler bottomSheetUpdateHandler; // Handler для обновления BottomSheet
    private Runnable bottomSheetUpdateRunnable; // Runnable для обновления BottomSheet
    private static final int BOTTOM_SHEET_UPDATE_INTERVAL = 1000; // Обновление каждую секунду

    // Отложенное центрирование из внешнего интента
    private Double pendingCenterLat = null;
    private Double pendingCenterLon = null;
    
    // Управление экраном
    private boolean keepScreenOn = true;
    
    // UI Watchdog для отслеживания зависаний
    private android.os.Handler uiWatchdogHandler;
    private Runnable uiWatchdogRunnable;
    private long lastUIUpdateTime = 0;
    private static final long UI_WATCHDOG_INTERVAL = 1000; // 1 секунда - быстрая диагностика
    private static final long UI_TIMEOUT = 3000; // 3 секунды без обновлений = зависание
    
    // Диагностика компаса
    private long lastCompassLogTime = 0;
    private long lastTouchLogTime = 0;
    private long lastKeyLogTime = 0;
    
    // Throttling для updateControlPanelPosition
    private android.os.Handler controlPanelUpdateHandler;
    private Runnable controlPanelUpdateRunnable;
    private boolean controlPanelUpdatePending = false;
    private static final long CONTROL_PANEL_UPDATE_DELAY = 200; // 200ms throttling
    private int controlPanelUpdateCount = 0; // Для диагностики
    private long lastControlPanelUpdateTime = 0;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Отключено: агрессивная диагностика StrictMode/Looper
        
        // Инициализация MapLibre перед созданием MapView
        try {
            MapLibre.getInstance(this);
        } catch (Exception e) {
            Log.e(TAG, "Ошибка инициализации MapLibre: " + e.getMessage(), e);
        }
        
        setContentView(R.layout.activity_main);
        
        initializeViews();
        initializeControllers();
        setupScreenManagement();
        setupUIWatchdog();
        // checkPermissions() будет вызван в onStart
    }

    // Отключено: принудительное bringToFront панели

    // Отключено: дополнительное логирование событий ввода
    
    private void initializeViews() {
        mapView = findViewById(R.id.map_view);
        btnCenterOnVessel = findViewById(R.id.btn_center_vessel);
        btnMapOrientation = findViewById(R.id.btn_map_orientation);
        btnSettings = findViewById(R.id.btn_settings);
        btnAisTargets = findViewById(R.id.btn_ais_targets);
        controlPanel = findViewById(R.id.control_panel);
        compassView = findViewById(R.id.compass_view);
        coordinatesWidget = findViewById(R.id.coordinates_widget);
        
        // Инициализируем троттлинг
        uiThrottleHandler = new android.os.Handler(android.os.Looper.getMainLooper());
        compassUpdateRunnable = () -> {
            if (compassView != null && lastCompassVessel != null) {
                compassView.setOurVessel(lastCompassVessel);
            }
        };
        coordinatesUpdateRunnable = () -> {
            if (coordinatesWidget != null && lastCoordinatesVessel != null) {
                coordinatesWidget.updateVessel(lastCoordinatesVessel);
            }
        };
        tvGpsAge = findViewById(R.id.tv_gps_age);
        tvAisAge = findViewById(R.id.tv_ais_age);
        
        // Инициализируем магнитный компас
        compassSensor = new CompassSensor(this);
        
        // Инициализируем throttling для updateControlPanelPosition
        setupControlPanelThrottling();
        
        initializeBottomSheet();
        setupButtonListeners();
        setupCompass();
        setupCoordinatesWidget();
        setupMessageAgesUpdater();
    }
    
    private void setupButtonListeners() {
        btnCenterOnVessel.setOnClickListener(v -> centerOnVessel());
        btnMapOrientation.setOnClickListener(v -> toggleMapOrientation());
        btnSettings.setOnClickListener(v -> showSettings());
        if (btnAisTargets != null) {
            btnAisTargets.setOnClickListener(v -> openAisTargets());
        }
        
        // Кнопка для показа информации о судне
//        Button btnShowVesselInfo = findViewById(R.id.btn_show_vessel_info);
//        if (btnShowVesselInfo != null) {
//            btnShowVesselInfo.setOnClickListener(v -> showOwnVesselBottomSheet());
//        }
    }
    
    private void setupCompass() {
        // Устанавливаем начальный азимут (например, север)
        compassView.setAzimuth(0);
        
        // Устанавливаем компас в dock-режим вверху экрана
        compassView.post(() -> {
            compassView.setDocked(true, true, 0, 0);
            compassView.invalidate(); // Принудительная отрисовка
        });
        
        // Настраиваем слушатель изменения размера док-виджета
        compassView.setOnDockResizeListener(newHeight -> {
            Log.d(TAG, "Compass dock height changed to: " + newHeight);
            // Обновляем позицию панели управления при любом изменении размера docked виджета
            updateControlPanelPosition();
        });
        
        // Настраиваем слушатель изменения состояния docked
        compassView.setOnDockStateChangeListener((isDocked, isTop) -> {
            Log.d(TAG, "Compass dock state changed: docked=" + isDocked + ", top=" + isTop);
            
            // Перепозиционируем все docked виджеты
            BaseDockWidget.repositionAllDockedWidgets((ViewGroup) compassView.getParent());
            
            updateControlPanelPosition();
        });
        //smt changed
        // Настраиваем магнитный компас
        if (compassSensor.isAvailable()) {
            compassSensor.startListening(new CompassSensor.CompassListener() {
        //check how git is working
                @Override
                public void onCompassChanged(float azimuth) {
                    // Диагностика: логируем каждые 10 секунд
                    long now = System.currentTimeMillis();
                    if (now - lastCompassLogTime > 10000) {
                        Log.d(TAG, "🧭 MainActivity: onCompassChanged получен, azimuth=" + azimuth);
                        lastCompassLogTime = now;
                    }
                    
                    // Обновляем компас в UI потоке
                    runOnUiThread(() -> {
                        // Диагностика: проверяем выполнение в UI потоке
                        if (now - lastCompassLogTime > 10000) {
                            Log.d(TAG, "🧭 MainActivity: runOnUiThread выполняется для компаса");
                        }
                        
                        compassView.setAzimuth(azimuth);
                        compassView.setMagneticCompass(azimuth);
                        
                        // Обновляем магнитный компас в модели нашего судна
                        if (appController != null) {
                            Vessel ourVessel = appController.getOwnVessel();
                            if (ourVessel != null) {
                                ourVessel.setMagneticCompass(azimuth);
                            }
                        }
                    });
                }
            });
            Log.d(TAG, "Magnetic compass started");
        } else {
            Log.w(TAG, "Magnetic compass not available");
        }
        
        // Принудительная отрисовка
        compassView.invalidate();
        
        // Инициализируем начальную позицию панели управления
        compassView.post(() -> {
            updateControlPanelPosition();
        });
    }
    
    private void setupCoordinatesWidget() {
        // Настраиваем слушатель изменения размера dock-виджета
        coordinatesWidget.setOnDockResizeListener(newHeight -> {
            Log.d(TAG, "Coordinates dock height changed to: " + newHeight);
            // Обновляем позицию панели управления при любом изменении размера docked виджета
            updateControlPanelPosition();
        });
        
        // Настраиваем слушатель изменения состояния docked
        coordinatesWidget.setOnDockStateChangeListener((isDocked, isTop) -> {
            Log.d(TAG, "Coordinates dock state changed: docked=" + isDocked + ", top=" + isTop);
            
            // Перепозиционируем все docked виджеты
            BaseDockWidget.repositionAllDockedWidgets((ViewGroup) coordinatesWidget.getParent());
            
            updateControlPanelPosition();
        });
        
        // Устанавливаем виджет координат в dock-режим внизу экрана
        coordinatesWidget.post(() -> {
            Log.d(TAG, "Setting coordinates widget to dock mode");
            coordinatesWidget.setDocked(true, false, 0, 0); // false = dock снизу
            coordinatesWidget.invalidate(); // Принудительная отрисовка
            
            // Принудительно обновляем виджет с тестовыми данными (в фоне)
            android.os.Handler bgHandler = new android.os.Handler(android.os.Looper.getMainLooper());
            bgHandler.post(() -> {
                try {
                    Vessel testVessel = new Vessel();
                    testVessel.setLatitude(55.7558);
                    testVessel.setLongitude(37.6176);
                    testVessel.setSpeed(5.5);
                    testVessel.setCourse(45.0);
                    testVessel.setAccuracy(3.0f);
                    coordinatesWidget.updateVessel(testVessel);
                    
                    // Используем throttled версию
                    updateControlPanelPositionThrottled();
                } catch (Exception e) {
                    Log.e(TAG, "Ошибка при инициализации тестового виджета: " + e.getMessage(), e);
                }
            });
        });
    }

    private void setupMessageAgesUpdater() {
        messageAgeHandler = new android.os.Handler(android.os.Looper.getMainLooper());
        messageAgeRunnable = new Runnable() {
            @Override
            public void run() {
                try {
                    if (appController != null) {
                        int gpsSec = appController.getSecondsSinceLastGPSMessage();
                        int aisSec = appController.getSecondsSinceLastAISMessage();
                        if (tvGpsAge != null) {
                            tvGpsAge.setText(gpsSec >= 0 ? ("GPS: " + gpsSec + " сек назад") : "GPS: --");
                            tvGpsAge.setTextColor(getAgeColor(gpsSec));
                        }
                        if (tvAisAge != null) {
                            tvAisAge.setText(aisSec >= 0 ? ("AIS: " + aisSec + " сек назад") : "AIS: --");
                            tvAisAge.setTextColor(getAgeColor(aisSec));
                        }
                    }
                } catch (Exception ignored) {}
                messageAgeHandler.postDelayed(this, 1000);
            }
        };
        // Стартуем после первичной инициализации
        messageAgeHandler.postDelayed(messageAgeRunnable, 1000);
    }

    private int getAgeColor(int seconds) {
        if (seconds < 0) {
            // Нет данных
            return Color.parseColor("#F44336"); // красный
        }
        if (seconds < 30) {
            return Color.parseColor("#4CAF50"); // зелёный
        } else if (seconds < 300) {
            return Color.parseColor("#FFC107"); // жёлтый
        } else {
            return Color.parseColor("#F44336"); // красный
        }
    }
    
    private void onUpdateCompass(float azimuth, List<AISVessel> nearbyVessels) {
        if (compassView != null) {
            compassView.setAzimuth(azimuth);
            compassView.updateNearbyVessels(nearbyVessels);
        }
    }
    
    /**
     * Инициализирует BottomSheet для отображения информации о нашем судне
     */
    private void initializeBottomSheet() {
        // Инициализация Handler для обновления времени
        timeUpdateHandler = new android.os.Handler(android.os.Looper.getMainLooper());
        timeUpdateRunnable = new Runnable() {
            @Override
            public void run() {
                if (currentAISVessel != null && aisVesselBottomSheet != null && aisVesselBottomSheet.isShowing()) {
                    updateAISTimeAgo();
                }
                // Планируем следующее обновление через 1 секунду
                timeUpdateHandler.postDelayed(this, 1000);
            }
        };
        
        // Инициализация Handler для автоматического обновления BottomSheet
        bottomSheetUpdateHandler = new android.os.Handler(android.os.Looper.getMainLooper());
        bottomSheetUpdateRunnable = new Runnable() {
            @Override
            public void run() {
                // Обновляем BottomSheet нашего судна, если он открыт
                if (ownVesselBottomSheet != null && ownVesselBottomSheet.isShowing()) {
                    updateBottomSheetUI();
                }
                
                // Обновляем AIS BottomSheet, если он открыт
                if (aisVesselBottomSheet != null && aisVesselBottomSheet.isShowing() && currentAISVessel != null) {
                    updateAISBottomSheetUI(currentAISVessel);
                }
                
                // Планируем следующее обновление
                bottomSheetUpdateHandler.postDelayed(this, BOTTOM_SHEET_UPDATE_INTERVAL);
            }
        };
        
        // Инициализация BottomSheet для нашего судна
        ownVesselBottomSheet = new BottomSheetDialog(this);
        bottomSheetView = getLayoutInflater().inflate(R.layout.bottom_sheet_own_vessel, null);
        ownVesselBottomSheet.setContentView(bottomSheetView);
        
        // Настраиваем кнопку закрытия
        ImageButton btnClose = bottomSheetView.findViewById(R.id.btn_close_bottom_sheet);
        btnClose.setOnClickListener(v -> {
            ownVesselBottomSheet.dismiss();
            // Восстанавливаем обработчики кликов после закрытия
            restoreMarkerClickListeners();
            // Останавливаем автоматическое обновление
            stopBottomSheetAutoUpdate();
        });
        
        // Настраиваем поведение BottomSheet
        ownVesselBottomSheet.setCanceledOnTouchOutside(true);
        ownVesselBottomSheet.setCancelable(true);
        
        // Добавляем слушатель закрытия BottomSheet
        ownVesselBottomSheet.setOnDismissListener(dialog -> {
            // Восстанавливаем обработчики кликов после закрытия
            restoreMarkerClickListeners();
            // Останавливаем автоматическое обновление
            stopBottomSheetAutoUpdate();
        });
        
        // Инициализация BottomSheet для AIS судов
        aisVesselBottomSheet = new BottomSheetDialog(this);
        aisBottomSheetView = getLayoutInflater().inflate(R.layout.bottom_sheet_ais_vessel, null);
        aisVesselBottomSheet.setContentView(aisBottomSheetView);
        
        // Настраиваем кнопку закрытия для AIS BottomSheet
        ImageButton btnCloseAIS = aisBottomSheetView.findViewById(R.id.btn_close_ais_bottom_sheet);
        btnCloseAIS.setOnClickListener(v -> {
            aisVesselBottomSheet.dismiss();
            stopTimeUpdate();
            // Восстанавливаем обработчики кликов после закрытия
            restoreMarkerClickListeners();
            // Останавливаем автоматическое обновление
            stopBottomSheetAutoUpdate();
        });
        
        // Настраиваем поведение AIS BottomSheet
        aisVesselBottomSheet.setCanceledOnTouchOutside(true);
        aisVesselBottomSheet.setCancelable(true);
        
        // Добавляем слушатель закрытия BottomSheet
        aisVesselBottomSheet.setOnDismissListener(dialog -> {
            stopTimeUpdate();
            // Восстанавливаем обработчики кликов после закрытия
            restoreMarkerClickListeners();
            // Останавливаем автоматическое обновление
            stopBottomSheetAutoUpdate();
        });
    }
    
    /**
     * Настраивает управление экраном
     */
    private void setupScreenManagement() {
        // Загружаем настройку из SettingsManager
        if (settingsManager != null) {
            keepScreenOn = settingsManager.isKeepScreenOnEnabled();
        }
        
        // Применяем настройку
        setKeepScreenOn(keepScreenOn);
        
        Log.i(TAG, "Управление экраном настроено: keepScreenOn=" + keepScreenOn);
    }
    
    /**
     * Настраивает UI watchdog для отслеживания зависаний
     */
    private void setupUIWatchdog() {
        uiWatchdogHandler = new android.os.Handler(android.os.Looper.getMainLooper());
        uiWatchdogRunnable = new Runnable() {
            @Override
            public void run() {
                long currentTime = System.currentTimeMillis();
                long timeSinceLastUpdate = currentTime - lastUIUpdateTime;
                
                if (timeSinceLastUpdate > UI_TIMEOUT) {
                    Log.e(TAG, "🚨 UI WATCHDOG: UI ЗАВИС! Последнее обновление " + 
                          (timeSinceLastUpdate / 1000) + " секунд назад");
                    Log.e(TAG, "🚨 UI WATCHDOG: Время зависания: " + new java.util.Date(currentTime));
                    Log.e(TAG, "🚨 UI WATCHDOG: Thread: " + Thread.currentThread().getName());
                    // Дамп стека главного потока и нескольких рабочих потоков
                    dumpThreadStacksForDiagnostics();
                    
                    // Попытка восстановления
                    tryRecoverFromUIHang();
                } else {
                    // Логируем каждые 10 секунд для мониторинга
                    if (timeSinceLastUpdate > 0 && (timeSinceLastUpdate / 1000) % 10 == 0) {
                        Log.i(TAG, "✅ UI WATCHDOG: UI активен, последнее обновление " + 
                              (timeSinceLastUpdate / 1000) + " секунд назад");
                    }
                }
                
                // Планируем следующую проверку
                uiWatchdogHandler.postDelayed(this, UI_WATCHDOG_INTERVAL);
            }
        };
        
        // Запускаем watchdog
        lastUIUpdateTime = System.currentTimeMillis();
        uiWatchdogHandler.postDelayed(uiWatchdogRunnable, UI_WATCHDOG_INTERVAL);
        Log.i(TAG, "UI watchdog запущен");
    }
    
    /**
     * Обновляет время последней активности UI
     */
    private void updateUIActivity() {
        long now = System.currentTimeMillis();
        long timeSinceLastUpdate = now - lastUIUpdateTime;
        lastUIUpdateTime = now;
        
        // Логируем если прошло больше 2 секунд с последнего обновления
        if (timeSinceLastUpdate > 2000) {
            Log.w(TAG, "⚠️ UI WATCHDOG: Долгая пауза в UI обновлениях: " + (timeSinceLastUpdate / 1000) + " сек");
        }
    }
    
    /**
     * Попытка восстановления после зависания UI
     */
    private void tryRecoverFromUIHang() {
        Log.w(TAG, "UI WATCHDOG: Попытка восстановления...");
        
        try {
            // Диагностика: проверяем состояние handler'ов
            boolean watchdogActive = uiWatchdogHandler != null && uiWatchdogRunnable != null;
            boolean messageAgeActive = messageAgeHandler != null && messageAgeRunnable != null;
            boolean bottomSheetActive = bottomSheetUpdateHandler != null && bottomSheetUpdateRunnable != null;
            boolean controlPanelActive = controlPanelUpdateHandler != null && controlPanelUpdateRunnable != null;
            
            Log.i(TAG, "UI WATCHDOG: Handler status - " +
                      "watchdog=" + watchdogActive + 
                      ", messageAge=" + messageAgeActive +
                      ", bottomSheet=" + bottomSheetActive +
                      ", controlPanel=" + controlPanelActive +
                      ", controlPanelCount=" + controlPanelUpdateCount);
            
            // Принудительная сборка мусора
            System.gc();
            
            // Проверяем состояние основных компонентов
            if (mapInterface == null) {
                Log.w(TAG, "UI WATCHDOG: mapInterface == null, переинициализируем карту");
                // Можно попробовать переинициализировать карту
            }
            
            if (appController == null) {
                Log.w(TAG, "UI WATCHDOG: appController == null");
            }
            
            // Если слишком много обновлений control panel, попробуем остановить
            if (controlPanelUpdateCount > 50) {
                Log.w(TAG, "UI WATCHDOG: Слишком много обновлений control panel (" + controlPanelUpdateCount + "/10сек), принудительно останавливаем");
                if (controlPanelUpdateHandler != null) {
                    controlPanelUpdateHandler.removeCallbacks(controlPanelUpdateRunnable);
                    controlPanelUpdatePending = false;
                    controlPanelUpdateCount = 0;
                }
            }
            
            // Обновляем время активности
            updateUIActivity();
            
            Log.i(TAG, "UI WATCHDOG: Восстановление завершено");
            
        } catch (Exception e) {
            Log.e(TAG, "UI WATCHDOG: Ошибка при восстановлении: " + e.getMessage(), e);
        }
    }
    
    /**
     * Диагностический дамп стеков главного и рабочих потоков
     */
    private void dumpThreadStacksForDiagnostics() {
        try {
            java.util.Map<Thread, StackTraceElement[]> all = Thread.getAllStackTraces();
            Thread main = Looper.getMainLooper().getThread();
            // Сначала главный поток
            if (main != null) {
                StackTraceElement[] st = all.get(main);
                Log.e(TAG, "===== MAIN THREAD STACK TRACE =====");
                if (st != null) {
                    for (StackTraceElement e : st) {
                        Log.e(TAG, "  at " + e.toString());
                    }
                }
            }
            // Затем несколько самых активных потоков по имени
            String[] interesting = new String[] {"AsyncTask", "RenderThread", "OkHttp", "GLThread", "pool-", "DefaultDispatcher"};
            for (java.util.Map.Entry<Thread, StackTraceElement[]> entry : all.entrySet()) {
                Thread t = entry.getKey();
                if (t == main) continue;
                String name = t.getName();
                boolean match = false;
                for (String key : interesting) {
                    if (name.contains(key)) { match = true; break; }
                }
                if (!match) continue;
                Log.w(TAG, "===== THREAD: " + name + " (" + t.getState() + ") =====");
                StackTraceElement[] st = entry.getValue();
                if (st != null) {
                    int count = 0;
                    for (StackTraceElement e : st) {
                        Log.w(TAG, "  at " + e.toString());
                        if (++count > 50) break; // ограничим длину
                    }
                }
            }
        } catch (Throwable t) {
            Log.e(TAG, "Ошибка дампа стеков: " + t.getMessage(), t);
        }
    }
    
    /**
     * Настраивает throttling для updateControlPanelPosition
     */
    private void setupControlPanelThrottling() {
        controlPanelUpdateHandler = new android.os.Handler(android.os.Looper.getMainLooper());
        controlPanelUpdateRunnable = () -> {
            controlPanelUpdatePending = false;
            updateControlPanelPositionSafe();
        };
    }
    
    /**
     * Безопасное обновление позиции панели управления с throttling
     */
    private void updateControlPanelPositionThrottled() {
        if (!controlPanelUpdatePending) {
            controlPanelUpdatePending = true;
            controlPanelUpdateHandler.removeCallbacks(controlPanelUpdateRunnable);
            controlPanelUpdateHandler.postDelayed(controlPanelUpdateRunnable, CONTROL_PANEL_UPDATE_DELAY);
        }
    }
    
    /**
     * Устанавливает режим работы экрана
     */
    private void setKeepScreenOn(boolean enabled) {
        if (enabled) {
            // Включаем режим "не засыпать"
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            Log.i(TAG, "Экран настроен на постоянную работу");
        } else {
            // Выключаем режим "не засыпать"
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            Log.i(TAG, "Экран настроен на обычный режим (может засыпать)");
        }
    }
    
    /**
     * Переключает режим работы экрана
     */
    public void toggleKeepScreenOn() {
        keepScreenOn = !keepScreenOn;
        setKeepScreenOn(keepScreenOn);
        
        // Сохраняем настройку
        if (settingsManager != null) {
            settingsManager.setKeepScreenOnEnabled(keepScreenOn);
        }
        
        String message = keepScreenOn ? "Экран будет оставаться включенным" : "Экран может засыпать";
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
        
        Log.i(TAG, "Режим экрана переключен: keepScreenOn=" + keepScreenOn);
    }
    
    private void initializeControllers() {
        // Инициализация менеджера настроек
        settingsManager = new SettingsManager(this);
        
        // Инициализация главного контроллера
        appController = new AppController(this);
        
        // Инициализация контроллера карты
        mapController = new MapController(this);
        
        // Устанавливаем callback для обновления UI

        // Запускаем Foreground Service для фоновых обновлений AIS/GPS
        startForegroundService();
        appController.setUIUpdateCallback(new AppController.ExtendedUIUpdateCallback() {
            @Override
            public void onVesselPositionUpdated(Vessel vessel) {
                updateUIActivity(); // Обновляем watchdog
                updateVesselPositionUI(vessel);
                
                // Троттлинг обновлений компаса
                lastCompassVessel = vessel;
                uiThrottleHandler.removeCallbacks(compassUpdateRunnable);
                uiThrottleHandler.postDelayed(compassUpdateRunnable, UI_UPDATE_THROTTLE_MS);
            }
            
            @Override
            public void onGPSQualityUpdated(Vessel vessel) {
                updateGPSQualityUI(vessel);
            }
            
            @Override
            public void onShowOwnVesselBottomSheet() {
                Log.i(TAG, "onShowOwnVesselBottomSheet callback получен в MainActivity");
                showOwnVesselBottomSheet();
            }
            
            @Override
            public void onShowAISVesselInfo(AISVessel vessel) {
                showAISVesselBottomSheet(vessel);
            }
            
            @Override
            public void onUpdateCompass(float azimuth, List<AISVessel> nearbyVessels) {
                updateUIActivity(); // Обновляем watchdog
                if (compassView != null) {
                    compassView.setAzimuth(azimuth);
                    compassView.updateNearbyVessels(nearbyVessels);
                }
            }
        });
    }
    
    private void startControllers() {
        // Загружаем настройки и применяем их
        applySettings();
        
        // Запускаем все слушатели
        appController.startAllListeners();
    }
    
    /**
     * Обновляет статус в UI
     */
    private void updateStatusUI() {
        // Обновляем статус в UI
//        TextView tvStatus = findViewById(R.id.tv_status);
//        TextView tvAisCount = findViewById(R.id.tv_ais_count);
//
//        if (tvStatus != null) {
//            tvStatus.setText("Статус: GPS активен, UDP готов");
//        }
//
//        if (tvAisCount != null) {
//            tvAisCount.setText("AIS суда: 0");
//        }
    }
    
    /**
     * Обновляет позицию судна в UI
     */
    private void updateVesselPositionUI(Vessel vessel) {
        if (isFinishing() || isDestroyed()) return;
        
        runOnUiThread(() -> {
            try {
                updateUIActivity(); // Обновляем watchdog
                
                if (vessel == null) return;
                
                // Троттлинг обновлений координатного виджета
                lastCoordinatesVessel = vessel;
                uiThrottleHandler.removeCallbacks(coordinatesUpdateRunnable);
                uiThrottleHandler.postDelayed(coordinatesUpdateRunnable, UI_UPDATE_THROTTLE_MS);
                
                // Обновляем BottomSheet, если он открыт
                if (ownVesselBottomSheet != null && ownVesselBottomSheet.isShowing()) {
                    updateBottomSheetUI();
                }
            } catch (Exception e) {
                Log.e(TAG, "Ошибка в updateVesselPositionUI: " + e.getMessage(), e);
            }
        });
    }
    
    /**
     * Обновляет качество GPS в UI
     */
    private void updateGPSQualityUI(Vessel vessel) {
        if (isFinishing() || isDestroyed()) return;
        
        runOnUiThread(() -> {
            try {
                updateUIActivity(); // Обновляем watchdog
                
                if (vessel == null) return;
                
                // Обновляем BottomSheet, если он открыт
                if (ownVesselBottomSheet != null && ownVesselBottomSheet.isShowing()) {
                    updateBottomSheetUI();
                }
            } catch (Exception e) {
                Log.e(TAG, "Ошибка в updateGPSQualityUI: " + e.getMessage(), e);
            }
        });
    }
    
    private void toggleUDP() {
        boolean isEnabled = appController.isUDPEnabled();
        
        if (isEnabled) {
            appController.setUDPEnabled(false);
            Toast.makeText(this, "UDP слушатель отключен", Toast.LENGTH_SHORT).show();
        } else {
            appController.setUDPEnabled(true);
            Toast.makeText(this, "UDP слушатель включен", Toast.LENGTH_SHORT).show();
        }
        
        // Обновляем заголовок меню
        invalidateOptionsMenu();
    }
    
    private void toggleGPS() {
        boolean isEnabled = appController.isAndroidNMEAEnabled();
        
        if (isEnabled) {
            appController.setAndroidNMEAEnabled(false);
            Toast.makeText(this, "GPS слушатель отключен", Toast.LENGTH_SHORT).show();
        } else {
            appController.setAndroidNMEAEnabled(true);
            Toast.makeText(this, "GPS слушатель включен", Toast.LENGTH_SHORT).show();
        }
        
        // Обновляем заголовок меню
        invalidateOptionsMenu();
    }
    
    private void centerOnVessel() {
        appController.centerOnOwnVessel();
        Toast.makeText(this, "Карта центрирована на судне", Toast.LENGTH_SHORT).show();
    }
    
    private void toggleMapOrientation() {
        // TODO: Реализовать переключение ориентации карты
        // Состояния: север, курс, компас
        Toast.makeText(this, "Переключение ориентации карты (в разработке)", Toast.LENGTH_SHORT).show();
    }
    
    private void togglePathTracking() {
        boolean currentState = settingsManager.isPathTrackingEnabled();
        boolean newState = !currentState;
        
        settingsManager.setPathTrackingEnabled(newState);
        
        // Обновляем состояние в карте
        if (mapInterface instanceof com.grigowashere.aismap.maps.YandexMapImpl) {
            ((com.grigowashere.aismap.maps.YandexMapImpl) mapInterface).setPathTrackingEnabled(newState);
        }
        
        String message = newState ? "Отслеживание путей включено" : "Отслеживание путей выключено";
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
        
        // Обновляем меню
        invalidateOptionsMenu();
    }
    
    /**
     * Очищает трекер пути собственного судна
     */
    private void clearVesselPath() {
        try {
            Log.i(TAG, "clearVesselPath() вызван");
            
            if (mapInterface != null) {
                Log.i(TAG, "Очищаем путь в карте");
                // Очищаем путь в карте
                mapInterface.clearVesselPath();
                
                // Также очищаем VesselPathController если он используется в AppController
                if (appController != null) {
                    Log.i(TAG, "Очищаем VesselPathController в AppController");
                    appController.clearVesselPath();
                } else {
                    Log.w(TAG, "AppController is null, не можем очистить VesselPathController");
                }
                
                Toast.makeText(this, "Трекер пути очищен", Toast.LENGTH_SHORT).show();
                Log.i(TAG, "Трекер пути собственного судна очищен");
            } else {
                Toast.makeText(this, "Карта не инициализирована", Toast.LENGTH_SHORT).show();
                Log.w(TAG, "Попытка очистки пути при неинициализированной карте");
            }
        } catch (Exception e) {
            Log.e(TAG, "Ошибка при очистке пути: " + e.getMessage(), e);
            Toast.makeText(this, "Ошибка при очистке пути", Toast.LENGTH_SHORT).show();
        }
    }
    
    private void showSettings() {
        Intent intent = new Intent(this, SettingsActivity.class);
        startActivityForResult(intent, SETTINGS_REQUEST_CODE);
    }

    private void openAisTargets() {
        Intent intent = new Intent(this, AisTargetsActivity.class);
        startActivity(intent);
    }
    
    /**
     * Обновляет позицию панели управления с throttling
     */
    private void updateControlPanelPosition() {
        updateControlPanelPositionThrottled();
    }
    
    /**
     * Безопасное обновление позиции панели управления (вызывается через throttling)
     */
    private void updateControlPanelPositionSafe() {
        if (controlPanel == null) return;
        
        try {
            updateUIActivity(); // Обновляем watchdog
            
            // Диагностика: считаем количество обновлений
            controlPanelUpdateCount++;
            long now = System.currentTimeMillis();
            if (now - lastControlPanelUpdateTime > 10000) { // каждые 10 секунд
                Log.d(TAG, "Control panel updates count: " + controlPanelUpdateCount + " за последние 10 сек");
                controlPanelUpdateCount = 0;
                lastControlPanelUpdateTime = now;
            }
            
            // Получаем параметры layout
            android.widget.RelativeLayout.LayoutParams params = 
                (android.widget.RelativeLayout.LayoutParams) controlPanel.getLayoutParams();
            if (params == null) return;
                
            int defaultMargin = dpToPx(16);
            int topMargin = defaultMargin;
            int bottomMargin = defaultMargin;
            
            // Проверяем compassView
            int compassHeight = 0;
            if (compassView != null && compassView.isDocked()) {
                compassHeight = compassView.getHeight();
                if (compassHeight <= 0) return; // Избегаем 0 размера, который может вызвать перестройку
            
                if (compassView.isDockTop()) {
                    topMargin = compassHeight + dpToPx(8);
                } else {
                    bottomMargin = compassHeight + dpToPx(8);
                }
            }
            
            // Проверяем coordinatesWidget
            int coordinatesHeight = 0;
            if (coordinatesWidget != null && coordinatesWidget.isDocked()) {
                coordinatesHeight = coordinatesWidget.getHeight();
                if (coordinatesHeight <= 0) return; // Избегаем 0 размера
                
                if (coordinatesWidget.isDockTop()) {
                    topMargin = Math.max(topMargin, coordinatesHeight + dpToPx(8));
                } else {
                    bottomMargin = Math.max(bottomMargin, coordinatesHeight + dpToPx(8));
                }
            }
            
            // Применяем изменения только если они отличаются от текущих
            if (params.topMargin != topMargin || params.bottomMargin != bottomMargin) {
                params.topMargin = topMargin;
                params.bottomMargin = bottomMargin;
                controlPanel.setLayoutParams(params);
                
                // Минимальное логирование в production
                Log.d(TAG, "Control panel updated: top=" + topMargin + ", bottom=" + bottomMargin);
            }
            
        } catch (Exception e) {
            Log.e(TAG, "Ошибка при обновлении позиции панели управления: " + e.getMessage(), e);
        }
    }
    

    
    private void clearAIS() {
        appController.clearAISVessels();
        Toast.makeText(this, "AIS суда очищены", Toast.LENGTH_SHORT).show();
    }
    
    /**
     * Конвертирует dp в px
     */
    private int dpToPx(int dp) {
        return (int) (dp * getResources().getDisplayMetrics().density);
    }
    
    @Override
    protected void onStart() {
        super.onStart();
        
        // MapLibre lifecycle
        if (mapView != null) {
            mapView.onStart();
        }
        
        // Запускаем карту через контроллер
        if (mapController != null) {
            Log.i(TAG, "Запускаем карту...");
            mapController.startMap();
            
            // Инициализируем карту
            Log.i(TAG, "Инициализируем карту...");
            mapInterface = mapController.initializeMapLibre(mapView);
            Log.i(TAG, "mapInterface получен: " + (mapInterface != null ? "успешно" : "null"));
            
            // Устанавливаем интерфейс карты в главный контроллер
            if (mapInterface != null) {
                // Сначала создаем UI Coordinator
                uiCoordinator = new UIRenderingCoordinator(mapInterface);
                Log.i(TAG, "UIRenderingCoordinator создам");
                
                // Устанавливаем UI Coordinator как notifier для AppController ДО setMapInterface
                appController.setUIDataChangeNotifier(uiCoordinator);
                Log.i(TAG, "UIDataChangeNotifier установлен в AppController");
                
                // Теперь устанавливаем mapInterface - восстановление будет через uiDataNotifier
                Log.i(TAG, "Устанавливаем mapInterface в AppController...");
                appController.setMapInterface(mapInterface);
                Log.i(TAG, "mapInterface установлен в AppController");
                
                // Принудительно выполняем pending операции для восстановления данных
                uiCoordinator.flushPendingOperations();
                Log.i(TAG, "Pending операции выполнены для восстановления маркеров");
                
                
                // Инициализируем курсор согласно настройкам
                initializeCursor();
                
                // Устанавливаем VesselPathController и AppController в MapController
                if (appController != null) {
                    VesselPathController pathController = appController.getPathController();
                    if (pathController != null) {
                        mapController.setVesselPathController(pathController);
                        Log.i(TAG, "VesselPathController установлен в MapController");
                    }
                    mapController.setAppController(appController);
                    Log.i(TAG, "AppController установлен в MapController");
                }
                
                mapInterface.initialize();
                Log.i(TAG, "Карта инициализирована");

                // Применяем отложенное центрирование, если было
                applyPendingCenterIfAny();
                
                // Отслеживание путей для MapLibre будет добавлено позже
                
                // Проверяем, что все настроено правильно
                Log.i(TAG, "Проверяем настройку карты...");
                
                // Дополнительная проверка обработчиков кликов
                Log.i(TAG, "Проверяем обработчики кликов...");
                if (mapInterface instanceof com.grigowashere.aismap.maps.YandexMapImpl) {
                    com.grigowashere.aismap.maps.YandexMapImpl yandexMap = (com.grigowashere.aismap.maps.YandexMapImpl) mapInterface;
                    yandexMap.refreshMarkerClickListeners();
                    Log.i(TAG, "Обработчики кликов обновлены");
                }
            } else {
                Log.e(TAG, "Не удалось получить mapInterface!");
            }
        }
        
        // Обрабатываем возможный интент центрирования
        handleCenterIntentIfAny(getIntent());

        // Проверяем разрешения и запускаем контроллеры
        checkPermissions();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        handleCenterIntentIfAny(intent);
    }

    private void handleCenterIntentIfAny(Intent intent) {
        if (intent == null) return;
        if (intent.hasExtra("center_lat") && intent.hasExtra("center_lon")) {
            double lat = intent.getDoubleExtra("center_lat", 0);
            double lon = intent.getDoubleExtra("center_lon", 0);
            Log.i(TAG, "Получен интент центрирования: lat=" + lat + ", lon=" + lon);
            if (lat != 0 || lon != 0) {
                if (mapInterface != null) {
                    Log.i(TAG, "Центрируем карту немедленно");
                    mapInterface.centerOnPosition(lat, lon);
                } else {
                    // Сохраняем для применения после инициализации карты
                    Log.i(TAG, "Сохраняем координаты для отложенного центрирования");
                    pendingCenterLat = lat;
                    pendingCenterLon = lon;
                }
            }
            // Сбрасываем, чтобы не повторялось при поворотах
            intent.removeExtra("center_lat");
            intent.removeExtra("center_lon");
            intent.removeExtra("center_mmsi");
        }
    }

    private void applyPendingCenterIfAny() {
        if (mapInterface == null) return;
        if (pendingCenterLat != null && pendingCenterLon != null) {
            Log.i(TAG, "Применяем отложенное центрирование: lat=" + pendingCenterLat + ", lon=" + pendingCenterLon);
            mapInterface.centerOnPosition(pendingCenterLat, pendingCenterLon);
            pendingCenterLat = null;
            pendingCenterLon = null;
        }
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        
        // MapLibre lifecycle
        if (mapView != null) {
            mapView.onStop();
        }
        
        // Останавливаем карту
        if (mapInterface != null) {
            mapInterface.cleanup();
        }
        
        // Очищаем UI Coordinator
        if (uiCoordinator != null) {
            uiCoordinator.cleanup();
        }
        
        // Очищаем троттлинг
        if (uiThrottleHandler != null) {
            uiThrottleHandler.removeCallbacks(compassUpdateRunnable);
            uiThrottleHandler.removeCallbacks(coordinatesUpdateRunnable);
        }
        
        // Не останавливаем слушатели здесь, чтобы UDP продолжал работать в фоне
        // if (appController != null) {
        // 	appController.stopAllListeners();
        // }
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        
        // MapLibre lifecycle
        if (mapView != null) {
            mapView.onDestroy();
        }
        
        // Останавливаем обновление времени
        stopTimeUpdate();
        
        // Останавливаем автоматическое обновление BottomSheet
        stopBottomSheetAutoUpdate();
        
        // Останавливаем обновление возраста сообщений
        if (messageAgeHandler != null && messageAgeRunnable != null) {
            messageAgeHandler.removeCallbacks(messageAgeRunnable);
            Log.i(TAG, "messageAgeHandler остановлен");
        }
        
        // Останавливаем UI watchdog
        if (uiWatchdogHandler != null && uiWatchdogRunnable != null) {
            uiWatchdogHandler.removeCallbacks(uiWatchdogRunnable);
            Log.i(TAG, "UI watchdog остановлен");
        }
        
        // Останавливаем throttling handler для control panel
        if (controlPanelUpdateHandler != null && controlPanelUpdateRunnable != null) {
            controlPanelUpdateHandler.removeCallbacks(controlPanelUpdateRunnable);
            Log.i(TAG, "Control panel throttling остановлен");
        }
        
        // Останавливаем магнитный компас
        if (compassSensor != null) {
            compassSensor.stopListening();
        }
        
        // Освобождаем ресурсы
        if (appController != null) {
            // Очищаем callback чтобы избежать утечки памяти
            appController.setUIUpdateCallback(null);
            appController.cleanup();
        }
        
        if (mapController != null) {
            mapController.cleanup();
        }
        
        // Останавливаем LogSender
        LogSender.shutdown();
        
        // Останавливаем форграунд сервис
        stopForegroundService();
    }
    
    @Override
    public void onConfigurationChanged(android.content.res.Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        
        // Обрабатываем изменения конфигурации (например, поворот экрана)
        if (mapInterface != null) {
            // Можно добавить логику для обработки изменений конфигурации карты
        }
    }
    
    /**
     * Проверяет необходимые разрешения
     */
    private void checkPermissions() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
                != PackageManager.PERMISSION_GRANTED) {
            
            ActivityCompat.requestPermissions(this, 
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
                PERMISSION_REQUEST_CODE);
        } else {
            // Разрешения уже получены, запускаем контроллеры
            startControllers();
        }
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        
        if (requestCode == PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Разрешение получено, запускаем контроллеры
                startControllers();
            } else {
                // Разрешение не получено
                Toast.makeText(this, "Для работы приложения необходимо разрешение на доступ к местоположению", 
                    Toast.LENGTH_LONG).show();
            }
        } else if (requestCode == NOTIFICATION_PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Разрешение на уведомления получено, запускаем сервис
                android.util.Log.i(TAG, "Разрешение на уведомления получено");
                startForegroundService();
            } else {
                // Разрешение на уведомления не получено
                android.util.Log.w(TAG, "Разрешение на уведомления не получено");
                Toast.makeText(this, "Для работы в фоне необходимо разрешение на уведомления", 
                    Toast.LENGTH_LONG).show();
            }
        }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        
        if (requestCode == SETTINGS_REQUEST_CODE) {
            if (resultCode == RESULT_OK && data != null) {
                boolean settingsChanged = data.getBooleanExtra("settings_changed", false);
                boolean needsRestart = data.getBooleanExtra("needs_restart", false);
                boolean clearVesselPath = data.getBooleanExtra("clear_vessel_path", false);
                boolean cursorEnabled = data.getBooleanExtra("cursor_enabled", false);
                
                if (clearVesselPath) {
                    Log.i(TAG, "Запрошена очистка трекера пути");
                    clearVesselPath();
                }
                
                if (settingsChanged) {
                    Log.i(TAG, "Настройки изменены, применяем изменения");
                    
                    // Применяем настройки курсора
                    applyCursorSettings(cursorEnabled);
                    
                    if (needsRestart) {
                        Log.i(TAG, "Требуется перезапуск сервисов");
                        restartServices();
                    } else {
                        Log.i(TAG, "Применяем настройки без перезапуска");
                        applySettings();
                    }
                    
                    Toast.makeText(this, "Настройки применены", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
    
    // Меню
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return true;
    }
    
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // Обновляем состояние элементов меню
        MenuItem gpsItem = menu.findItem(R.id.menu_gps);
        MenuItem udpItem = menu.findItem(R.id.menu_udp);
        
        if (gpsItem != null) {
            gpsItem.setTitle(appController.isAndroidNMEAEnabled() ? "GPS ✓" : "GPS");
        }
        
        if (udpItem != null) {
            udpItem.setTitle(appController.isUDPEnabled() ? "UDP ✓" : "UDP");
        }
        
        MenuItem pathItem = menu.findItem(R.id.menu_path_tracking);
        if (pathItem != null) {
            boolean pathEnabled = settingsManager.isPathTrackingEnabled();
            pathItem.setTitle(pathEnabled ? "Пути ✓" : "Пути");
        }
        
        MenuItem screenItem = menu.findItem(R.id.menu_keep_screen_on);
        if (screenItem != null) {
            boolean screenEnabled = settingsManager.isKeepScreenOnEnabled();
            screenItem.setTitle(screenEnabled ? "Экран ✓" : "Экран");
        }
        
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        
        if (id == R.id.menu_gps) {
            toggleGPS();
            return true;
        } else if (id == R.id.menu_udp) {
            toggleUDP();
            return true;
        } else if (id == R.id.menu_clear_ais) {
            clearAIS();
            return true;
        } else if (id == R.id.menu_path_tracking) {
            togglePathTracking();
            return true;
        } else if (id == R.id.menu_service_test) {
            testForegroundService();
            return true;
        } else if (id == R.id.menu_keep_screen_on) {
            toggleKeepScreenOn();
            return true;
        }
        
        return super.onOptionsItemSelected(item);
    }
    
    /**
     * Показывает BottomSheet с информацией о нашем судне
     */
    private void showOwnVesselBottomSheet() {
        if (ownVesselBottomSheet != null && !ownVesselBottomSheet.isShowing()) {
            updateBottomSheetUI();
            ownVesselBottomSheet.show();
            
            // Запускаем автоматическое обновление BottomSheet
            startBottomSheetAutoUpdate();
        }
    }
    
    /**
     * Обновляет UI BottomSheet с актуальными данными
     */
    private void updateBottomSheetUI() {
        if (bottomSheetView == null) return;
        
        Vessel vessel = appController.getOwnVessel();
        if (vessel == null) return;
        
        // Убеждаемся, что обновление происходит в главном потоке
        runOnUiThread(() -> {
            if (bottomSheetView == null) return;
            
            Vessel currentVessel = appController.getOwnVessel();
            if (currentVessel == null) return;
            
            // Обновляем все поля в BottomSheet
            TextView tvStatus = bottomSheetView.findViewById(R.id.bottom_sheet_status);
            TextView tvPosition = bottomSheetView.findViewById(R.id.bottom_sheet_position);
            TextView tvCourse = bottomSheetView.findViewById(R.id.bottom_sheet_course);
            TextView tvSpeed = bottomSheetView.findViewById(R.id.bottom_sheet_speed);
            TextView tvAltitude = bottomSheetView.findViewById(R.id.bottom_sheet_altitude);
            TextView tvAccuracy = bottomSheetView.findViewById(R.id.bottom_sheet_accuracy);
            TextView tvGPSQuality = bottomSheetView.findViewById(R.id.bottom_sheet_gps_quality);
            TextView tvSatellites = bottomSheetView.findViewById(R.id.bottom_sheet_satellites);
            TextView tvDOP = bottomSheetView.findViewById(R.id.bottom_sheet_dop);
            TextView tvFixTime = bottomSheetView.findViewById(R.id.bottom_sheet_fix_time);
            TextView tvFixQuality = bottomSheetView.findViewById(R.id.bottom_sheet_fix_quality);
        
            // Статус
            if (tvStatus != null) {
                if (currentVessel.getLatitude() != 0 && currentVessel.getLongitude() != 0) {
                    tvStatus.setText("Статус: GPS активен, данные получены");
                } else {
                    tvStatus.setText("Статус: Ожидание GPS данных...");
                }
            }
            
            // Координаты
            if (tvPosition != null) {
                if (currentVessel.getLatitude() != 0 && currentVessel.getLongitude() != 0) {
                    String positionText = String.format("📍 Координаты: %.6f, %.6f", 
                        currentVessel.getLatitude(), currentVessel.getLongitude());
                    tvPosition.setText(positionText);
                } else {
                    tvPosition.setText("📍 Координаты: Не определены");
                }
            }
            
            // Курс
            if (tvCourse != null) {
                if (currentVessel.getCourse() > 0) {
                    String courseText = String.format("🧭 Курс: %.1f°", currentVessel.getCourse());
                    tvCourse.setText(courseText);
                } else {
                    tvCourse.setText("🧭 Курс: --°");
                }
            }
            
            // Скорость
            if (tvSpeed != null) {
                if (currentVessel.getSpeed() > 0) {
                    String speedText = String.format("⚡ Скорость: %.1f узлов", currentVessel.getSpeed());
                    tvSpeed.setText(speedText);
                } else {
                    tvSpeed.setText("⚡ Скорость: -- узлов");
                }
            }
            
            // Высота
            if (tvAltitude != null) {
                if (currentVessel.getAltitude() != 0) {
                    String altitudeText = String.format("🏔️ Высота: %.1f м", currentVessel.getAltitude());
                    tvAltitude.setText(altitudeText);
                } else {
                    tvAltitude.setText("🏔️ Высота: -- м");
                }
            }
            
            // Точность
            if (tvAccuracy != null) {
                if (currentVessel.getAccuracy() > 0) {
                    String accuracyText = String.format("🎯 Точность: %.1f м", currentVessel.getAccuracy());
                    tvAccuracy.setText(accuracyText);
                } else {
                    tvAccuracy.setText("🎯 Точность: -- м");
                }
            }
            
            // Качество GPS
            if (tvGPSQuality != null) {
                if (currentVessel.getGPSQualityDescription() != null) {
                    String qualityText = String.format("📊 Качество GPS: %s", currentVessel.getGPSQualityDescription());
                    tvGPSQuality.setText(qualityText);
                } else {
                    tvGPSQuality.setText("📊 Качество GPS: --");
                }
            }
            
            // Спутники
            if (tvSatellites != null) {
                if (currentVessel.getSatellites() > 0) {
                    String satellitesText = String.format("Спутники: %d/%d", 
                        currentVessel.getActiveSatellites(), currentVessel.getSatellites());
                    tvSatellites.setText(satellitesText);
                } else {
                    tvSatellites.setText("Спутники: --/--");
                }
            }
            
            // DOP
            if (tvDOP != null) {
                if (currentVessel.getPdop() > 0) {
                    String dopText = String.format("📈 DOP: PDOP=%.2f HDOP=%.2f VDOP=%.2f", 
                        currentVessel.getPdop(), currentVessel.getHdop(), currentVessel.getVdop());
                    tvDOP.setText(dopText);
                } else {
                    tvDOP.setText("📈 DOP: PDOP=-- HDOP=-- VDOP=--");
                }
            }
            
            // Время фикса
            if (tvFixTime != null) {
                if (currentVessel.getFixTime() > 0) {
                    java.util.Date fixDate = new java.util.Date(currentVessel.getFixTime());
                    String fixTimeText = String.format("🕐 Время фикса: %s", 
                        new java.text.SimpleDateFormat("HH:mm:ss", java.util.Locale.getDefault()).format(fixDate));
                    tvFixTime.setText(fixTimeText);
                } else {
                    tvFixTime.setText("🕐 Время фикса: --");
                }
            }
            
            // Качество фикса
            if (tvFixQuality != null) {
                if (currentVessel.getFixQuality() != null) {
                    String fixQualityText = String.format("🔒 Качество фикса: %s", currentVessel.getFixQuality());
                    tvFixQuality.setText(fixQualityText);
                } else {
                    tvFixQuality.setText("🔒 Качество фикса: --");
                }
            }
        });
    }
    
    /**
     * Показывает BottomSheet с информацией об AIS судне
     */
    private void showAISVesselBottomSheet(AISVessel vessel) {
        if (aisVesselBottomSheet != null && !aisVesselBottomSheet.isShowing()) {
            currentAISVessel = vessel;
            updateAISBottomSheetUI(vessel);
            aisVesselBottomSheet.show();
            startTimeUpdate();
            
            // Запускаем автоматическое обновление BottomSheet
            startBottomSheetAutoUpdate();
        }
    }
    
    /**
     * Запускает обновление времени
     */
    private void startTimeUpdate() {
        if (timeUpdateHandler != null && timeUpdateRunnable != null) {
            timeUpdateHandler.postDelayed(timeUpdateRunnable, 1000);
        }
    }
    
    /**
     * Останавливает обновление времени
     */
    private void stopTimeUpdate() {
        if (timeUpdateHandler != null && timeUpdateRunnable != null) {
            timeUpdateHandler.removeCallbacks(timeUpdateRunnable);
        }
        currentAISVessel = null;
    }
    
    /**
     * Запускает автоматическое обновление BottomSheet
     */
    private void startBottomSheetAutoUpdate() {
        if (bottomSheetUpdateHandler != null && bottomSheetUpdateRunnable != null) {
            // Останавливаем предыдущее обновление, если оно запущено
            bottomSheetUpdateHandler.removeCallbacks(bottomSheetUpdateRunnable);
            // Запускаем новое обновление
            bottomSheetUpdateHandler.postDelayed(bottomSheetUpdateRunnable, BOTTOM_SHEET_UPDATE_INTERVAL);
            Log.i(TAG, "Автоматическое обновление BottomSheet запущено");
        }
    }
    
    /**
     * Останавливает автоматическое обновление BottomSheet
     */
    private void stopBottomSheetAutoUpdate() {
        if (bottomSheetUpdateHandler != null && bottomSheetUpdateRunnable != null) {
            bottomSheetUpdateHandler.removeCallbacks(bottomSheetUpdateRunnable);
            Log.i(TAG, "Автоматическое обновление BottomSheet остановлено");
        }
    }
    
    /**
     * Обновляет только время назад для AIS судна
     */
    private void updateAISTimeAgo() {
        if (aisBottomSheetView == null || currentAISVessel == null) return;
        
        TextView tvTimeAgo = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_time_ago);
        if (tvTimeAgo != null && currentAISVessel.getLastUpdate() != null) {
            long secondsAgo = java.time.Duration.between(currentAISVessel.getLastUpdate(), java.time.LocalDateTime.now()).getSeconds();
            String timeAgoText = formatTimeAgo(secondsAgo);
            tvTimeAgo.setText("⏱️ Время назад: " + timeAgoText);
        }
    }
    
    /**
     * Обновляет UI AIS BottomSheet с актуальными данными
     */
    private void updateAISBottomSheetUI(AISVessel vessel) {
        if (aisBottomSheetView == null || vessel == null) return;
        
        // Обновляем текущее судно, если это то же самое судно
        if (currentAISVessel != null && currentAISVessel.getMmsi() != null && 
            currentAISVessel.getMmsi().equals(vessel.getMmsi())) {
            currentAISVessel = vessel;
        }
        
        // Убеждаемся, что обновление происходит в главном потоке
        runOnUiThread(() -> {
            if (aisBottomSheetView == null || vessel == null) return;
        
            // Обновляем все поля в AIS BottomSheet
            TextView tvTitle = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_title);
            TextView tvMmsi = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_mmsi);
            TextView tvCallsign = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_callsign);
            TextView tvImo = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_imo);
            TextView tvType = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_type);
            TextView tvPosition = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_position);
            TextView tvCourse = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_course);
            TextView tvRot = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_rot);
            TextView tvHeading = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_heading);
            TextView tvSpeed = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_speed);
            TextView tvDimensions = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_dimensions);
            TextView tvDraft = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_draft);
            TextView tvDestination = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_destination);
            TextView tvEta = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_eta);
            TextView tvNavStatus = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_nav_status);
            TextView tvClass = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_class);
            TextView tvSignal = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_signal);
            TextView tvDistance = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_distance);
            TextView tvBearing = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_bearing);
            TextView tvLastUpdate = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_last_update);
            TextView tvTimeAgo = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_time_ago);
        
            // Заголовок
            if (tvTitle != null) {
                String name = vessel.getVesselName() != null && !vessel.getVesselName().isEmpty() 
                    ? vessel.getVesselName() 
                    : "AIS СУДНО";
                String flag = getFlagEmojiForMMSI(vessel.getMmsi());
                String title = (flag != null ? flag + " " : "") + "🚢 " + name;
                tvTitle.setText(title);
            }
            
            // MMSI
            if (tvMmsi != null) {
                tvMmsi.setText("🆔 MMSI: " + (vessel.getMmsi() != null ? vessel.getMmsi() : "--"));
            }
            
            // Название судна

            
            // Позывной
            if (tvCallsign != null) {
                tvCallsign.setText("📻 Позывной: " + (vessel.getCallSign() != null ? vessel.getCallSign() : "--"));
            }
            
            // IMO
            if (tvImo != null) {
                tvImo.setText("🏷️ IMO: " + (vessel.getImo() > 0 ? String.valueOf(vessel.getImo()) : "--"));
            }
            
            // Тип судна
            if (tvType != null) {
                tvType.setText("🚢 Тип: " + (vessel.getVesselType() != null ? vessel.getVesselType() : "--"));
            }
            
            // Координаты
            if (tvPosition != null) {
                if (vessel.getLatitude() != 0 && vessel.getLongitude() != 0) {
                    String positionText = String.format("📍 Координаты: %.6f, %.6f", 
                        vessel.getLatitude(), vessel.getLongitude());
                    tvPosition.setText(positionText);
                } else {
                    tvPosition.setText("📍 Координаты: --");
                }
            }
            
            // Курс (COG)
            if (tvCourse != null) {
                if (vessel.getCourse() > 0) {
                    String courseText = String.format("🧭 COG: %.1f°", vessel.getCourse());
                    tvCourse.setText(courseText);
                } else {
                    tvCourse.setText("🧭 COG: --°");
                }
            }
            
            // Скорость поворота (ROT)
            if (tvRot != null) {
                double rot = vessel.getRateOfTurn();
                if (rot != 0) {
                    String rotText = String.format("🔄 ROT: %.1f°/мин", rot);
                    tvRot.setText(rotText);
                } else {
                    tvRot.setText("🔄 ROT: --°/мин");
                }
            }
            
            // Направление (HDG)
            if (tvHeading != null) {
                if (vessel.getHeading() > 0) {
                    String headingText = String.format("🧭 HDG: %.1f°", vessel.getHeading());
                    tvHeading.setText(headingText);
                } else {
                    tvHeading.setText("🧭 HDG: --°");
                }
            }
            
            // Скорость
            if (tvSpeed != null) {
                if (vessel.getSpeed() > 0) {
                    String speedText = String.format("⚡ Скорость: %.1f узлов", vessel.getSpeed());
                    tvSpeed.setText(speedText);
                } else {
                    tvSpeed.setText("⚡ Скорость: -- узлов");
                }
            }
            
            // Размеры
            if (tvDimensions != null) {
                if (vessel.getLength() > 0 && vessel.getWidth() > 0) {
                    String dimensionsText = String.format("📏 Размеры: %.1f x %.1f м", 
                        vessel.getLength(), vessel.getWidth());
                    tvDimensions.setText(dimensionsText);
                } else {
                    tvDimensions.setText("📏 Размеры: --");
                }
            }
        
            // Осадка
            if (tvDraft != null) {
                if (vessel.getDraft() > 0) {
                    String draftText = String.format("🌊 Осадка: %.1f м", vessel.getDraft());
                    tvDraft.setText(draftText);
                } else {
                    tvDraft.setText("🌊 Осадка: -- м");
                }
            }
            
            // Пункт назначения
            if (tvDestination != null) {
                tvDestination.setText("🎯 Назначение: " + (vessel.getDestination() != null ? vessel.getDestination() : "--"));
            }
            
            // ETA
            if (tvEta != null) {
                if (vessel.getEta() != null) {
                    String etaText = String.format("⏰ ETA: %s", 
                        vessel.getEta().format(java.time.format.DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm")));
                    tvEta.setText(etaText);
                } else {
                    tvEta.setText("⏰ ETA: --");
                }
            }
            
            // Навигационный статус
            if (tvNavStatus != null) {
                tvNavStatus.setText("🚦 Статус: " + (vessel.getNavigationalStatus() != null ? vessel.getNavigationalStatus() : "--"));
            }
            
            // Класс судна
            if (tvClass != null) {
                tvClass.setText("📋 Класс: " + (vessel.getVesselClass() != null ? vessel.getVesselClass() : "--"));
            }
            
            // Сила сигнала
            if (tvSignal != null) {
                if (vessel.getSignalStrength() > 0) {
                    String signalText = String.format("📶 Сигнал: %d", vessel.getSignalStrength());
                    tvSignal.setText(signalText);
                } else {
                    // Показываем качество позиции по AIS Accuracy биту
                    String qualityText = vessel.isPositionAccuracy() ? "📶 Точность: высокая" : "📶 Точность: низкая";
                    tvSignal.setText(qualityText);
                }
            }
            
            // Последнее обновление
            if (tvLastUpdate != null) {
                if (vessel.getLastUpdate() != null) {
                    String lastUpdateText = String.format("🕐 Обновлено: %s", 
                        vessel.getLastUpdate().format(java.time.format.DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss")));
                    tvLastUpdate.setText(lastUpdateText);
                } else {
                    tvLastUpdate.setText("🕐 Обновлено: --");
                }
            }
        
            // Расстояние до судна
            if (tvDistance != null) {
                Vessel ourVessel = appController.getOwnVessel();
                if (ourVessel != null && ourVessel.getLatitude() != 0 && ourVessel.getLongitude() != 0 && 
                    vessel.getLatitude() != 0 && vessel.getLongitude() != 0) {
                    double distance = com.grigowashere.aismap.utils.NavigationUtils.calculateDistance(
                        ourVessel.getLatitude(), ourVessel.getLongitude(),
                        vessel.getLatitude(), vessel.getLongitude()
                    );
                    String distanceText = "📏 Расстояние: " + com.grigowashere.aismap.utils.NavigationUtils.formatDistance(distance);
                    tvDistance.setText(distanceText);
                } else {
                    tvDistance.setText("📏 Расстояние: --");
                }
            }
            
            // Пеленг (азимут) до судна
            if (tvBearing != null) {
                Vessel ourVessel = appController.getOwnVessel();
                if (ourVessel != null && ourVessel.getLatitude() != 0 && ourVessel.getLongitude() != 0 && 
                    vessel.getLatitude() != 0 && vessel.getLongitude() != 0) {
                    double bearing = com.grigowashere.aismap.utils.NavigationUtils.calculateBearing(
                        ourVessel.getLatitude(), ourVessel.getLongitude(),
                        vessel.getLatitude(), vessel.getLongitude()
                    );
                    double relativeBearing = com.grigowashere.aismap.utils.NavigationUtils.calculateRelativeBearing(
                        ourVessel.getCourse(), bearing
                    );
                    String bearingText = "🧭 Пеленг: " + com.grigowashere.aismap.utils.NavigationUtils.formatRelativeBearing(relativeBearing);
                    tvBearing.setText(bearingText);
                } else {
                    tvBearing.setText("🧭 Пеленг: --");
                }
            }

            // Время назад
            if (tvTimeAgo != null) {
                if (vessel.getLastUpdate() != null) {
                    long secondsAgo = java.time.Duration.between(vessel.getLastUpdate(), java.time.LocalDateTime.now()).getSeconds();
                    String timeAgoText = formatTimeAgo(secondsAgo);
                    tvTimeAgo.setText("⏱️ Время назад: " + timeAgoText);
                } else {
                    tvTimeAgo.setText("⏱️ Время назад: --");
                }
            }
        });
    }
    
    /**
     * Форматирует время назад в читаемый вид
     */
    private String formatTimeAgo(long seconds) {
        if (seconds < 60) {
            return seconds + " сек";
        } else if (seconds < 3600) {
            long minutes = seconds / 60;
            return minutes + " мин";
        } else if (seconds < 86400) {
            long hours = seconds / 3600;
            return hours + " ч";
        } else {
            long days = seconds / 86400;
            return days + " дн";
        }
    }

    /**
     * Возвращает флаг-эмодзи по MMSI через MID->ISO2.
     */
    private String getFlagEmojiForMMSI(String mmsi) {
        try {
            if (mmsi == null || mmsi.length() < 3) return null;
            String mid = mmsi.substring(0, 3);
            String iso2 = MIDToCountry.MID_TO_COUNTRY.get(mid);
            if (iso2 == null || iso2.length() != 2) return null;
            char a = Character.toUpperCase(iso2.charAt(0));
            char b = Character.toUpperCase(iso2.charAt(1));
            int base = 0x1F1E6;
            int cp1 = base + (a - 'A');
            int cp2 = base + (b - 'A');
            return new String(Character.toChars(cp1)) + new String(Character.toChars(cp2));
        } catch (Exception ignored) {
            return null;
        }
    }
    
    /**
     * Восстанавливает обработчики кликов для маркеров
     */
    private void restoreMarkerClickListeners() {
        Log.i(TAG, "Восстанавливаем обработчики кликов для маркеров");
        if (mapInterface instanceof com.grigowashere.aismap.maps.YandexMapImpl) {
            com.grigowashere.aismap.maps.YandexMapImpl yandexMap = (com.grigowashere.aismap.maps.YandexMapImpl) mapInterface;
            yandexMap.refreshMarkerClickListeners();
            Log.i(TAG, "Обработчики кликов восстановлены");
        }
    }
    
    /**
     * Тестирует работу кликов по маркерам
     */
    private void testMarkerClicks() {
        Log.i(TAG, "Тестируем работу кликов по маркерам");
        Toast.makeText(this, "Тестируем клики по маркерам", Toast.LENGTH_SHORT).show();
        
        // Восстанавливаем обработчики кликов
        restoreMarkerClickListeners();
        
        // Проверяем, что маркеры существуют
        Vessel ownVessel = appController.getOwnVessel();
        if (ownVessel != null && ownVessel.getLatitude() != 0 && ownVessel.getLongitude() != 0) {
            Log.i(TAG, "Наше судно найдено, координаты: " + ownVessel.getLatitude() + ", " + ownVessel.getLongitude());
            Toast.makeText(this, "Наше судно найдено, попробуйте кликнуть по маркеру", Toast.LENGTH_LONG).show();
        } else {
            Log.w(TAG, "Наше судно не найдено или координаты равны 0");
            Toast.makeText(this, "Наше судно не найдено", Toast.LENGTH_SHORT).show();
        }
        
        // Проверяем AIS суда
        List<AISVessel> aisVessels = appController.getAISVessels();
        if (!aisVessels.isEmpty()) {
            Log.i(TAG, "Найдено AIS судов: " + aisVessels.size());
            Toast.makeText(this, "Найдено AIS судов: " + aisVessels.size(), Toast.LENGTH_SHORT).show();
        } else {
            Log.w(TAG, "AIS суда не найдены");
            Toast.makeText(this, "AIS суда не найдены", Toast.LENGTH_SHORT).show();
        }
    }
    
    /**
     * Инициализирует Яндекс.Карты
     */
    private void initializeYandexMaps() {
        if (!isYandexMapsInitialized) {
            try {
                // Инициализация Яндекс.Карт
                com.yandex.mapkit.MapKitFactory.setApiKey("9ae1917c-2049-4927-9d1e-29dd0d3e8ebc");
                com.yandex.mapkit.MapKitFactory.initialize(this);
                isYandexMapsInitialized = true;
                
                // Устанавливаем флаг в MapController
                MapController.setYandexMapsInitialized(true);
                
                Log.i(TAG, "Яндекс.Карты успешно инициализированы");
            } catch (Exception e) {
                Log.e(TAG, "Ошибка инициализации Яндекс.Карт: " + e.getMessage(), e);
            }
        }
    }
    
    /**
     * Применяет настройки к контроллерам
     */
    private void applySettings() {
        if (settingsManager == null || appController == null) {
            Log.w(TAG, "SettingsManager или AppController не инициализированы");
            return;
        }
        
        try {
            // Применяем UDP настройки
            int udpPort = settingsManager.getUDPPort();
            boolean udpEnabled = settingsManager.isUDPEnabled();
            
            appController.setUDPPort(udpPort);
            appController.setUDPEnabled(udpEnabled);
            
            // Применяем NMEA настройки
            boolean androidNMEAEnabled = settingsManager.isAndroidNMEAEnabled();
            boolean udpNMEAEnabled = settingsManager.isUDPNMEAEnabled();
            
            appController.setAndroidNMEAEnabled(androidNMEAEnabled);
            appController.setUDPNMEAEnabled(udpNMEAEnabled);
            
            // Применяем режим данных
            String dataMode = settingsManager.getDataMode();
            appController.setDataMode(dataMode);
            
            Log.i(TAG, "Настройки применены: " + settingsManager.getSettingsSummary());
            
        } catch (Exception e) {
            Log.e(TAG, "Ошибка при применении настроек: " + e.getMessage(), e);
            Toast.makeText(this, "Ошибка при применении настроек", Toast.LENGTH_SHORT).show();
        }
    }
    
    /**
     * Запускает форграунд сервис
     */
    private void startForegroundService() {
        try {
            // Проверяем разрешения для Android 13+
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
                if (androidx.core.content.ContextCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS) 
                    != android.content.pm.PackageManager.PERMISSION_GRANTED) {
                    android.util.Log.w(TAG, "Запрашиваем разрешение на уведомления для Android 13+");
                    androidx.core.app.ActivityCompat.requestPermissions(this, 
                        new String[]{android.Manifest.permission.POST_NOTIFICATIONS}, 
                        NOTIFICATION_PERMISSION_REQUEST_CODE);
                    return; // Ждем разрешения
                }
            }
            
            android.content.Intent svc = new android.content.Intent(this, com.grigowashere.aismap.services.AISForegroundService.class);
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                startForegroundService(svc);
                android.util.Log.i(TAG, "Форграунд сервис запущен через startForegroundService()");
            } else {
                startService(svc);
                android.util.Log.i(TAG, "Форграунд сервис запущен через startService()");
            }
        } catch (Exception e) {
            android.util.Log.e(TAG, "Не удалось запустить форграунд сервис: " + e.getMessage(), e);
        }
    }
    
    /**
     * Останавливает форграунд сервис
     */
    private void stopForegroundService() {
        try {
            android.content.Intent svc = new android.content.Intent(this, com.grigowashere.aismap.services.AISForegroundService.class);
            stopService(svc);
            android.util.Log.i(TAG, "Форграунд сервис остановлен");
        } catch (Exception e) {
            android.util.Log.e(TAG, "Ошибка при остановке форграунд сервиса: " + e.getMessage(), e);
        }
    }
    
    /**
     * Тестирует работу форграунд сервиса
     */
    private void testForegroundService() {
        android.util.Log.i(TAG, "=== ТЕСТ ФОРГРАУНД СЕРВИСА ===");
        
        // Проверяем разрешения на уведомления
        boolean hasNotificationPermission = true;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
            hasNotificationPermission = androidx.core.content.ContextCompat.checkSelfPermission(this, 
                android.Manifest.permission.POST_NOTIFICATIONS) == android.content.pm.PackageManager.PERMISSION_GRANTED;
        }
        android.util.Log.i(TAG, "Разрешение на уведомления: " + hasNotificationPermission);
        
        // Проверяем статус сервиса
        boolean isServiceRunning = isServiceRunning();
        android.util.Log.i(TAG, "Сервис запущен: " + isServiceRunning);
        
        if (isServiceRunning) {
            android.util.Log.i(TAG, "Останавливаем сервис...");
            stopForegroundService();
            Toast.makeText(this, "Сервис остановлен", Toast.LENGTH_SHORT).show();
        } else {
            android.util.Log.i(TAG, "Запускаем сервис...");
            startForegroundService();
            Toast.makeText(this, "Сервис запущен", Toast.LENGTH_SHORT).show();
        }
        
        android.util.Log.i(TAG, "=== КОНЕЦ ТЕСТА ===");
    }
    
    /**
     * Проверяет, запущен ли сервис
     */
    private boolean isServiceRunning() {
        android.app.ActivityManager manager = (android.app.ActivityManager) getSystemService(android.content.Context.ACTIVITY_SERVICE);
        for (android.app.ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (com.grigowashere.aismap.services.AISForegroundService.class.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * Перезапускает сервисы с новыми настройками
     */
    private void restartServices() {
        if (appController == null) {
            Log.w(TAG, "AppController не инициализирован");
            return;
        }
        
        try {
            Log.i(TAG, "Перезапускаем сервисы...");
            
            // Останавливаем все слушатели
            appController.stopAllListeners();
            
            // Применяем новые настройки
            applySettings();
            
            // Перезапускаем UDP слушатель с новым портом, если нужно
            if (settingsManager.shouldRestartUDP(appController.getUDPPort(), appController.isUDPEnabled())) {
                appController.restartUDPListener();
            }
            
            // Запускаем слушатели с новыми настройками
            appController.startAllListeners();
            
            Log.i(TAG, "Сервисы успешно перезапущены");
            Log.i(TAG, "Статус настроек: " + appController.getSettingsStatus());
            
        } catch (Exception e) {
            Log.e(TAG, "Ошибка при перезапуске сервисов: " + e.getMessage(), e);
            Toast.makeText(this, "Ошибка при перезапуске сервисов", Toast.LENGTH_SHORT).show();
        }
    }
    
    /**
     * Инициализирует курсор согласно настройкам
     */
    private void initializeCursor() {
        if (mapInterface == null || settingsManager == null) return;
        
        boolean cursorEnabled = settingsManager.isCursorEnabled();
        if (cursorEnabled) {
            mapInterface.showCursor();
            // Обновляем координаты курсора с центра карты
            mapInterface.updateCursorFromMapCenter();
        } else {
            mapInterface.hideCursor();
        }
        
        Log.i(TAG, "Курсор инициализирован: " + (cursorEnabled ? "включен" : "выключен"));
    }
    
    /**
     * Применяет настройки курсора
     */
    private void applyCursorSettings(boolean cursorEnabled) {
        if (mapInterface == null) return;
        
        if (cursorEnabled) {
            mapInterface.showCursor();
            // Обновляем координаты курсора с центра карты
            mapInterface.updateCursorFromMapCenter();
        } else {
            mapInterface.hideCursor();
        }
        
        Log.i(TAG, "Настройки курсора применены: " + (cursorEnabled ? "включен" : "выключен"));
    }
    
}