package com.grigowashere.aismap.models;

import java.time.LocalDateTime;

/**
 * Модель нашего судна
 */
public class Vessel {
    private double latitude;
    private double longitude;
    private double course; // курс в градусах (0-360)
    private double speed; // скорость в узлах
    private double heading; // направление движения в градусах
    private double magneticCompass; // магнитный компас в градусах (0-360)
    private int signalStrength; // сила сигнала GPS (0-100)
    private LocalDateTime lastUpdate;
    private String vesselName;
    private String mmsi; // Maritime Mobile Service Identity
    private String callSign; // позывной
    private double altitude; // высота над уровнем моря
    private int satellites; // общее количество спутников
    private int activeSatellites; // количество активных спутников в фиксе
    
    // DOP (Dilution of Precision) - показатели качества GPS
    private double pdop; // Position DOP - общая точность позиции
    private double hdop; // Horizontal DOP - точность по горизонтали
    private double vdop; // Vertical DOP - точность по вертикали
    
    // Дополнительные GPS параметры
    private float accuracy; // точность в метрах
    private long fixTime; // время последнего фикса
    private String fixQuality; // качество фикса (GPS, DGPS, RTK и т.д.)

    public Vessel() {
        this.lastUpdate = LocalDateTime.now();
        this.fixQuality = "NO_FIX";
        this.accuracy = -1.0f;
    }

    public Vessel(double latitude, double longitude) {
        this();
        this.latitude = latitude;
        this.longitude = longitude;
    }

    // Геттеры и сеттеры
    public double getLatitude() { return latitude; }
    public void setLatitude(double latitude) { this.latitude = latitude; }

    public double getLongitude() { return longitude; }
    public void setLongitude(double longitude) { this.longitude = longitude; }

    public double getCourse() { return course; }
    public void setCourse(double course) { this.course = course; }

    public double getSpeed() { return speed; }
    public void setSpeed(double speed) { this.speed = speed; }

    public double getHeading() { return heading; }
    public void setHeading(double heading) { this.heading = heading; }

    public double getMagneticCompass() { return magneticCompass; }
    public void setMagneticCompass(double magneticCompass) { this.magneticCompass = magneticCompass; }

    public int getSignalStrength() { return signalStrength; }
    public void setSignalStrength(int signalStrength) { this.signalStrength = signalStrength; }

    public LocalDateTime getLastUpdate() { return lastUpdate; }
    public void setLastUpdate(LocalDateTime lastUpdate) { this.lastUpdate = lastUpdate; }

    public String getVesselName() { return vesselName; }
    public void setVesselName(String vesselName) { this.vesselName = vesselName; }

    public String getMmsi() { return mmsi; }
    public void setMmsi(String mmsi) { this.mmsi = mmsi; }

    public String getCallSign() { return callSign; }
    public void setCallSign(String callSign) { this.callSign = callSign; }

    public double getAltitude() { return altitude; }
    public void setAltitude(double altitude) { this.altitude = altitude; }

    public int getSatellites() { return satellites; }
    public void setSatellites(int satellites) { this.satellites = satellites; }

    public int getActiveSatellites() { return activeSatellites; }
    public void setActiveSatellites(int activeSatellites) { this.activeSatellites = activeSatellites; }

    public double getPdop() { return pdop; }
    public void setPdop(double pdop) { this.pdop = pdop; }

    public double getHdop() { return hdop; }
    public void setHdop(double hdop) { this.hdop = hdop; }

    public double getVdop() { return vdop; }
    public void setVdop(double vdop) { this.vdop = vdop; }

    public float getAccuracy() { return accuracy; }
    public void setAccuracy(float accuracy) { this.accuracy = accuracy; }

    public long getFixTime() { return fixTime; }
    public void setFixTime(long fixTime) { this.fixTime = fixTime; }

    public String getFixQuality() { return fixQuality; }
    public void setFixQuality(String fixQuality) { this.fixQuality = fixQuality; }

    /**
     * Обновляет данные судна
     */
    public void updatePosition(double latitude, double longitude, double course, double speed) {
        this.latitude = latitude;
        this.longitude = longitude;
        this.course = course;
        this.speed = speed;
        this.lastUpdate = LocalDateTime.now();
    }

    /**
     * Обновляет GPS качество
     */
    public void updateGPSQuality(int satellites, int activeSatellites, double pdop, double hdop, double vdop, float accuracy) {
        this.satellites = satellites;
        this.activeSatellites = activeSatellites;
        this.pdop = pdop;
        this.hdop = hdop;
        this.vdop = vdop;
        this.accuracy = accuracy;
        this.lastUpdate = LocalDateTime.now();
    }

    /**
     * Получает качество GPS сигнала в процентах
     */
    public int getGPSQualityPercentage() {
        if (accuracy <= 0) return 0;
        if (accuracy <= 3) return 100;      // Отличное качество (≤3м)
        if (accuracy <= 5) return 90;       // Очень хорошее (≤5м)
        if (accuracy <= 10) return 80;      // Хорошее (≤10м)
        if (accuracy <= 20) return 60;      // Удовлетворительное (≤20м)
        if (accuracy <= 50) return 40;      // Плохое (≤50м)
        return 20;                          // Очень плохое (>50м)
    }

    /**
     * Получает текстовое описание качества GPS
     */
    public String getGPSQualityDescription() {
        int quality = getGPSQualityPercentage();
        if (quality >= 90) return "Отличное";
        if (quality >= 80) return "Очень хорошее";
        if (quality >= 60) return "Хорошее";
        if (quality >= 40) return "Удовлетворительное";
        if (quality >= 20) return "Плохое";
        return "Очень плохое";
    }

    @Override
    public String toString() {
        return "Vessel{" +
                "lat=" + latitude +
                ", lon=" + longitude +
                ", course=" + course +
                ", speed=" + speed +
                ", name='" + vesselName + '\'' +
                ", satellites=" + satellites + "/" + activeSatellites +
                ", accuracy=" + accuracy + "m" +
                ", quality=" + getGPSQualityDescription() +
                '}';
    }
}
