package com.grigowashere.aismap.maps;

import android.content.Context;
import android.graphics.Color;

import com.grigowashere.aismap.models.Vessel;
import com.grigowashere.aismap.models.AISVessel;
import com.grigowashere.aismap.view.CursorOverlay;
import com.grigowashere.aismap.R;
import org.mapsforge.core.model.LatLong;
import org.mapsforge.map.android.view.MapView;
import org.mapsforge.map.layer.Layers;
import org.mapsforge.map.layer.overlay.Marker;
import org.mapsforge.map.model.Model;
import org.mapsforge.core.graphics.Bitmap;
import android.view.ViewGroup;

import java.util.HashMap;
import java.util.Map;

/**
 * Реализация карты для MapForge
 */
public class MapForgeImpl implements MapInterface {
    
    private Context context;
    private MapView mapView;
    private Layers layers;
    private MarkerClickListener markerClickListener;
    
    private Map<String, Marker> aisMarkers;
    private Marker ownVesselMarker;
    private CursorOverlay cursorOverlay;
    private Vessel ownVessel;
    
    public MapForgeImpl(Context context, MapView mapView) {
        this.context = context;
        this.mapView = mapView;
        this.aisMarkers = new HashMap<>();
        this.layers = mapView.getLayerManager().getLayers();
        this.cursorOverlay = new CursorOverlay(context);
        
        // Добавляем overlay курсора в MapView
        if (mapView instanceof ViewGroup) {
            ViewGroup parent = (ViewGroup) mapView;
            // Проверяем, не добавлен ли уже курсор
            if (parent.findViewById(R.id.cursor_cross) == null) {
                parent.addView(cursorOverlay.getView());
            }
        }
    }
    
    @Override
    public void initialize() {
        // MapForge уже инициализирован
        setupMapMovementListener();
    }
    
    @Override
    public void cleanup() {
        if (mapView != null) {
            mapView.destroy();
        }
    }
    
    @Override
    public void addOwnVesselMarker(Vessel vessel) {
        if (ownVesselMarker != null) {
            layers.remove(ownVesselMarker);
        }
        
        this.ownVessel = vessel;
        cursorOverlay.setOwnVessel(vessel);
        
        LatLong position = new LatLong(vessel.getLatitude(), vessel.getLongitude());
        org.mapsforge.core.graphics.Bitmap icon = createMapForgeIcon(Color.BLUE, vessel.getCourse());
        
        ownVesselMarker = new Marker(position, icon, 0, 0);
        // MapForge не поддерживает OnTapListener напрямую, нужно использовать другой подход
        
        layers.add(ownVesselMarker);
    }
    
    @Override
    public void updateOwnVesselPosition(Vessel vessel) {
        if (ownVesselMarker != null) {
            LatLong newPosition = new LatLong(vessel.getLatitude(), vessel.getLongitude());
            ownVesselMarker.setLatLong(newPosition);
            
            org.mapsforge.core.graphics.Bitmap icon = createMapForgeIcon(Color.BLUE, vessel.getCourse());
            ownVesselMarker.setBitmap(icon);
        }
        
        this.ownVessel = vessel;
        cursorOverlay.setOwnVessel(vessel);
    }
    
    @Override
    public void addAISVesselMarker(AISVessel vessel) {
        LatLong position = new LatLong(vessel.getLatitude(), vessel.getLongitude());
        // Используем heading вместо course для поворота маркера AIS судна
        double rotationAngle = vessel.getHeading() > 0 ? vessel.getHeading() : vessel.getCourse();
        org.mapsforge.core.graphics.Bitmap icon = createMapForgeIcon(Color.RED, rotationAngle);
        
        Marker marker = new Marker(position, icon, 0, 0);
        // MapForge не поддерживает OnTapListener напрямую
        
        layers.add(marker);
        aisMarkers.put(vessel.getMmsi(), marker);
    }
    
