"""Mission Control bootstrap document for a durable Journey that has a
persisted route (Work Package 1) -- and optionally a plan (Work Package 2)
-- but no AnalysisRun. Work Package 3 of docs/route_persistence_v0_1_design.md.

journey_analysis_runs stays entirely out of scope (design doc section 5):
this never invents or approximates any intelligence-domain result. It
mirrors the product's existing, already-shipped treatment of TMB Day 2-9
(mountain_twin/journey/stages.py's has_intelligence=False days): real
geometry, real distance/ascent/descent/elevation facts derived the same way
mountain_twin.route_analysis.prepare_route already derives them, and an
explicit false for has_intelligence -- the frontend renders every
intelligence domain as UNAVAILABLE/"Nie obliczono" from that flag, never a
guessed value.

journey-tmb-day-01-v0_1 (mountain_twin.journey.repository.
tmb_day_1_repository()) never reaches this module: catalog.is_reference()
routes it to the existing, untouched JourneyReadService/JIP path in
scripts/serve_visual_prototype.py, exactly as before this work package.
"""

from __future__ import annotations

from typing import Any

from mountain_twin.route_analysis import prepare_route

from .contracts import Journey, JourneyPlan, RouteRevision
from .elevation_gain import ascent_descent, method_for
from .route_persistence import route_activity_document, route_points_from_geometry_geojson
from .route_region import resolve_route_region
from .route_segments import transfers_document


def geometry_only_bootstrap_document(
    *,
    journey: Journey,
    route: RouteRevision,
    geometry_geojson: dict[str, Any],
    plan: JourneyPlan | None,
) -> dict[str, Any]:
    route_points = route_points_from_geometry_geojson(route.route_revision_id, geometry_geojson)
    prepared = prepare_route(route_points).points
    elevations = [point.gpx_elevation_m for point in prepared if point.gpx_elevation_m is not None]
    # Z2: smoothed by distance (and on foot a hysteresis), by the route's
    # activity (elevation_gain.py) -- the same for drawn and imported routes.
    window_m, hysteresis_m, ascent_method = method_for(route.activity_id)
    ascent_m, descent_m = ascent_descent(
        [point.cumulative_distance_m for point in prepared],
        [point.gpx_elevation_m for point in prepared],
        window_m=window_m,
        hysteresis_m=hysteresis_m,
        # AV-064: no climb across a transfer.
        run_starts=[
            k > 0 and point.segment_index != prepared[k - 1].segment_index
            for k, point in enumerate(prepared)
        ],
    )
    transfers = transfers_document(
        geometry_geojson["coordinates"], geometry_geojson.get("segments")
    )

    stage = {
        "route_id": route.route_id,
        "route_revision_id": route.route_revision_id,
        "day_number": 1,
        "name": journey.title,
        "distance_m": prepared[-1].cumulative_distance_m if prepared else 0.0,
        "ascent_m": ascent_m,
        "descent_m": descent_m,
        "ascent_method": ascent_method,
        # AV-064: distance_m is movement only; transfers are shown apart.
        "transfer_distance_m": float(sum(item["distance_m"] for item in transfers)),
        "transfers": transfers,
        "min_elevation_m": min(elevations) if elevations else None,
        "max_elevation_m": max(elevations) if elevations else None,
        "has_intelligence": False,
    }
    return {
        "kind": "GEOMETRY_ONLY_JOURNEY",
        # AV-031: what the route was drawn for (trekking for older routes).
        **route_activity_document(route),
        "journey": {"journey_id": journey.journey_id, "title": journey.title},
        "stage": stage,
        # The hero photo's region, from the route's first point (route_region.py).
        "route_region": resolve_route_region(route_points[0].latitude, route_points[0].longitude)
        if route_points
        else None,
        "plan": None
        if plan is None
        else {
            "journey_plan_id": plan.journey_plan_id,
            "planned_start_local": plan.planned_start_local,
            "journey_timezone": plan.journey_timezone,
            "pace_policy_id": plan.pace_policy_id,
        },
    }
