"""Device reading model for health metric data from connected devices."""
from datetime import datetime
from typing import Literal, Optional

from pydantic import Field

from .base import BaseDocument
from .types import PyObjectId


# Valid metric identifiers — these match exactly what the Android companion app
# sends from Health Connect (see android/.../health/HealthReader.kt). Keep this
# in sync with frontend's MetricId in frontend/src/devices/types.ts.
#
# Why this list and not more: Samsung Health on Android only writes a specific
# subset of categories to Health Connect. Things like hydration, active calories,
# HRV, body temperature, and respiratory rate are deliberately NOT exported by
# Samsung Health, so we don't claim to support them.
VALID_METRICS = {
    'steps',
    'calories_total',
    'calories_intake',
    'sleep_duration',
    'heart_rate_resting',
    'blood_oxygen',
    'weight',
    'body_fat',
    'basal_metabolic_rate',
    'blood_glucose',
    'blood_pressure_sys',
    'blood_pressure_dia',
}

# Valid unit strings for readings.
VALID_UNITS = {
    'steps', 'kcal', 'bpm', 'hours', 'percent',
    'kg', 'mmHg', 'mg/dL',
}


class DeviceReading(BaseDocument):
    """A single health metric reading from a connected device.

    MongoDB indexes (create via device_repository.ensure_indexes):
      1. Compound unique on {userId, provider, metric, date} for daily_summary —
         prevents duplicate daily summaries from re-syncs.
      2. Query index on {userId, metric, date} for fast user metric lookups.
    """
    userId: PyObjectId = Field(description="ID of the Hipograf user")
    connectionId: PyObjectId = Field(description="ID of the DeviceConnection that produced this")
    provider: Literal['samsung_health'] = Field(
        default='samsung_health',
        description="Device provider identifier"
    )

    metric: str = Field(description="Metric identifier (e.g. 'steps', 'heart_rate_resting')")
    date: str = Field(description="Calendar day this reading belongs to, YYYY-MM-DD format")
    timestamp: Optional[datetime] = Field(
        default=None, description="Exact time for intraday metrics (heart rate samples, etc.)"
    )

    value: float = Field(description="Primary numeric value for this metric")
    unit: str = Field(description="Unit of measurement (e.g. 'steps', 'bpm', 'hours')")

    metricType: Literal['daily_summary', 'intraday_sample', 'session'] = Field(
        default='daily_summary',
        description=(
            "daily_summary: one record per day per metric; "
            "intraday_sample: multiple records per day; "
            "session: a bounded event (sleep session, workout)"
        ),
    )

    subMetrics: dict = Field(
        default_factory=dict,
        description="Complex sub-values, e.g. sleep stages or HR summary"
    )
    quality: str = Field(
        default='good',
        description="Data quality: excellent | good | poor | artifact"
    )
    rawData: Optional[dict] = Field(
        default=None,
        description="Original provider payload for debugging (not displayed)"
    )
