from __future__ import annotations

from dataclasses import dataclass
from urllib.parse import urlparse


def is_localhost(url: str) -> bool:
    host = urlparse(url).hostname
    return host in {"localhost", "127.0.0.1", "::1"}


def extract_loopback_host(url: str) -> str:
    p = urlparse(url)
    host = str(p.hostname or "").strip()
    if host in {"localhost", "127.0.0.1", "::1"}:
        return host
    raise ValueError(f"Redirect URI must use a loopback host: {url!r}")


def extract_port(url: str) -> int:
    p = urlparse(url)
    if p.port is None:
        raise ValueError(f"Redirect URI must include an explicit port: {url!r}")
    return int(p.port)


def remove_url_scheme(url: str) -> str:
    """Return host[:port]/path without scheme, matching upstream scope-building."""
    u = (url or "").strip()
    if not u:
        return ""
    p = urlparse(u)
    if p.scheme:
        # Keep netloc+path+query? upstream mostly uses host[:port]
        rest = (p.netloc or "") + (p.path or "")
        return rest.lstrip("/")
    return u.lstrip("/")


@dataclass(frozen=True)
class OAuthTokens:
    access_token: str
    access_expiration_ts: float
    refresh_token: str | None
    refresh_expiration_ts: float | None

