package com.grigowashere.aismap.maps;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;

import com.grigowashere.aismap.models.Vessel;
import com.grigowashere.aismap.models.AISVessel;
import com.yandex.mapkit.geometry.Point;
import com.yandex.mapkit.map.PlacemarkMapObject;
import com.yandex.mapkit.map.MapObjectCollection;
import com.yandex.runtime.image.ImageProvider;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Обертка для маркера Yandex Maps с управлением жизненным циклом
 */
public class YandexMarkerWrapper extends MarkerWrapper {
    
    private Context context;
    private PlacemarkMapObject marker;
    private MapObjectCollection mapObjects;
    private Vessel vessel;
    private AISVessel aisVessel;
    private boolean isOwnVessel;
    private AtomicBoolean clickListenerSet = new AtomicBoolean(false);
    private Runnable clickHandler;
    
    // Ссылка на MapView для получения азимута карты
    private com.yandex.mapkit.mapview.MapView mapView;
    
    // Кешированные данные для предотвращения лишних обновлений
    private double lastLatitude = Double.NaN;
    private double lastLongitude = Double.NaN;
    private double lastCourse = Double.NaN;
    private int lastColor = -1;
    private boolean lastSelected = false;
    
    // Кеш иконок для быстрого отображения
    private Bitmap cachedIconBitmap;
    private double cachedIconCourse = Double.NaN;
    private int cachedIconColor = -1;
    private boolean cachedIconSelected = false;
    private float cachedIconZoom = -1;
    private boolean cachedIconStale = false;
    
    // Ссылка на SettingsManager для получения настроек устаревания
    private com.grigowashere.aismap.utils.SettingsManager settingsManager;
    
    // Константы для масштабирования маркеров
    private static final float MIN_MARKER_SIZE = 24f; // Минимальный размер маркера в пикселях (увеличен)
    private static final float MAX_MARKER_SIZE = 200f; // Максимальный размер маркера в пикселях (увеличен)
    private static final float ZOOM_THRESHOLD_FOR_REAL_SIZE = 12f; // Зум, при котором начинаем использовать реальные размеры (снижен)
    private static final float MEDIUM_ZOOM_SIZE = 48f; // Размер маркера на среднем приближении
    private static final float CLOSE_ZOOM_SIZE = 80f; // Размер маркера на близком приближении
    
    public YandexMarkerWrapper(Context context, MapObjectCollection mapObjects, 
                              com.yandex.mapkit.mapview.MapView mapView, Vessel vessel, String id,
                              com.grigowashere.aismap.utils.SettingsManager settingsManager) {
        super(id);
        this.context = context;
        this.mapObjects = mapObjects;
        this.mapView = mapView;
        this.vessel = vessel;
        this.isOwnVessel = true;
        this.settingsManager = settingsManager;
        // Предварительно создаем иконку
        preloadIcon();
        createMarker();
    }
    
    public YandexMarkerWrapper(Context context, MapObjectCollection mapObjects, 
                              com.yandex.mapkit.mapview.MapView mapView, AISVessel vessel, String id,
                              com.grigowashere.aismap.utils.SettingsManager settingsManager) {
        super(id);
        this.context = context;
        this.mapObjects = mapObjects;
        this.mapView = mapView;
        this.aisVessel = vessel;
        this.isOwnVessel = false;
        this.settingsManager = settingsManager;
        // Предварительно создаем иконку
        preloadIcon();
        createMarker();
    }
    
    /**
     * Предварительно создает иконку для быстрого отображения
     */
    private void preloadIcon() {
        try {
            // Курс для поворота: HDG (0..359) если валиден, иначе COG
            double course = getDisplayCourse();
            int color = isOwnVessel ? android.graphics.Color.BLUE : getVesselColor();
            boolean selected = !isOwnVessel && aisVessel.isSelected();
            boolean stale = isDataStale(); // Проверяем устаревание данных
            
            cachedIconBitmap = createRotatedIcon(course, color, selected, stale);
            cachedIconCourse = course;
            cachedIconColor = color;
            cachedIconSelected = selected;
            cachedIconStale = stale;
        } catch (Exception e) {
            // Ошибка предварительной загрузки иконки
            cachedIconBitmap = null;
        }
    }
    
