"""Telemetry data models."""

from datetime import datetime
from enum import Enum
from typing import Any
from uuid import UUID

from pydantic import BaseModel, Field


class DataType(str, Enum):
    """Supported telemetry data types.

    Mirrors the backend DataType enum and proto definition.
    """

    POSITION = "position"
    DEPTH = "depth"
    SPEED = "speed"
    COURSE = "course"
    HEADING = "heading"
    WATER_TEMP = "water_temp"
    AIR_TEMP = "air_temp"
    WIND_SPEED = "wind_speed"
    WIND_DIRECTION = "wind_direction"
    ENGINE_RPM = "engine_rpm"
    FUEL_RATE = "fuel_rate"
    FUEL_LEVEL = "fuel_level"
    BATTERY = "battery"
    PRESSURE = "pressure"
    HUMIDITY = "humidity"
    CATCH_WEIGHT = "catch_weight"
    CATCH_SPECIES = "catch_species"
    ALARM = "alarm"
    AIS = "ais"
    CUSTOM = "custom"


class TelemetryPoint(BaseModel):
    """Single telemetry data point.

    This is the canonical schema for all telemetry data, used for both
    ingestion (REST/gRPC) and query responses.

    Attributes:
        time: Timestamp of the measurement (UTC)
        vessel_id: Vessel identifier (UUID)
        tenant_id: Tenant identifier (UUID)
        data_type: Type of telemetry data
        latitude: Latitude in degrees (-90 to 90), required for POSITION type
        longitude: Longitude in degrees (-180 to 180), required for POSITION type
        value: Measurement value (numeric, string, or structured dict)
        unit: Unit of measurement (e.g., "knots", "meters", "celsius")
        quality: Data quality score (0-100, default 100)
        status: Status code or message
        metadata: Additional structured metadata
        source: Data source identifier (e.g., "gps", "ais", "manual")
    """

    time: datetime = Field(..., description="Timestamp of the measurement")
    vessel_id: UUID = Field(..., description="Vessel ID")
    tenant_id: UUID = Field(..., description="Tenant ID")
    data_type: DataType = Field(..., description="Type of telemetry data")

    # Position fields (required for POSITION type)
    latitude: float | None = Field(
        default=None,
        ge=-90,
        le=90,
        description="Latitude in degrees (-90 to 90)",
    )
    longitude: float | None = Field(
        default=None,
        ge=-180,
        le=180,
        description="Longitude in degrees (-180 to 180)",
    )

    # Generic value field (type depends on data_type)
    value: float | str | dict[str, Any] | None = Field(
        default=None,
        description="Measurement value (numeric, string, or structured)",
    )
    unit: str | None = Field(
        default=None,
        max_length=50,
        description="Unit of measurement (e.g., 'knots', 'meters', 'celsius')",
    )

    # Quality and status
    quality: int = Field(
        default=100,
        ge=0,
        le=100,
        description="Data quality score (0-100, 100 = highest quality)",
    )
    status: str | None = Field(
        default=None,
        max_length=50,
        description="Status code or message",
    )

    # Additional metadata
    metadata: dict[str, Any] = Field(
        default_factory=dict,
        description="Additional structured metadata",
    )

    # Source information
    source: str | None = Field(
        default=None,
        max_length=100,
        description="Data source identifier (e.g., 'gps', 'ais', 'manual')",
    )

    model_config = {
        "json_schema_extra": {
            "example": {
                "time": "2025-12-11T12:00:00Z",
                "vessel_id": "550e8400-e29b-41d4-a716-446655440000",
                "tenant_id": "550e8400-e29b-41d4-a716-446655440001",
                "data_type": "position",
                "latitude": 64.1466,
                "longitude": -21.9426,
                "quality": 95,
                "source": "gps",
            }
        }
    }
