package com.grigowashere.aismap.view;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.grigowashere.aismap.R;
import com.grigowashere.aismap.models.Vessel;
import com.grigowashere.aismap.models.AISVessel;
import com.grigowashere.aismap.utils.GeoUtils;

/**
 * Overlay для отображения курсора на карте с координатами и информацией о расстоянии
 */
public class CursorOverlay {
    
    private Context context;
    private View overlayView;
    private TextView tvCursorLatitude;
    private TextView tvCursorLongitude;
    private TextView tvDistance;
    private TextView tvBearing;
    private LinearLayout coordinatesPanel;
    private LinearLayout distanceBearingPanel;
    private LinearLayout aisVesselInfoPanel;
    
    // AIS vessel info TextViews
    private TextView tvAisMmsi;
    private TextView tvAisName;
    private TextView tvAisCallSign;
    private TextView tvAisCog;
    private TextView tvAisSog;
    
    private Vessel ownVessel;
    private AISVessel currentAisVessel;
    private double cursorLatitude;
    private double cursorLongitude;
    
    // Размеры экрана для расчета позиций
    private int screenWidth;
    private int screenHeight;
    private int centerX;
    private int centerY;
    
    // Отступы от центра
    private static final int COORDINATES_OFFSET_X = -60;
    private static final int COORDINATES_OFFSET_Y = -210;
    private static final int DISTANCE_OFFSET_X = 60;
    private static final int DISTANCE_OFFSET_Y = 60;
    private static final int AIS_INFO_OFFSET_X = -60;
    private static final int AIS_INFO_OFFSET_Y = 60;
    
    public CursorOverlay(Context context) {
        this.context = context;
        initializeViews();
    }
    
    private void initializeViews() {
        LayoutInflater inflater = LayoutInflater.from(context);
        overlayView = inflater.inflate(R.layout.cursor, null);
        // Помечаем overlay для последующего обнаружения/удаления
        overlayView.setTag("cursor_overlay");
        
        tvCursorLatitude = overlayView.findViewById(R.id.tv_cursor_latitude);
        tvCursorLongitude = overlayView.findViewById(R.id.tv_cursor_longitude);
        tvDistance = overlayView.findViewById(R.id.tv_distance);
        tvBearing = overlayView.findViewById(R.id.tv_bearing);
        coordinatesPanel = overlayView.findViewById(R.id.coordinates_panel);
        distanceBearingPanel = overlayView.findViewById(R.id.distance_bearing_panel);
        aisVesselInfoPanel = overlayView.findViewById(R.id.ais_vessel_info_panel);
        
        // Initialize AIS vessel info TextViews
        tvAisMmsi = overlayView.findViewById(R.id.tv_ais_mmsi);
        tvAisName = overlayView.findViewById(R.id.tv_ais_name);
        tvAisCallSign = overlayView.findViewById(R.id.tv_ais_call_sign);
        tvAisCog = overlayView.findViewById(R.id.tv_ais_cog);
        tvAisSog = overlayView.findViewById(R.id.tv_ais_sog);
        
        // По умолчанию курсор скрыт
        overlayView.setVisibility(View.GONE);
    }
    
    public View getView() {
        return overlayView;
    }
    
    /**
     * Устанавливает размеры экрана для расчета позиций панелей
     */
    public void setScreenDimensions(int width, int height) {
        this.screenWidth = width;
        this.screenHeight = height;
        this.centerX = width / 2;
        this.centerY = height / 2;
        
        // Обновляем позиции всех панелей
        updatePanelPositions();
    }
    
    /**
     * Обновляет позиции всех панелей относительно центра экрана
     */
    private void updatePanelPositions() {
        if (centerX == 0 || centerY == 0) {
            return; // Размеры экрана еще не установлены
        }
        
        android.util.Log.d("CursorOverlay", "updatePanelPositions: обновляем позиции панелей");
        
        // Позиционируем панель координат (верхний левый квадрант) - растет влево
        positionPanel(coordinatesPanel, COORDINATES_OFFSET_X, COORDINATES_OFFSET_Y, false, true);
        
        // Позиционируем панель расстояния и пеленга (нижний правый квадрант) - растет вправо
        positionPanel(distanceBearingPanel, DISTANCE_OFFSET_X, DISTANCE_OFFSET_Y, true, true);
        
        // НЕ позиционируем AIS панель здесь - она обновляется в updateAisVesselInfo
        android.util.Log.d("CursorOverlay", "updatePanelPositions: пропускаем AIS панель, она обновляется отдельно");
    }
    