    @Override
    public void updateAISVesselPosition(AISVessel vessel) {
        Marker marker = aisMarkers.get(vessel.getMmsi());
        if (marker != null) {
            LatLong newPosition = new LatLong(vessel.getLatitude(), vessel.getLongitude());
            marker.setLatLong(newPosition);
            
            // Используем heading вместо course для поворота маркера AIS судна
            double rotationAngle = vessel.getHeading() > 0 ? vessel.getHeading() : vessel.getCourse();
            org.mapsforge.core.graphics.Bitmap icon = createMapForgeIcon(Color.RED, rotationAngle);
            marker.setBitmap(icon);
        }
    }
    
    @Override
    public void removeAISVesselMarker(String mmsi) {
        Marker marker = aisMarkers.remove(mmsi);
        if (marker != null) {
            layers.remove(marker);
        }
    }
    
    @Override
    public void clearAISVesselMarkers() {
        for (Marker marker : aisMarkers.values()) {
            layers.remove(marker);
        }
        aisMarkers.clear();
    }
    
    @Override
    public void centerOnPosition(double latitude, double longitude) {
        LatLong position = new LatLong(latitude, longitude);
        mapView.getModel().mapViewPosition.setCenter(position);
    }
    
    @Override
    public void setZoom(float zoom) {
        mapView.getModel().mapViewPosition.setZoomLevel((byte) zoom);
    }
    
    @Override
    public float getZoom() {
        return mapView.getModel().mapViewPosition.getZoomLevel();
    }
    
    @Override
    public void setBearing(float bearing) {
        // MapForge: нет прямой поддержки bearing у MapViewPosition — игнорируем
    }
    
    @Override
    public float getBearing() {
        // MapForge: возвращаем всегда север вверх
        return 0f;
    }
    
    @Override
    public void addLayer(String layerId, Object layerData) {
        // Реализация добавления слоев для MapForge
    }
    
    @Override
    public void removeLayer(String layerId) {
        // Реализация удаления слоев
    }
    
    @Override
    public void setMarkerClickListener(MarkerClickListener listener) {
        this.markerClickListener = listener;
    }
    
    @Override
    public void clearVesselPath() {
        // MapForge не поддерживает трекинг пути в данной реализации
        // Метод добавлен для совместимости с интерфейсом
        // В будущем можно добавить поддержку трекинга пути для MapForge
    }
    
    private org.mapsforge.core.graphics.Bitmap createMapForgeIcon(int color, double course) {
        // Создаем простую иконку для MapForge
        // В реальном приложении нужно конвертировать Android Bitmap в MapForge Bitmap
        // Пока возвращаем null - это заглушка
        return null;
    }
    
    @Override
    public void showCursor() {
        if (cursorOverlay != null) {
            // cursorOverlay.showCoordinates();
        }
    }
    
    @Override
    public void hideCursor() {
        if (cursorOverlay != null) {
            cursorOverlay.hideCursor();
        }
    }
    
    @Override
    public void updateCursorCoordinates(double latitude, double longitude) {
        if (cursorOverlay != null) {
            cursorOverlay.updateCursorCoordinates(latitude, longitude);
        }
    }
    
    @Override
    public void updateCursorFromMapCenter() {
        if (cursorOverlay != null && mapView != null) {
            // Получаем координаты центра карты
            LatLong center = mapView.getModel().mapViewPosition.getCenter();
            cursorOverlay.updateCursorCoordinates(center.latitude, center.longitude);
        }
    }
    
    /**
     * Настраивает слушатель движения карты для обновления курсора
     */
    private void setupMapMovementListener() {
        if (mapView != null) {
           // mapView.getModel().mapViewPosition.addObserver(new org.mapsforge.map.model.Observer() {
//                @Override
//                public void onChange() {
//                    // Обновляем координаты курсора при движении карты
//                    updateCursorFromMapCenter();
//                }
//            });
        }
    }
    
    @Override
    public void setAisVesselInfo(com.grigowashere.aismap.models.AISVessel vessel) {
        if (cursorOverlay != null) {
            cursorOverlay.setAisVesselInfo(vessel);
        }
    }

    @Override
    public void clearAisVesselInfo() {
        if (cursorOverlay != null) {
            cursorOverlay.clearAisVesselInfo();
        }
    }

    public MapView getMapView() {
        return mapView;
    }
}
