"""Activities — filter + browse, click a row to drill in.

The list applies inclusive filters (type / date / distance / name) and
defers rendering big tables until the user has narrowed the set. Selecting
a row navigates to the Activity detail page via query-parameter.
"""

from __future__ import annotations

from datetime import date, timedelta

import pandas as pd
import streamlit as st

from openrun.web._helpers import cached_activities, empty_state, show_sidebar


st.set_page_config(page_title="Activities · openrun", page_icon="📋", layout="wide")
show_sidebar()
st.title("📋 Activities")

runs = cached_activities(type=None)
if runs.empty:
    empty_state("No activities yet.", "Run `openrun-sync` or import an export from the Sync page.")
    st.stop()

# Drop unparseable rows once; everything downstream gets a clean frame.
runs = runs.dropna(subset=["start_time_local"]).copy()
runs["date"] = runs["start_time_local"].dt.date


# ---------------------------------------------------------------------------
# Filters
# ---------------------------------------------------------------------------

st.subheader("Filter")
f1, f2 = st.columns([2, 3])

with f1:
    all_types = sorted(runs["activity_type"].dropna().unique().tolist())
    default_types = [t for t in ("running", "trail_running") if t in all_types] or all_types[:1]
    types = st.multiselect("Type", all_types, default=default_types)

with f2:
    min_date = runs["date"].min()
    max_date = runs["date"].max()
    default_start = max(min_date, max_date - timedelta(days=180))
    date_range = st.date_input(
        "Date range",
        value=(default_start, max_date),
        min_value=min_date,
        max_value=max_date,
    )

f3, f4 = st.columns([2, 3])
with f3:
    dist_min, dist_max = st.slider(
        "Distance (km)",
        min_value=0.0,
        max_value=float(runs["distance_km"].max() or 100),
        value=(0.0, float(runs["distance_km"].max() or 100)),
        step=0.5,
    )
with f4:
    name_q = st.text_input("Name contains", placeholder="e.g. tempo, race, hill")


# ---------------------------------------------------------------------------
# Apply
# ---------------------------------------------------------------------------

filt = runs.copy()
if types:
    filt = filt[filt["activity_type"].isin(types)]
if isinstance(date_range, tuple) and len(date_range) == 2:
    start, end = date_range
    filt = filt[(filt["date"] >= start) & (filt["date"] <= end)]
filt = filt[filt["distance_km"].between(dist_min, dist_max)]
if name_q.strip():
    needle = name_q.strip().lower()
    filt = filt[filt["activity_name"].fillna("").str.lower().str.contains(needle)]

filt = filt.sort_values("start_time_local", ascending=False)
st.caption(f"**{len(filt):,}** activities match. Click a row to open detail.")


# ---------------------------------------------------------------------------
# Display + selection
# ---------------------------------------------------------------------------

if filt.empty:
    empty_state("No activities match the filters.")
    st.stop()


def _fmt_pace(p: float) -> str:
    if pd.isna(p):
        return "—"
    minutes = int(p)
    seconds = int(round((p - minutes) * 60))
    return f"{minutes}:{seconds:02d}/km"


display = filt[[
    "activity_id", "start_time_local", "activity_name", "activity_type",
    "distance_km", "pace_min_per_km", "avg_hr", "training_load",
]].copy().reset_index(drop=True)
display["pace"] = display["pace_min_per_km"].apply(_fmt_pace)
display["distance_km"] = display["distance_km"].round(2)
display["avg_hr"] = display["avg_hr"].round(0)
display = display.rename(columns={
    "start_time_local": "When",
    "activity_name": "Name",
    "activity_type": "Type",
    "distance_km": "Distance (km)",
    "avg_hr": "Avg HR",
    "training_load": "TL",
})[
    ["When", "Name", "Type", "Distance (km)", "pace", "Avg HR", "TL", "activity_id"]
].rename(columns={"pace": "Pace"})

event = st.dataframe(
    display.drop(columns=["activity_id"]),
    width="stretch",
    hide_index=True,
    height=520,
    selection_mode="single-row",
    on_select="rerun",
    key="activities_table",
)

selected = event.selection.rows if hasattr(event, "selection") else []
if selected:
    aid = int(display.iloc[selected[0]]["activity_id"])
    st.query_params["aid"] = str(aid)
    st.switch_page("pages/8_Activity_Detail.py")