    /**
     * Позиционирует панель относительно центра экрана
     * @param panel панель для позиционирования
     * @param offsetX смещение по X от центра
     * @param offsetY смещение по Y от центра
     * @param alignLeft выравнивать ли по левому краю (иначе по правому)
     * @param alignTop выравнивать ли по верхнему краю (иначе по нижнему)
     */
    private void positionPanel(View panel, int offsetX, int offsetY, boolean alignLeft, boolean alignTop) {
        android.util.Log.d("CursorOverlay", String.format("positionPanel: panel=%s, centerX=%d, centerY=%d", 
            panel != null ? panel.getClass().getSimpleName() : "null", centerX, centerY));
        
        if (panel == null || centerX == 0 || centerY == 0) {
            android.util.Log.d("CursorOverlay", "positionPanel: выход - panel=null или размеры экрана не установлены");
            return;
        }
        
        // Измеряем размеры панели
        panel.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        int panelWidth = panel.getMeasuredWidth();
        int panelHeight = panel.getMeasuredHeight();
        
        android.util.Log.d("CursorOverlay", String.format("positionPanel: размеры панели width=%d, height=%d", panelWidth, panelHeight));
        
        // Если панель еще не измерена, используем ViewTreeObserver
        if (panelWidth == 0 || panelHeight == 0) {
            android.util.Log.d("CursorOverlay", String.format("positionPanel: панель не измерена (width=%d, height=%d), ждем layout", panelWidth, panelHeight));
            panel.getViewTreeObserver().addOnGlobalLayoutListener(new android.view.ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    panel.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    android.util.Log.d("CursorOverlay", "positionPanel: layout готов, повторяем позиционирование");
                    positionPanel(panel, offsetX, offsetY, alignLeft, alignTop);
                }
            });
            return;
        }
        
        // Рассчитываем финальную позицию с учетом выравнивания
        int finalX, finalY;
        
        if (alignLeft) {
            // Для левого выравнивания: левый край панели на offsetX от центра
            finalX = centerX + offsetX;
        } else {
            // Для правого выравнивания: правый край панели на offsetX от центра
            finalX = centerX + offsetX - panelWidth;
        }
        
        if (alignTop) {
            // Для верхнего выравнивания: верхний край панели на offsetY от центра
            finalY = centerY + offsetY;
        } else {
            // Для нижнего выравнивания: нижний край панели на offsetY от центра
            finalY = centerY + offsetY - panelHeight;
        }
        
        android.util.Log.d("CursorOverlay", String.format("positionPanel: финальные координаты finalX=%d, finalY=%d, alignLeft=%b, alignTop=%b", 
            finalX, finalY, alignLeft, alignTop));
        
        // Устанавливаем позицию через LayoutParams
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        );
        
        params.leftMargin = finalX;
        params.topMargin = finalY;
        
        // Убираем все правила выравнивания, которые могут конфликтовать
        params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
        params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
        params.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
        params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0);
        params.addRule(RelativeLayout.CENTER_IN_PARENT, 0);
        params.addRule(RelativeLayout.CENTER_HORIZONTAL, 0);
        params.addRule(RelativeLayout.CENTER_VERTICAL, 0);
        
        panel.setLayoutParams(params);
        android.util.Log.d("CursorOverlay", "positionPanel: LayoutParams установлены");
        
        // Альтернативный способ - используем setX/setY
        panel.setX(finalX);
        panel.setY(finalY);
        android.util.Log.d("CursorOverlay", String.format("positionPanel: setX/setY установлены: x=%.1f, y=%.1f", panel.getX(), panel.getY()));
        
        // Принудительно обновляем layout
        panel.requestLayout();
        android.util.Log.d("CursorOverlay", "positionPanel: requestLayout вызван");
        
        // Принудительно обновляем layout родителя
        if (panel.getParent() instanceof ViewGroup) {
            ((ViewGroup) panel.getParent()).requestLayout();
            android.util.Log.d("CursorOverlay", "positionPanel: requestLayout родителя вызван");
        }
        
        // Принудительно поднимаем AIS панель наверх
        if (panel == aisVesselInfoPanel) {
            panel.bringToFront();
            panel.setElevation(20f); // Принудительно поднимаем elevation выше курсора
            android.util.Log.d("CursorOverlay", "positionPanel: AIS панель поднята наверх с elevation=20");
            
            // Принудительно поднимаем панель над курсором
            View cursorCross = overlayView.findViewById(R.id.cursor_cross);
            if (cursorCross != null) {
                cursorCross.setElevation(5f); // Курсор ниже AIS панели
                android.util.Log.d("CursorOverlay", "positionPanel: курсор опущен с elevation=5");
            }
            
            // Проверяем видимость панели
            android.util.Log.d("CursorOverlay", String.format("positionPanel AIS: видимость=%d, alpha=%.2f, x=%.1f, y=%.1f", 
                panel.getVisibility(), panel.getAlpha(), panel.getX(), panel.getY()));
            
            // Проверяем позицию после всех операций
            panel.post(() -> {
                android.util.Log.d("CursorOverlay", String.format("positionPanel AIS: финальная позиция x=%.1f, y=%.1f, width=%d, height=%d", 
                    panel.getX(), panel.getY(), panel.getWidth(), panel.getHeight()));
                
                // Проверяем, не выходит ли панель за границы экрана
                float right = panel.getX() + panel.getWidth();
                float bottom = panel.getY() + panel.getHeight();
                android.util.Log.d("CursorOverlay", String.format("positionPanel AIS: границы панели left=%.1f, top=%.1f, right=%.1f, bottom=%.1f", 
                    panel.getX(), panel.getY(), right, bottom));
                android.util.Log.d("CursorOverlay", String.format("positionPanel AIS: размеры экрана width=%d, height=%d", 
                    screenWidth, screenHeight));
                
                // Проверяем, выходит ли панель за границы экрана
                boolean outOfBounds = panel.getX() < 0 || panel.getY() < 0 || right > screenWidth || bottom > screenHeight;
                android.util.Log.d("CursorOverlay", String.format("positionPanel AIS: панель за границами экрана=%b", outOfBounds));
                
                if (outOfBounds) {
                    android.util.Log.w("CursorOverlay", String.format("positionPanel AIS: ПРОБЛЕМА! Панель выходит за границы экрана!"));
                    android.util.Log.w("CursorOverlay", String.format("positionPanel AIS: left=%.1f < 0? %b", panel.getX(), panel.getX() < 0));
                    android.util.Log.w("CursorOverlay", String.format("positionPanel AIS: top=%.1f < 0? %b", panel.getY(), panel.getY() < 0));
                    android.util.Log.w("CursorOverlay", String.format("positionPanel AIS: right=%.1f > %d? %b", right, screenWidth, right > screenWidth));
                    android.util.Log.w("CursorOverlay", String.format("positionPanel AIS: bottom=%.1f > %d? %b", bottom, screenHeight, bottom > screenHeight));
                }
                
                // Проверяем видимость панели
                android.util.Log.d("CursorOverlay", String.format("positionPanel AIS: видимость=%d, alpha=%.2f, elevation=%.1f", 
                    panel.getVisibility(), panel.getAlpha(), panel.getElevation()));
                
                // Проверяем фон панели
                android.util.Log.d("CursorOverlay", String.format("positionPanel AIS: фон панели=%s", 
                    panel.getBackground() != null ? panel.getBackground().getClass().getSimpleName() : "null"));
            });
        }
        
        // Отладочная информация для AIS панели
        if (panel == aisVesselInfoPanel) {
            android.util.Log.d("CursorOverlay", String.format("positionPanel AIS: centerX=%d, centerY=%d, offsetX=%d, offsetY=%d, panelWidth=%d, panelHeight=%d, finalX=%d, finalY=%d, alignLeft=%b, alignTop=%b", 
                centerX, centerY, offsetX, offsetY, panelWidth, panelHeight, finalX, finalY, alignLeft, alignTop));
        }
    }
    
    /**
     * Обновляет координаты курсора (центра экрана)
     */
    public void updateCursorCoordinates(double latitude, double longitude) {
        this.cursorLatitude = latitude;
        this.cursorLongitude = longitude;
        
        tvCursorLatitude.setText(String.format("%.6f°", latitude));
        tvCursorLongitude.setText(String.format("%.6f°", longitude));
        
        // Обновляем позицию панели координат после изменения содержимого
        coordinatesPanel.post(() -> positionPanel(coordinatesPanel, COORDINATES_OFFSET_X, COORDINATES_OFFSET_Y, false, true));
        
        // Обновляем информацию о расстоянии и пеленге, если есть данные о нашем судне
        updateDistanceAndBearing();
    }
    
    /**
     * Устанавливает данные о нашем судне для расчета расстояния и пеленга
     */
    public void setOwnVessel(Vessel vessel) {
        this.ownVessel = vessel;
        updateDistanceAndBearing();
    }
    
    /**
     * Обновляет информацию о расстоянии и пеленге
     */
    private void updateDistanceAndBearing() {
        if (ownVessel != null && isValidPosition(ownVessel)) {
            double distance = GeoUtils.calculateDistance(
                ownVessel.getLatitude(), ownVessel.getLongitude(),
                cursorLatitude, cursorLongitude
            );
            
            // Вычисляем пеленг от судна к курсору
            double bearingToCursor = GeoUtils.calculateBearing(
                ownVessel.getLatitude(), ownVessel.getLongitude(),
                cursorLatitude, cursorLongitude
            );
            
            // Вычисляем относительный пеленг
            double relativeBearing;
            if (ownVessel.getCourse() > 0) {
                relativeBearing = GeoUtils.calculateRelativeBearing(ownVessel.getCourse(), bearingToCursor);
            } else {
                // Если курс неизвестен, показываем абсолютный пеленг
                relativeBearing = bearingToCursor;
            }
            
            // Форматируем расстояние
            String distanceText = "Rng: " + GeoUtils.formatDistance(distance);
            
            tvDistance.setText(distanceText);
            tvBearing.setText(String.format("Brg: %.1f°", relativeBearing));
            
            // Показываем информацию о расстоянии и пеленге
            tvDistance.setVisibility(View.VISIBLE);
            tvBearing.setVisibility(View.VISIBLE);
            
            // Обновляем позицию панели после изменения содержимого
            distanceBearingPanel.post(() -> positionPanel(distanceBearingPanel, DISTANCE_OFFSET_X, DISTANCE_OFFSET_Y, true, true));
        } else {
            // Скрываем информацию, если нет валидных координат нашего судна
            tvDistance.setVisibility(View.GONE);
            tvBearing.setVisibility(View.GONE);
        }
    }
    
    
    /**
     * Скрывает курсор
     */
    public void hideCursor() {
        if (overlayView != null) {
            overlayView.setVisibility(View.GONE);
            // Также скрываем панели, чтобы исключить ложное наложение
            if (aisVesselInfoPanel != null) aisVesselInfoPanel.setVisibility(View.GONE);
            if (coordinatesPanel != null) coordinatesPanel.clearAnimation();
            if (distanceBearingPanel != null) distanceBearingPanel.clearAnimation();
        }
    }
    
    /**
     * Показывает курсор
     */
    public void showCursor() {
        if (overlayView != null) {
            overlayView.setVisibility(View.VISIBLE);
            // Поднимем overlay над картой
            overlayView.bringToFront();
            overlayView.setElevation(10f);
            // Гарантируем, что крест выше, а панель AIS ещё выше
            View cursorCross = overlayView.findViewById(R.id.cursor_cross);
            if (cursorCross != null) {
                cursorCross.setElevation(12f);
            }
            if (aisVesselInfoPanel != null) {
                aisVesselInfoPanel.bringToFront();
                aisVesselInfoPanel.setElevation(20f);
            }
        }
    }
    
    /**
     * Устанавливает информацию об AIS судне под курсором
     */
    public void setAisVesselInfo(AISVessel vessel) {
        android.util.Log.d("CursorOverlay", String.format("setAisVesselInfo: получили судно %s", 
            vessel != null ? vessel.getMmsi() : "null"));
        this.currentAisVessel = vessel;
        updateAisVesselInfo();
    }
    
    /**
     * Обновляет отображение информации об AIS судне
     */
    ///TO DO у нас тут ошибка после смены активности, надо ее исправить
    private void updateAisVesselInfo() {
        android.util.Log.d("CursorOverlay", String.format("updateAisVesselInfo: обновляем информацию, судно=%s", 
            currentAisVessel != null ? currentAisVessel.getMmsi() : "null"));
        if (currentAisVessel != null) {
            // MMSI
            tvAisMmsi.setText("MMSI: " + currentAisVessel.getMmsi());
            
            // Название
            String name = currentAisVessel.getVesselName();
            if (name != null && !name.trim().isEmpty()) {
                tvAisName.setText("Название: " + name);
                tvAisName.setVisibility(View.VISIBLE);
            } else {
                tvAisName.setVisibility(View.GONE);
            }
            
            // Позывной
            String callSign = currentAisVessel.getCallSign();
            if (callSign != null && !callSign.trim().isEmpty()) {
                tvAisCallSign.setText("Позывной: " + callSign);
                tvAisCallSign.setVisibility(View.VISIBLE);
            } else {
                tvAisCallSign.setVisibility(View.GONE);
            }
            
            // COG (курс)
            if (currentAisVessel.getCourse() > 0) {
                tvAisCog.setText(String.format("COG: %.1f°", currentAisVessel.getCourse()));
                tvAisCog.setVisibility(View.VISIBLE);
            } else {
                tvAisCog.setVisibility(View.GONE);
            }
            
            // SOG (скорость)
            if (currentAisVessel.getSpeed() > 0) {
                tvAisSog.setText(String.format("SOG: %.1f уз", currentAisVessel.getSpeed()));
                tvAisSog.setVisibility(View.VISIBLE);
            } else {
                tvAisSog.setVisibility(View.GONE);
            }
            
            // Показываем панель СНАЧАЛА
            android.util.Log.d("CursorOverlay", String.format("updateAisVesselInfo: ДО установки видимости - видимость=%d, alpha=%.2f", 
                aisVesselInfoPanel.getVisibility(), aisVesselInfoPanel.getAlpha()));
            
            aisVesselInfoPanel.setVisibility(View.VISIBLE);
            
            android.util.Log.d("CursorOverlay", String.format("updateAisVesselInfo: ПОСЛЕ установки видимости - видимость=%d, alpha=%.2f", 
                aisVesselInfoPanel.getVisibility(), aisVesselInfoPanel.getAlpha()));
            
            // Обновляем позицию после изменения содержимого
            android.util.Log.d("CursorOverlay", String.format("updateAisVesselInfo: родитель панели=%s", 
                aisVesselInfoPanel.getParent() != null ? aisVesselInfoPanel.getParent().getClass().getSimpleName() : "null"));
            
            // Вызываем позиционирование
            android.util.Log.d("CursorOverlay", "updateAisVesselInfo: вызываем positionPanel");
            positionPanel(aisVesselInfoPanel, AIS_INFO_OFFSET_X, AIS_INFO_OFFSET_Y, false, true);
            
            // Проверяем видимость после позиционирования
            android.util.Log.d("CursorOverlay", String.format("updateAisVesselInfo: после позиционирования - видимость=%d, alpha=%.2f, x=%.1f, y=%.1f", 
                aisVesselInfoPanel.getVisibility(), aisVesselInfoPanel.getAlpha(), 
                aisVesselInfoPanel.getX(), aisVesselInfoPanel.getY()));
            
            // Проверяем содержимое панели
            android.util.Log.d("CursorOverlay", String.format("updateAisVesselInfo: содержимое панели - MMSI=%s, Name=%s, CallSign=%s, COG=%.1f, SOG=%.1f", 
                currentAisVessel.getMmsi(),
                currentAisVessel.getVesselName() != null ? currentAisVessel.getVesselName() : "null",
                currentAisVessel.getCallSign() != null ? currentAisVessel.getCallSign() : "null",
                currentAisVessel.getCourse(),
                currentAisVessel.getSpeed()));
            
            // Проверяем видимость элементов панели
            android.util.Log.d("CursorOverlay", String.format("updateAisVesselInfo: видимость элементов - MMSI=%d, Name=%d, CallSign=%d, COG=%d, SOG=%d", 
                tvAisMmsi.getVisibility(),
                tvAisName.getVisibility(),
                tvAisCallSign.getVisibility(),
                tvAisCog.getVisibility(),
                tvAisSog.getVisibility()));
            
            // Проверяем видимость родительских контейнеров
            if (overlayView != null) {
                android.util.Log.d("CursorOverlay", String.format("updateAisVesselInfo: overlayView видимость=%d, alpha=%.2f", 
                    overlayView.getVisibility(), overlayView.getAlpha()));
            }
            if (aisVesselInfoPanel.getParent() != null) {
                android.util.Log.d("CursorOverlay", String.format("updateAisVesselInfo: родитель панели видимость=%d, alpha=%.2f", 
                    ((View) aisVesselInfoPanel.getParent()).getVisibility(), ((View) aisVesselInfoPanel.getParent()).getAlpha()));
            }
        } else {
            // Скрываем панель
            aisVesselInfoPanel.setVisibility(View.GONE);
            android.util.Log.d("CursorOverlay", "updateAisVesselInfo: скрываем панель");
        }
    }
    
    /**
     * Очищает информацию об AIS судне
     */
    public void clearAisVesselInfo() {
        android.util.Log.d("CursorOverlay", "clearAisVesselInfo: очищаем информацию о судне");
        this.currentAisVessel = null;
        aisVesselInfoPanel.setVisibility(View.GONE);
    }
    
    /**
     * Проверяет валидность позиции судна
     */
    private boolean isValidPosition(Vessel vessel) {
        if (vessel == null) return false;
        
        return GeoUtils.isValidCoordinates(vessel.getLatitude(), vessel.getLongitude());
    }
}
