from __future__ import annotations

from dataclasses import dataclass
from typing import Any

from therminal.models._base import DictLikeMixin, _to_float, _to_int


@dataclass(frozen=True)
class Observation(DictLikeMixin):
    station_code: str
    observed_at: str
    observation_type: str
    source: str
    temp_f: float | None
    dewpoint_f: float | None
    relative_humidity: float | None
    wind_dir_degrees: int | None
    wind_speed_kt: int | None
    wind_gust_kt: int | None
    altimeter_inhg: float | None
    sea_level_pressure_mb: float | None
    sky_cover_1: str | None
    sky_base_1_ft: int | None
    sky_cover_2: str | None
    sky_base_2_ft: int | None
    sky_cover_3: str | None
    sky_base_3_ft: int | None
    sky_cover_4: str | None
    sky_base_4_ft: int | None
    visibility_miles: float | None
    weather_codes: str | None
    precip_1hr_inches: float | None
    peak_wind_gust_kt: int | None
    peak_wind_dir: int | None
    peak_wind_time: str | None
    feels_like_f: float | None
    snow_depth_inches: float | None
    raw_metar: str | None

    @classmethod
    def from_api_dict(cls, d: dict[str, Any]) -> Observation:
        """Create from API response dict. Go omitempty means absent keys."""
        return cls(
            station_code=d.get("station_code", ""),
            observed_at=d.get("observed_at", ""),
            observation_type=d.get("observation_type", "METAR"),
            source=d.get("source", ""),
            temp_f=_to_float(d.get("temp_f")),
            dewpoint_f=_to_float(d.get("dewpoint_f")),
            relative_humidity=_to_float(d.get("relative_humidity")),
            wind_dir_degrees=_to_int(d.get("wind_dir_degrees")),
            wind_speed_kt=_to_int(d.get("wind_speed_kt")),
            wind_gust_kt=_to_int(d.get("wind_gust_kt")),
            altimeter_inhg=_to_float(d.get("altimeter_inhg")),
            sea_level_pressure_mb=_to_float(d.get("sea_level_pressure_mb")),
            sky_cover_1=d.get("sky_cover_1"),
            sky_base_1_ft=_to_int(d.get("sky_base_1_ft")),
            sky_cover_2=d.get("sky_cover_2"),
            sky_base_2_ft=_to_int(d.get("sky_base_2_ft")),
            sky_cover_3=d.get("sky_cover_3"),
            sky_base_3_ft=_to_int(d.get("sky_base_3_ft")),
            sky_cover_4=d.get("sky_cover_4"),
            sky_base_4_ft=_to_int(d.get("sky_base_4_ft")),
            visibility_miles=_to_float(d.get("visibility_miles")),
            weather_codes=d.get("weather_codes"),
            precip_1hr_inches=_to_float(d.get("precip_1hr_inches")),
            peak_wind_gust_kt=_to_int(d.get("peak_wind_gust_kt")),
            peak_wind_dir=_to_int(d.get("peak_wind_dir")),
            peak_wind_time=d.get("peak_wind_time"),
            feels_like_f=_to_float(d.get("feels_like_f")),
            snow_depth_inches=_to_float(d.get("snow_depth_inches")),
            raw_metar=d.get("raw_metar"),
        )

    @classmethod
    def from_awc_json(cls, d: dict[str, Any]) -> Observation | None:
        """Create from AWC METAR JSON. Returns None if invalid."""
        from therminal.weather._awc import awc_to_observation

        return awc_to_observation(d)
