package com.grigowashere.aismap.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import com.grigowashere.aismap.models.Vessel;

public class CoordinatesDockWidget extends BaseDockWidget {
    private static final String TAG = "CoordinatesDockWidget";
    
    // Цвета
    private static final int BACKGROUND_COLOR = 0xD91A1F24; // Полупрозрачный тёмный с лёгким синим
    private static final int TEXT_COLOR = 0xFFFFFFFF; // Белый
    private static final int LABEL_COLOR = 0xFF9AA4B2; // Серо-голубой
    private static final int ACCENT_COLOR = 0xFF4CAF50; // Зеленый
    private static final int WARNING_COLOR = 0xFFFF9800; // Оранжевый
    private static final int ERROR_COLOR = 0xFFF44336; // Красный

    // Кисти
    private Paint backgroundPaint;
    private Paint labelPaint;
    private Paint textPaint;
    private Paint accentPaint;
    private Paint warningPaint;
    private Paint errorPaint;
    private Paint dividerPaint;

    // Данные для отображения
    private Vessel vessel;
    private String coordinatesText = "--";
    private String sogText = "--";
    private String cogText = "--";
    private String accuracyText = "--";
    
    public CoordinatesDockWidget(Context context) {
        super(context);
        init();
    }
    
    public CoordinatesDockWidget(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    
    private void init() {
        backgroundPaint = new Paint();
        backgroundPaint.setColor(BACKGROUND_COLOR);
        backgroundPaint.setStyle(Paint.Style.FILL);
        backgroundPaint.setAntiAlias(true);

        labelPaint = new Paint();
        labelPaint.setColor(LABEL_COLOR);
        labelPaint.setTextSize(dp(11));
        labelPaint.setTypeface(Typeface.DEFAULT);
        labelPaint.setAntiAlias(true);
        labelPaint.setLetterSpacing(0.08f);

        textPaint = new Paint();
        textPaint.setColor(TEXT_COLOR);
        textPaint.setTextSize(dp(16));
        textPaint.setTypeface(Typeface.DEFAULT_BOLD);
        textPaint.setAntiAlias(true);

        accentPaint = new Paint();
        accentPaint.setColor(ACCENT_COLOR);
        accentPaint.setTextSize(dp(16));
        accentPaint.setTypeface(Typeface.DEFAULT_BOLD);
        accentPaint.setAntiAlias(true);

        warningPaint = new Paint();
        warningPaint.setColor(WARNING_COLOR);
        warningPaint.setTextSize(dp(16));
        warningPaint.setTypeface(Typeface.DEFAULT_BOLD);
        warningPaint.setAntiAlias(true);

        errorPaint = new Paint();
        errorPaint.setColor(ERROR_COLOR);
        errorPaint.setTextSize(dp(16));
        errorPaint.setTypeface(Typeface.DEFAULT_BOLD);
        errorPaint.setAntiAlias(true);

        dividerPaint = new Paint();
        dividerPaint.setColor(0x33FFFFFF);
        dividerPaint.setStrokeWidth(dp(1));
        dividerPaint.setAntiAlias(true);

        // Фон самой view держим прозрачным — в dock/circle режиме фон
        // рисуем вручную в onDraw*, иначе в round-режиме виден чёрный
        // квадрат вокруг окружности.
        setBackgroundColor(android.graphics.Color.TRANSPARENT);
    }
    
    /**
     * Обновляет данные судна
     */
    public void updateVessel(Vessel vessel) {
        Log.d(TAG, "updateVessel called with vessel: " + (vessel != null ? "not null" : "null"));
        if (vessel != null) {
            Log.d(TAG, "Vessel data: lat=" + vessel.getLatitude() + 
                  ", lon=" + vessel.getLongitude() + 
                  ", speed=" + vessel.getSpeed() + 
                  ", course=" + vessel.getCourse());
        }
        this.vessel = vessel;
        updateDisplayText();
        invalidate();
    }
    
    /**
     * Обновляет текст для отображения
     */
    private void updateDisplayText() {
        if (vessel == null) {
            coordinatesText = "--";
            sogText = "--";
            cogText = "--";
            accuracyText = "--";
            return;
        }

        if (vessel.getLatitude() != 0 || vessel.getLongitude() != 0) {
            coordinatesText = formatLatLon(vessel.getLatitude(), vessel.getLongitude());
        } else {
            coordinatesText = "нет фикса";
        }

        if (vessel.getSpeed() > 0.05) {
            sogText = String.format(java.util.Locale.US, "%.1f kn", vessel.getSpeed());
        } else {
            sogText = "0.0 kn";
        }

        if (vessel.getCourse() > 0 || vessel.getSpeed() > 0.05) {
            cogText = String.format(java.util.Locale.US, "%.0f\u00B0", vessel.getCourse());
        } else {
            cogText = "---\u00B0";
        }

        float acc = vessel.getAccuracy();
        if (acc > 0f) {
            accuracyText = String.format(java.util.Locale.US, "\u00B1%.1f m", acc);
        } else {
            accuracyText = "--";
        }
    }

    private String formatLatLon(double lat, double lon) {
        char latHemi = lat >= 0 ? 'N' : 'S';
        char lonHemi = lon >= 0 ? 'E' : 'W';
        double absLat = Math.abs(lat);
        double absLon = Math.abs(lon);
        int latDeg = (int) absLat;
        double latMin = (absLat - latDeg) * 60.0;
        int lonDeg = (int) absLon;
        double lonMin = (absLon - lonDeg) * 60.0;
        return String.format(java.util.Locale.US,
                "%02d\u00B0%06.3f'%c  %03d\u00B0%06.3f'%c",
                latDeg, latMin, latHemi, lonDeg, lonMin, lonHemi);
    }
    
    @Override
    protected void onDrawDock(Canvas canvas) {
        int width = getWidth();
        int height = getHeight();
        if (width <= 0 || height <= 0) {
            Log.w(TAG, "Invalid dimensions: width=" + width + ", height=" + height);
            return;
        }

        // Фон рисуем на всю область виджета (уезжает под нав-бар/вырез),
        // а контент — в рамках паддингов от WindowInsets.
        canvas.drawRect(0, 0, width, height, backgroundPaint);

        float left = getPaddingLeft();
        float top = getPaddingTop();
        float right = width - getPaddingRight();
        float bottom = height - getPaddingBottom();
        float contentW = Math.max(0f, right - left);
        float contentH = Math.max(0f, bottom - top);
        if (contentW <= 0 || contentH <= 0) return;

        // Верхняя тонкая разделительная линия (виджет снизу): визуальная
        // граница между картой и панелью.
        if (!isDockTop()) {
            canvas.drawLine(left, top, right, top, dividerPaint);
        }

        float padX = dp(16);
        float innerLeft = left + padX;
        float innerRight = right - padX;
        float innerTop = top + dp(8);
        float innerBottom = bottom - dp(8);

        // Строка 1: координаты (с подписью "POSITION").
        Paint posPaint = getCoordinatesPaint();
        float labelH = labelPaint.getTextSize() * 1.1f;
        float valueH = posPaint.getTextSize() * 1.15f;

        float y = innerTop + labelH;
        canvas.drawText("POSITION", innerLeft, y, labelPaint);
        y += valueH;
        canvas.drawText(coordinatesText, innerLeft, y, posPaint);

        // Строка 2: SOG | COG | ACC в три колонки.
        float colTop = y + dp(10);
        float colW = (innerRight - innerLeft) / 3f;
        float colLabelY = colTop + labelH;
        float colValueY = colLabelY + valueH;

        // SOG
        canvas.drawText("SOG", innerLeft, colLabelY, labelPaint);
        canvas.drawText(sogText, innerLeft, colValueY, getSOGPaint());

        // COG
        float cogX = innerLeft + colW;
        canvas.drawText("COG", cogX, colLabelY, labelPaint);
        canvas.drawText(cogText, cogX, colValueY, getCOGPaint());

        // ACC
        float accX = innerLeft + colW * 2f;
        canvas.drawText("ACC", accX, colLabelY, labelPaint);
        canvas.drawText(accuracyText, accX, colValueY, getAccuracyPaint());

        if (colValueY > innerBottom) {
            // На всякий случай: если текст не помещается, оставляем только
            // первую строку (координаты).
        }
    }

    @Override
    protected void onDrawCircle(Canvas canvas) {
        int width = getWidth();
        int height = getHeight();
        int centerX = width / 2;
        int centerY = height / 2;
        int radius = Math.min(width, height) / 2 - (int) dp(4);

        canvas.drawCircle(centerX, centerY, radius, backgroundPaint);

        Paint borderPaint = new Paint();
        borderPaint.setColor(ACCENT_COLOR);
        borderPaint.setStyle(Paint.Style.STROKE);
        borderPaint.setStrokeWidth(dp(2));
        borderPaint.setAntiAlias(true);
        canvas.drawCircle(centerX, centerY, radius, borderPaint);

        // Более компактная вёрстка: 4 строки (POS lat / POS lon / SOG·COG / ACC)
        Paint posPaint = getCoordinatesPaint();
        float smallLabel = dp(9);
        float smallValue = dp(11);
        float bigValue = dp(13);
        labelPaint.setTextSize(smallLabel);
        posPaint.setTextSize(smallValue);
        Paint sogPaint = getSOGPaint();
        Paint cogPaint = getCOGPaint();
        Paint accPaint = getAccuracyPaint();
        sogPaint.setTextSize(bigValue);
        cogPaint.setTextSize(bigValue);
        accPaint.setTextSize(smallValue);

        String[] latLon = coordinatesText.split("  ", 2);
        String latLine = latLon.length > 0 ? latLon[0] : coordinatesText;
        String lonLine = latLon.length > 1 ? latLon[1] : "";

        float lineGap = dp(2);
        float lineH = smallValue + lineGap;

        // Считаем общую высоту блока для вертикального центрирования.
        float totalH = smallLabel + lineH + lineH // POSITION + 2 строки
                + dp(6)
                + smallLabel + bigValue + lineGap // SOG/COG label+value
                + dp(4)
                + smallLabel + smallValue; // ACC

        float y = centerY - totalH / 2f + smallLabel;

        drawCentered(canvas, "POSITION", centerX, y, labelPaint);
        y += lineH;
        drawCentered(canvas, latLine, centerX, y, posPaint);
        y += lineH;
        if (!lonLine.isEmpty()) {
            drawCentered(canvas, lonLine, centerX, y, posPaint);
            y += lineH;
        }
        y += dp(4);

        // SOG / COG бок о бок.
        float colCenterL = centerX - radius * 0.45f;
        float colCenterR = centerX + radius * 0.45f;
        drawCentered(canvas, "SOG", colCenterL, y, labelPaint);
        drawCentered(canvas, "COG", colCenterR, y, labelPaint);
        y += bigValue + lineGap;
        drawCentered(canvas, sogText, colCenterL, y, sogPaint);
        drawCentered(canvas, cogText, colCenterR, y, cogPaint);
        y += dp(6);

        drawCentered(canvas, "ACC", centerX, y, labelPaint);
        y += smallValue + lineGap;
        drawCentered(canvas, accuracyText, centerX, y, accPaint);

        // Восстанавливаем типовые размеры для dock-режима.
        labelPaint.setTextSize(dp(11));
        textPaint.setTextSize(dp(16));
        accentPaint.setTextSize(dp(16));
        warningPaint.setTextSize(dp(16));
        errorPaint.setTextSize(dp(16));
    }

    private void drawCentered(Canvas canvas, String text, float cx, float y, Paint p) {
        if (text == null) return;
        Rect b = new Rect();
        p.getTextBounds(text, 0, text.length(), b);
        canvas.drawText(text, cx - b.width() / 2f - b.left, y, p);
    }
    
    /**
     * Определяет цвет для отображения координат
     */
    private Paint getCoordinatesPaint() {
        if (vessel == null || vessel.getLatitude() == 0 || vessel.getLongitude() == 0) {
            return errorPaint;
        }
        
        // Проверяем точность GPS
        if (vessel.getAccuracy() > 0) {
            if (vessel.getAccuracy() <= 5) {
                return accentPaint; // Высокая точность - зеленый
            } else if (vessel.getAccuracy() <= 20) {
                return warningPaint; // Средняя точность - оранжевый
            } else {
                return errorPaint; // Низкая точность - красный
            }
        }
        
        return textPaint; // По умолчанию - белый
    }
    
    /**
     * Определяет цвет для отображения SOG
     */
    private Paint getSOGPaint() {
        if (vessel == null || vessel.getSpeed() <= 0) {
            return errorPaint;
        }
        
        return accentPaint; // Если есть данные о скорости - зеленый
    }
    
    /**
     * Определяет цвет для отображения COG
     */
    private Paint getCOGPaint() {
        if (vessel == null) return errorPaint;
        // Курс может быть 0 при движении чётко на север — поэтому считаем
        // валидным любой курс при наличии скорости, а также любой курс > 0.
        if (vessel.getCourse() > 0 || vessel.getSpeed() > 0.05) {
            return textPaint;
        }
        return errorPaint;
    }

    /**
     * Определяет цвет для отображения точности (ACC, ±метры).
     */
    private Paint getAccuracyPaint() {
        if (vessel == null) return errorPaint;
        float acc = vessel.getAccuracy();
        if (acc <= 0f) return errorPaint;
        if (acc <= 5f) return accentPaint;
        if (acc <= 20f) return warningPaint;
        return errorPaint;
    }
    
    /**
     * Получает высоту виджета в dock-режиме
     */
    public int getDockHeight() {
        if (isDocked()) {
            return getHeight();
        }
        return (int) dp(DEFAULT_DOCK_HEIGHT_DP);
    }
}
