"""Bluesky-Helper — AT-Protocol public Search-API.

Verwendet `api.bsky.app` (NICHT `public.api.bsky.app` — letzteres ist 403
in v0.1, KAR-38 Drift-Fund 13.05.2026).
"""
from __future__ import annotations

import datetime as dt
import json
import logging
import time
import urllib.parse
import urllib.request

log = logging.getLogger(__name__)

API_BASE = "https://api.bsky.app/xrpc/app.bsky.feed.searchPosts"
USER_AGENT = "aria-radar/0.1 (+aseckzai@gmail.com)"
TIMEOUT_SECONDS = 15

KEYWORDS = [
    "claude code",
    "anthropic api",
    "mcp server",
    "claude sdk",
    "ai agent",
]


def _search(keyword: str, max_items: int = 10) -> list[dict]:
    params = {"q": keyword, "limit": str(max_items), "sort": "top"}
    url = f"{API_BASE}?{urllib.parse.urlencode(params)}"
    req = urllib.request.Request(url, headers={"User-Agent": USER_AGENT, "Accept": "application/json"})
    with urllib.request.urlopen(req, timeout=TIMEOUT_SECONDS) as resp:
        payload = json.loads(resp.read())
    return payload.get("posts", [])


def fetch(*, since: dt.datetime, max_per_keyword: int = 5) -> list[dict]:
    """Search Bluesky for AI-related posts. Defensive — keyword-fail skips, total-fail returns []."""
    all_items: list[dict] = []
    seen_uris: set[str] = set()
    for keyword in KEYWORDS:
        try:
            posts = _search(keyword, max_items=max_per_keyword * 2)
        except Exception as exc:  # noqa: BLE001
            log.warning("bluesky keyword '%s' failed: %s", keyword, exc)
            continue
        for post in posts:
            uri = post.get("uri", "")
            if not uri or uri in seen_uris:
                continue
            indexed_at = post.get("indexedAt") or post.get("record", {}).get("createdAt") or ""
            try:
                created = dt.datetime.fromisoformat(indexed_at.replace("Z", "+00:00"))
            except ValueError:
                created = dt.datetime.now(dt.timezone.utc)
            if created < since:
                continue
            author = post.get("author", {})
            handle = author.get("handle", "unknown")
            post_id = uri.rsplit("/", 1)[-1] if "/" in uri else uri
            text = (post.get("record", {}) or {}).get("text", "")
            all_items.append({
                "title": f"@{handle}: {text[:80]}",
                "url": f"https://bsky.app/profile/{handle}/post/{post_id}",
                "date": created.isoformat(),
                "source": "bluesky",
                "score": (post.get("likeCount") or 0) + (post.get("repostCount") or 0) * 2,
                "raw": {
                    "keyword": keyword,
                    "handle": handle,
                    "text": text[:300],
                    "like_count": post.get("likeCount"),
                    "repost_count": post.get("repostCount"),
                    "reply_count": post.get("replyCount"),
                },
            })
            seen_uris.add(uri)
            if len([i for i in all_items if i["raw"]["keyword"] == keyword]) >= max_per_keyword:
                break
        time.sleep(0.3)
    log.info("bluesky: %d items from %d keywords", len(all_items), len(KEYWORDS))
    return all_items


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    items = fetch(since=dt.datetime.now(dt.timezone.utc) - dt.timedelta(hours=24))
    print(json.dumps(items, indent=2))