    private void createMarker() {
        try {
            double lat = isOwnVessel ? vessel.getLatitude() : aisVessel.getLatitude();
            double lon = isOwnVessel ? vessel.getLongitude() : aisVessel.getLongitude();
            
            // Сначала создаем иконку
            Bitmap iconBitmap = createIconBitmap();
            
            Point point = new Point(lat, lon);
            marker = mapObjects.addPlacemark(point);
            
            if (marker != null) {
                // Сразу устанавливаем готовую иконку
                if (iconBitmap != null) {
                    marker.setIcon(ImageProvider.fromBitmap(iconBitmap));
                } else {
                    // Fallback иконка
                    marker.setIcon(ImageProvider.fromResource(context, android.R.drawable.ic_menu_compass));
                }
                setupClickListener();
            }
        } catch (Exception e) {
            // Ошибка создания маркера
            deactivate();
        }
    }
    
    /**
     * Создает иконку маркера заранее
     */
    private Bitmap createIconBitmap() {
        try {
            // Курс для поворота: HDG (0..359) если валиден, иначе COG
            double course = getDisplayCourse();
            int color = isOwnVessel ? android.graphics.Color.BLUE : getVesselColor();
            boolean selected = !isOwnVessel && aisVessel.isSelected();
            boolean stale = isDataStale(); // Проверяем устаревание данных
            
            return createRotatedIcon(course, color, selected, stale);
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * Пересоздает маркер с новыми координатами
     * Этот метод больше не используется - маркеры всегда пересоздаются в менеджере
     */
    private void recreateMarker(double latitude, double longitude) {
        // Метод оставлен для совместимости, но не используется
    }
    
    /**
     * Устанавливает иконку немедленно без проверок
     */
    private void setIconImmediately() {
        try {
            // Курс для поворота: HDG (0..359) если валиден, иначе COG
            double course = getDisplayCourse();
            int color = isOwnVessel ? android.graphics.Color.BLUE : getVesselColor();
            boolean selected = !isOwnVessel && aisVessel.isSelected();
            boolean stale = isDataStale(); // Проверяем устаревание данных
            
            // Получаем текущий зум для проверки кеша
            float currentZoom = getCurrentZoom();
            
            // Проверяем кеш иконки
            Bitmap iconBitmap = null;
            if (Double.compare(course, cachedIconCourse) == 0 && 
                color == cachedIconColor && 
                selected == cachedIconSelected && 
                stale == cachedIconStale &&
                Float.compare(currentZoom, cachedIconZoom) == 0 &&
                cachedIconBitmap != null) {
                // Используем кешированную иконку
                iconBitmap = cachedIconBitmap;
            } else {
                // Создаем новую иконку
                iconBitmap = createRotatedIcon(course, color, selected, stale);
                if (iconBitmap != null) {
                    // Кешируем иконку
                    cachedIconBitmap = iconBitmap;
                    cachedIconCourse = course;
                    cachedIconColor = color;
                    cachedIconSelected = selected;
                    cachedIconStale = stale;
                    cachedIconZoom = currentZoom;
                }
            }
            
            if (iconBitmap != null) {
                marker.setIcon(ImageProvider.fromBitmap(iconBitmap));
            } else {
                // Fallback иконка если не удалось создать повернутую
                marker.setIcon(ImageProvider.fromResource(context, android.R.drawable.ic_menu_compass));
            }
            
            // Обновляем кешированные значения
            lastCourse = course;
            lastColor = color;
            lastSelected = selected;
        } catch (Exception e) {
            // Ошибка установки иконки - используем fallback
            try {
                marker.setIcon(ImageProvider.fromResource(context, android.R.drawable.ic_menu_compass));
            } catch (Exception ex) {
                // Игнорируем ошибки fallback
            }
        }
    }
    
    @Override
    public boolean isValid() {
        try {
            if (marker == null) {
                return false;
            }
            // Пробуем получить геометрию для проверки состояния
            marker.getGeometry();
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    @Override
    public void updatePosition(double latitude, double longitude) {
        // Этот метод больше не используется - маркеры всегда пересоздаются
        // Оставляем для совместимости с интерфейсом
    }
    
    @Override
    public void updateCourse(double course) {
        // Этот метод больше не используется - маркеры всегда пересоздаются
        // Оставляем для совместимости с интерфейсом
    }
    
    @Override
    public void remove() {
        try {
            if (marker != null) {
                mapObjects.remove(marker);
            }
        } catch (Exception e) {
            // Игнорируем ошибки при удалении
        } finally {
            deactivate();
        }
    }
    
    @Override
    public void updateIcon() {
        // Этот метод больше не используется - маркеры всегда пересоздаются
        // Оставляем для совместимости с интерфейсом
    }
    
    @Override
    public void setClickListener(Runnable clickHandler) {
        this.clickHandler = clickHandler;
        setupClickListener();
    }
    
    private void setupClickListener() {
        if (marker == null || clickHandler == null) {
            return;
        }
        
        // Сбрасываем флаг для возможности повторной установки
        clickListenerSet.set(false);
        
        try {
            marker.addTapListener((mapObject, point) -> {
                try {
                    if (mapObject != null && clickHandler != null) {
                        clickHandler.run();
                    }
                    return true;
                } catch (Exception e) {
                    return false;
                }
            });
            clickListenerSet.set(true);
        } catch (Exception e) {
            // Ошибка установки обработчика кликов
            clickListenerSet.set(false);
        }
    }
    
    private Bitmap createRotatedIcon(double course, int color, boolean isSelected, boolean isStale) {
        // Получаем текущий зум карты
        float currentZoom = getCurrentZoom();
        
        try {
            // Сначала выбираем базовую иконку: для AIS Class A используем targetclassa
            String baseIconName = (!isOwnVessel && isAISClassA()) ? "targetclassa" : "target";
            int targetIconResId = context.getResources().getIdentifier(baseIconName, "drawable", context.getPackageName());
            if (targetIconResId == 0) {
                return createSimpleIcon(color, course, currentZoom, isStale);
            }
            
            Drawable targetDrawable = context.getResources().getDrawable(targetIconResId, null);
            if (targetDrawable == null) {
                return createSimpleIcon(color, course, currentZoom, isStale);
            }
            
            // Получаем иконку losingtarget для наложения (если данные устарели)
            Drawable losingTargetDrawable = null;
            if (isStale) {
                int losingTargetIconResId = context.getResources().getIdentifier("losingtarget", "drawable", context.getPackageName());
                if (losingTargetIconResId != 0) {
                    losingTargetDrawable = context.getResources().getDrawable(losingTargetIconResId, null);
                }
            }
            
            // Применяем цвет к основной иконке
            if (color != 0) {
                targetDrawable.setColorFilter(color, android.graphics.PorterDuff.Mode.SRC_IN);
            }
            
            // Получаем размеры основной иконки
            int originalWidth = targetDrawable.getIntrinsicWidth();
            int originalHeight = targetDrawable.getIntrinsicHeight();
            
            if (originalWidth <= 0) originalWidth = 32;
            if (originalHeight <= 0) originalHeight = 48;
            
            // Рассчитываем размер маркера на основе зума и размеров судна
            float markerSize = calculateMarkerSize(currentZoom);
            
            // Масштабируем пропорционально рассчитанному размеру
            float scale = markerSize / Math.max(originalWidth, originalHeight);
            int width = (int) (originalWidth * scale);
            int height = (int) (originalHeight * scale);
            
            // Создаем bitmap с дополнительным пространством для обводки и тени
            int padding = 12;
            int bitmapSize = Math.max(width, height) + padding * 2;
            Bitmap bitmap = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            
            // Получаем азимут карты (поворот карты)
            float mapAzimuth = 0.0f;
            try {
                if (mapView != null) {
                    com.yandex.mapkit.map.CameraPosition cameraPosition = mapView.getMap().getCameraPosition();
                    mapAzimuth = cameraPosition.getAzimuth();
                }
            } catch (Exception e) {
                // Не удалось получить азимут карты, используем 0
            }
            
            // Поворачиваем основную иконку на курс судна с учетом поворота карты
            // Курс судна - это направление относительно севера
            // Азимут карты - это поворот карты относительно севера
            // Итоговый поворот = курс судна - азимут карты (чтобы маркер оставался относительно севера)
            float rotationAngle = (float) (course - mapAzimuth);
            
            int centerX = bitmapSize / 2;
            int centerY = bitmapSize / 2;
            int left = centerX - width / 2;
            int top = centerY - height / 2;
            
            // Рисуем тень (смещенную копию)
            targetDrawable.setBounds(left + 2, top + 2, left + width + 2, top + height + 2);
            targetDrawable.setColorFilter(0x80000000, android.graphics.PorterDuff.Mode.SRC_IN);
            
            canvas.save();
            canvas.rotate(rotationAngle, centerX, centerY);
            targetDrawable.draw(canvas);
            canvas.restore();
            
            // Рисуем основную иконку target (поворачивается)
            targetDrawable.setBounds(left, top, left + width, top + height);
            targetDrawable.setColorFilter(color, android.graphics.PorterDuff.Mode.SRC_IN);
            
            canvas.save();
            canvas.rotate(rotationAngle, centerX, centerY);
            targetDrawable.draw(canvas);
            canvas.restore();
            
            // Рисуем losingtarget поверх (НЕ поворачивается)
            if (losingTargetDrawable != null) {
                // Используем тот же размер для losingtarget
                losingTargetDrawable.setBounds(left, top, left + width, top + height);
                losingTargetDrawable.draw(canvas); // Без поворота!
            }
            
            // Добавляем рамку выделения если нужно
            if (isSelected) {
                addSelectionFrame(canvas, centerX, centerY, Math.max(width, height));
            }
            
            return bitmap;
        } catch (Exception e) {
            return createSimpleIcon(color, course, currentZoom, isStale);
        }
    }

    /**
     * Возвращает курс для отображения маркера: валидный HDG (0..359), иначе COG
     */
    private double getDisplayCourse() {
        try {
            if (isOwnVessel) {
                double cog = vessel != null ? vessel.getCourse() : 0.0;
                return normalizeCourse(cog);
            }
            if (aisVessel != null) {
                double hdg = aisVessel.getHeading();
                if (isValidHeading(hdg)) {
                    return normalizeCourse(hdg);
                }
                double cog = aisVessel.getCourse();
                return normalizeCourse(cog);
            }
        } catch (Exception ignored) {
        }
        return 0.0;
    }

    /**
     * Проверка валидности HDG: 0..359 включительно, 511 — невалидно
     */
    private boolean isValidHeading(double heading) {
        if (Double.isNaN(heading) || Double.isInfinite(heading)) return false;
        int h = (int) Math.round(heading);
        if (h == 511) return false;
        return h >= 0 && h <= 359;
    }

    /**
     * Нормализует курс к диапазону [0, 360)
     */
    private double normalizeCourse(double course) {
        if (Double.isNaN(course) || Double.isInfinite(course)) return 0.0;
        double c = course % 360.0;
        if (c < 0) c += 360.0;
        return c;
    }

    private boolean isAISClassA() {
        try {
            if (aisVessel == null) return false;
            String cls = aisVessel.getVesselClass();
            if (cls == null) return false;
            String s = cls.trim().toLowerCase();
            return s.equals("class a") || s.equals("a") || s.contains("class a");
        } catch (Exception ignored) {
            return false;
        }
    }
    
    private Bitmap createSimpleIcon(int color, double course, float zoom, boolean isStale) {
        try {
            // Рассчитываем размер маркера на основе зума
            float markerSize = calculateMarkerSize(zoom);
            int size = (int) markerSize;
            
            // Увеличиваем размер bitmap для обводки и тени
            int padding = 8;
            int bitmapSize = size + padding * 2;
            Bitmap bitmap = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            
            // Смещаем координаты с учетом padding
            float centerX = bitmapSize / 2f;
            float centerY = bitmapSize / 2f;
            
            // Создаем путь для треугольника
            android.graphics.Path path = new android.graphics.Path();
            path.moveTo(centerX, padding);
            path.lineTo(padding + size * 0.1f, padding + size * 0.8f);
            path.lineTo(padding + size * 0.9f, padding + size * 0.8f);
            path.close();
            
            // Рисуем тень (смещенную копию)
            Paint shadowPaint = new Paint();
            shadowPaint.setColor(0x80000000); // Полупрозрачный черный
            shadowPaint.setStyle(Paint.Style.FILL);
            shadowPaint.setAntiAlias(true);
            
            canvas.save();
            canvas.translate(2, 2); // Смещение для тени
            canvas.rotate((float) course, centerX, centerY);
            canvas.drawPath(path, shadowPaint);
            canvas.restore();
            
            // Рисуем внешнюю обводку
            Paint outlinePaint = new Paint();
            outlinePaint.setColor(0xFF000000); // Черная обводка
            outlinePaint.setStyle(Paint.Style.STROKE);
            outlinePaint.setStrokeWidth(4f);
            outlinePaint.setAntiAlias(true);
            
            canvas.save();
            canvas.rotate((float) course, centerX, centerY);
            canvas.drawPath(path, outlinePaint);
            canvas.restore();
            
            // Рисуем внутреннюю обводку
            Paint innerOutlinePaint = new Paint();
            innerOutlinePaint.setColor(0xFFFFFFFF); // Белая внутренняя обводка
            innerOutlinePaint.setStyle(Paint.Style.STROKE);
            innerOutlinePaint.setStrokeWidth(2f);
            innerOutlinePaint.setAntiAlias(true);
            
            canvas.save();
            canvas.rotate((float) course, centerX, centerY);
            canvas.drawPath(path, innerOutlinePaint);
            canvas.restore();
            
            // Рисуем основную заливку
            Paint fillPaint = new Paint();
            fillPaint.setColor(color);
            fillPaint.setStyle(Paint.Style.FILL);
            fillPaint.setAntiAlias(true);
            
            // Для устаревших данных рисуем пунктирный треугольник
            if (isStale) {
                fillPaint.setStyle(Paint.Style.STROKE);
                fillPaint.setStrokeWidth(3f);
                fillPaint.setPathEffect(new android.graphics.DashPathEffect(new float[]{10, 5}, 0));
            }
            
            canvas.save();
            canvas.rotate((float) course, centerX, centerY);
            canvas.drawPath(path, fillPaint);
            canvas.restore();
            
            return bitmap;
        } catch (Exception e) {
            return null;
        }
    }
    
    private void addSelectionFrame(Canvas canvas, int centerX, int centerY, int size) {
        try {
            // Сначала рисуем тень для рамки выделения
            Paint shadowPaint = new Paint();
            shadowPaint.setColor(0x80000000);
            shadowPaint.setStyle(Paint.Style.STROKE);
            shadowPaint.setStrokeWidth(6f);
            shadowPaint.setAntiAlias(true);
            
            int shadowSize = size + 20;
            canvas.drawCircle(centerX + 2, centerY + 2, shadowSize / 2, shadowPaint);
            
            // Рисуем внешнюю обводку
            Paint outerOutlinePaint = new Paint();
            outerOutlinePaint.setColor(0xFF000000);
            outerOutlinePaint.setStyle(Paint.Style.STROKE);
            outerOutlinePaint.setStrokeWidth(4f);
            outerOutlinePaint.setAntiAlias(true);
            
            int outerSize = size + 18;
            canvas.drawCircle(centerX, centerY, outerSize / 2, outerOutlinePaint);
            
            // Рисуем внутреннюю обводку
            Paint innerOutlinePaint = new Paint();
            innerOutlinePaint.setColor(0xFFFFFFFF);
            innerOutlinePaint.setStyle(Paint.Style.STROKE);
            innerOutlinePaint.setStrokeWidth(2f);
            innerOutlinePaint.setAntiAlias(true);
            
            int innerSize = size + 16;
            canvas.drawCircle(centerX, centerY, innerSize / 2, innerOutlinePaint);
            
            // Пробуем использовать иконку chosentarget если доступна
            int iconResId = context.getResources().getIdentifier("chosentarget", "drawable", context.getPackageName());
            if (iconResId != 0) {
                Drawable selectionDrawable = context.getResources().getDrawable(iconResId, null);
                if (selectionDrawable != null) {
                    int selectionSize = size + 16;
                    int selectionLeft = centerX - selectionSize / 2;
                    int selectionTop = centerY - selectionSize / 2;
                    
                    selectionDrawable.setBounds(selectionLeft, selectionTop, 
                        selectionLeft + selectionSize, selectionTop + selectionSize);
                    selectionDrawable.draw(canvas);
                }
            }
        } catch (Exception e) {
            // Игнорируем ошибки рамки выделения
        }
    }
    
    private int getVesselColor() {
        if (aisVessel == null) return android.graphics.Color.WHITE;
        
        String navStatus = aisVessel.getNavigationalStatus();
        if (navStatus != null) {
            switch (navStatus.toLowerCase()) {
                case "under way using engine":
                case "under way":
                    return android.graphics.Color.GREEN;
                case "at anchor":
                    return android.graphics.Color.YELLOW;
                case "moored":
                    return android.graphics.Color.BLUE;
                case "not under command":
                case "restricted manoeuvrability":
                    return android.graphics.Color.RED;
                default:
                    return android.graphics.Color.WHITE;
            }
        }
        return android.graphics.Color.WHITE;
    }
    
    public Vessel getVessel() {
        return vessel;
    }
    
    public AISVessel getAISVessel() {
        return aisVessel;
    }
    
    public boolean isOwnVessel() {
        return isOwnVessel;
    }
    
    /**
     * Проверяет, устарели ли данные судна (для AIS судов)
     */
    public boolean isDataStale() {
        if (isOwnVessel || aisVessel == null || settingsManager == null) {
            return false; // Собственное судно никогда не устаревает
        }
        return aisVessel.isDataStale(settingsManager.getDataStaleWarningMinutes());
    }
    
    /**
     * Проверяет, нужно ли удалить судно (для AIS судов)
     */
    public boolean shouldBeRemoved() {
        if (isOwnVessel || aisVessel == null || settingsManager == null) {
            return false; // Собственное судно никогда не удаляется
        }
        return aisVessel.shouldBeRemoved(settingsManager.getDataStaleRemoveMinutes());
    }
    
    /**
     * Получает текущий зум карты
     */
    private float getCurrentZoom() {
        try {
            if (mapView != null) {
                com.yandex.mapkit.map.CameraPosition cameraPosition = mapView.getMap().getCameraPosition();
                return cameraPosition.getZoom();
            }
        } catch (Exception e) {
            // Ошибка получения зума, возвращаем значение по умолчанию
        }
        return 10f; // Значение по умолчанию
    }
    
    /**
     * Рассчитывает размер маркера на основе зума и размеров судна
     */
    private float calculateMarkerSize(float zoom) {
        // На очень большом расстоянии используем минимальный размер
        if (zoom < 8) {
            return MIN_MARKER_SIZE;
        }
        
        // На среднем расстоянии используем средний размер
        if (zoom < 12) {
            return MEDIUM_ZOOM_SIZE;
        }
        
        // На близком расстоянии используем крупный размер
        if (zoom < 15) {
            return CLOSE_ZOOM_SIZE;
        }
        
        // При очень близком приближении рассчитываем размер на основе реальных размеров судна
        double vesselLength = 0;
        double vesselWidth = 0;
        
        if (isOwnVessel && vessel != null) {
            // Для собственного судна используем примерные размеры
            vesselLength = 50; // метры
            vesselWidth = 10;  // метры
        } else if (!isOwnVessel && aisVessel != null) {
            vesselLength = aisVessel.getLength();
            vesselWidth = aisVessel.getWidth();
        }
        
        // Если размеры не заданы или очень маленькие, используем увеличенный базовый размер
        if (vesselLength <= 0 || vesselWidth <= 0 || vesselLength < 10 || vesselWidth < 5) {
            // Используем размер, основанный на зуме, но увеличенный
            float baseSize = CLOSE_ZOOM_SIZE + (zoom - 15) * 8; // Увеличиваем размер с зумом
            return Math.max(CLOSE_ZOOM_SIZE, Math.min(MAX_MARKER_SIZE, baseSize));
        }
        
        // Рассчитываем размер на основе большего из размеров судна
        double vesselSize = Math.max(vesselLength, vesselWidth);
        
        // Коэффициент масштабирования (пиксели на метр при текущем зуме)
        // Чем больше зум, тем больше пикселей на метр
        float pixelsPerMeter = (float) (Math.pow(2, zoom - 12) * 1.0); // Увеличенный коэффициент
        
        // Размер маркера в пикселях
        float calculatedSize = (float) (vesselSize * pixelsPerMeter);
        
        // Ограничиваем размер маркера, но с более высоким минимумом
        float minSize = Math.max(CLOSE_ZOOM_SIZE, MIN_MARKER_SIZE);
        return Math.max(minSize, Math.min(MAX_MARKER_SIZE, calculatedSize));
    }
}
