"""openrun — endurance-running analytics, local-first.

Most notebooks just need:

    from openrun import open_conn, load_activities, load_wellness
    conn = open_conn()
    runs = load_activities(conn, type='running')

Submodules:
    openrun.config   — UserProfile, HR zones, Banister params, race calendar
    openrun.db       — schema + connection helper
    openrun.model    — loaders + derived metrics (decoupling, zones, Banister, FIT)
    openrun.ingest.* — data-source ingesters (Garmin export, FIT linker, time-in-zone)
"""

from .config import (
    Config,
    HRZones,
    UserProfile,
    BanisterParams,
    default_config,
    default_profile,
    load_config,
    write_config,
)
from .db import connect, get_state, set_state
from .model import (
    # connections
    open_conn,
    # loaders
    load_activities,
    load_wellness,
    load_sleep_stages,
    load_splits,
    daily_training_load,
    daily_training_load_series,
    joined,
    expand_raw,
    # FIT
    load_fit_records,
    fit_decoupling,
    fit_rolling_efficiency,
    # zones
    assign_hr_zone,
    hr_to_user_zone,
    time_in_zone_from_fit,
    time_in_zone_from_splits,
    weekly_time_in_zone,
    # Banister
    banister,
    banister_forecast,
    # Race-plan helpers
    personal_records,
    calibrate_tl_per_km,
    plan_to_daily_load,
    # Geo
    haversine_km,
    cluster_routes,
    # split-level decoupling (kept for back-compat)
    decoupling,
)

__all__ = [
    "Config", "HRZones", "UserProfile", "BanisterParams",
    "default_config", "default_profile", "load_config", "write_config",
    "connect", "get_state", "set_state",
    "open_conn",
    "load_activities", "load_wellness", "load_sleep_stages", "load_splits",
    "daily_training_load",
    "daily_training_load_series", "joined", "expand_raw",
    "load_fit_records", "fit_decoupling", "fit_rolling_efficiency",
    "assign_hr_zone", "hr_to_user_zone",
    "time_in_zone_from_fit", "time_in_zone_from_splits", "weekly_time_in_zone",
    "banister", "banister_forecast", "personal_records", "calibrate_tl_per_km",
    "plan_to_daily_load",
    "haversine_km", "cluster_routes", "decoupling",
    "HR_ZONES_USER",  # back-compat alias, resolved lazily
]


def __getattr__(name: str):
    # Lazy fallback so `from openrun import HR_ZONES_USER` works.
    # Resolves to the current default profile's zones at access time.
    if name == "HR_ZONES_USER":
        from .config import default_profile
        return default_profile().hr_zones().as_tuples()
    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
