"""Strava-only page adapter; page and bounds never escape as generic sync semantics."""

from __future__ import annotations

from mountain_twin.activity.persistence import (
    AcquiredProviderPage,
    OpaqueProviderState,
    ProviderAuthError,
    ProviderRateLimitError,
    ProviderRetryableError,
)

from .client import (
    StravaApiError,
    StravaAuthenticationError,
    StravaClient,
    StravaInsufficientScopeError,
    StravaRateLimitError,
)
from .oauth import READ_SCOPE


class StravaPageAdapter:
    def __init__(self, client: StravaClient, *, required_scope: str = READ_SCOPE):
        self.client, self.required_scope = client, required_scope

    def acquire_page(
        self, plan: OpaqueProviderState, resume: OpaqueProviderState
    ) -> AcquiredProviderPage:
        try:
            self.client.ensure_access(self.required_scope)
            page = int(resume.value.get("page", 1))
            per_page = int(plan.value.get("per_page", 30))
            after, before = plan.value.get("after"), plan.value.get("before")
            values = self.client.activity_page(
                page=page, per_page=per_page, after=after, before=before
            )
        except StravaRateLimitError as error:
            raise ProviderRateLimitError("STRAVA_RATE_LIMITED") from error
        except (StravaAuthenticationError, StravaInsufficientScopeError) as error:
            raise ProviderAuthError("STRAVA_AUTH_BLOCKED") from error
        except StravaApiError as error:
            raise ProviderRetryableError(error.args[0]) from error
        # Strava may return a short non-final page; only an empty page exhausts this query.
        exhausted = len(values) == 0
        next_resume = OpaqueProviderState(resume.version, {"page": page + 1})
        terminal_state = (
            OpaqueProviderState("strava_sync_terminal_v0_1", {"page": page}) if exhausted else None
        )
        return AcquiredProviderPage(
            tuple(values),
            next_resume,
            exhausted,
            terminal_state,
            plan_complete=exhausted,
        )
