import dataclasses
from typing import NewType
from urllib import parse

Pathname = NewType("Pathname", str)
Site = NewType("Site", str)


@dataclasses.dataclass(frozen=True)
class Query:
    """A URL query string."""

    params: dict[str, str]

    def __str__(self) -> str:
        raw = self.params.get("$raw", "")
        rest = {k: v for k, v in self.params.items() if k != "$raw"}
        encoded = parse.urlencode(rest)
        if raw and encoded:
            return f"$raw={raw}&{encoded}"
        if raw:
            return f"$raw={raw}"
        return encoded


@dataclasses.dataclass(frozen=True)
class URL:
    """A URL with optional query parameters."""

    site: Site
    pathname: Pathname
    query: Query | None = None

    @property
    def full(self) -> str:
        return parse.urljoin(
            self.site,
            f"{self.pathname}?{self.query}" if self.query else self.pathname,
        )

    def __str__(self) -> str:
        return self.full
