"""Bluesky platform adapter."""

from __future__ import annotations

from collections.abc import Mapping
from dataclasses import dataclass, field
from typing import Any

from atproto import Client  # type: ignore[import-untyped]

from sm_tracker.platforms import AdapterConfigError, BaseAdapter, PlatformCounts
from sm_tracker.platforms.utils import extract_int


@dataclass(frozen=True)
class BlueskyAdapter(BaseAdapter):
    """Fetch Bluesky follower/following counts for one handle."""

    handle: str
    app_password: str | None = field(default=None, repr=False)

    @property
    def name(self) -> str:
        return "bluesky"

    def _build_client(self) -> Client:
        return Client()

    def _fetch_profile(self, client: Client) -> Any:
        return client.get_profile(actor=self.handle)

    def fetch_counts(self) -> PlatformCounts:
        client = self._build_client()
        if self.app_password:
            client.login(self.handle, self.app_password)

        profile = self._fetch_profile(client)
        follower_count = extract_int(profile, "followers_count", "followersCount")
        following_count = extract_int(profile, "follows_count", "followsCount")
        return PlatformCounts(
            platform=self.name,
            follower_count=follower_count,
            following_count=following_count,
        )

    @classmethod
    def from_env(cls, env: Mapping[str, str]) -> BlueskyAdapter:
        """Create a Bluesky adapter from env vars."""
        handle = env.get("BLUESKY_HANDLE", "").strip()
        if not handle:
            raise AdapterConfigError("Skipping bluesky: missing BLUESKY_HANDLE in environment.")

        app_password_raw = env.get("BLUESKY_APP_PASSWORD")
        app_password = app_password_raw.strip() if app_password_raw else None
        return cls(handle=handle, app_password=app_password)
