package com.grigowashere.aismap.models;

import java.io.Serializable;

/**
 * Модель точки пути судна
 * Содержит координаты, скорость и время прохождения
 */
public class VesselPathPoint implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    private double longitude;
    private double latitude;
    private float speed; // скорость в узлах
    private long timestamp; // время в миллисекундах
    
    public VesselPathPoint() {
        this.timestamp = System.currentTimeMillis();
    }
    
    public VesselPathPoint(double longitude, double latitude, float speed) {
        this.longitude = longitude;
        this.latitude = latitude;
        this.speed = speed;
        this.timestamp = System.currentTimeMillis();
    }
    
    public VesselPathPoint(double longitude, double latitude, float speed, long timestamp) {
        this.longitude = longitude;
        this.latitude = latitude;
        this.speed = speed;
        this.timestamp = timestamp;
    }
    
    // Геттеры и сеттеры
    public double getLongitude() {
        return longitude;
    }
    
    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }
    
    public double getLatitude() {
        return latitude;
    }
    
    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }
    
    public float getSpeed() {
        return speed;
    }
    
    public void setSpeed(float speed) {
        this.speed = speed;
    }
    
    public long getTimestamp() {
        return timestamp;
    }
    
    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }
    
    /**
     * Вычисляет расстояние до другой точки в метрах
     */
    public double distanceTo(VesselPathPoint other) {
        if (other == null) return 0;
        
        final int R = 6371000; // радиус Земли в метрах
        double lat1Rad = Math.toRadians(this.latitude);
        double lat2Rad = Math.toRadians(other.latitude);
        double deltaLatRad = Math.toRadians(other.latitude - this.latitude);
        double deltaLonRad = Math.toRadians(other.longitude - this.longitude);
        
        double a = Math.sin(deltaLatRad / 2) * Math.sin(deltaLatRad / 2) +
                   Math.cos(lat1Rad) * Math.cos(lat2Rad) *
                   Math.sin(deltaLonRad / 2) * Math.sin(deltaLonRad / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        
        return R * c;
    }
    
    /**
     * Вычисляет время между точками в секундах
     */
    public long timeDifferenceSeconds(VesselPathPoint other) {
        if (other == null) return 0;
        return Math.abs(this.timestamp - other.timestamp) / 1000;
    }
    
    @Override
    public String toString() {
        return String.format("VesselPathPoint{lon=%.6f, lat=%.6f, speed=%.1f, time=%d}", 
                           longitude, latitude, speed, timestamp);
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        
        VesselPathPoint that = (VesselPathPoint) obj;
        
        return Double.compare(that.longitude, longitude) == 0 &&
               Double.compare(that.latitude, latitude) == 0 &&
               Float.compare(that.speed, speed) == 0 &&
               timestamp == that.timestamp;
    }
    
    @Override
    public int hashCode() {
        int result;
        long temp;
        temp = Double.doubleToLongBits(longitude);
        result = (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(latitude);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        result = 31 * result + (speed != 0.0f ? Float.floatToIntBits(speed) : 0);
        result = 31 * result + (int) (timestamp ^ (timestamp >>> 32));
        return result;
    }
}
