"""Reddit top.rss?t=week → record-форма. Анонимный JSON заблокирован (403),
RSS-эндпоинт отдаёт топ недели. Score в RSS не приходит → metric=None,
ранг = порядок ленты (она уже отсортирована по топу), кап на сабреддит."""
import time
from calendar import timegm
from datetime import datetime, timezone
from typing import List, Tuple
from urllib.parse import urlparse

import feedparser
import requests

TOP_RSS_URL = "https://www.reddit.com/r/{}/top.rss"
REQUEST_DELAY = 5.0  # сек между сабреддитами — Reddit агрессивно rate-лимитит анонимку


def _entry_date(e) -> str:
    for key in ("published_parsed", "updated_parsed"):
        t = e.get(key)
        if t:
            return datetime.fromtimestamp(timegm(t), tz=timezone.utc).isoformat()
    return ""


def _entry_id(sub: str, e) -> str:
    raw = e.get("id") or e.get("link") or ""
    if "t3_" in raw:
        tid = raw.split("t3_")[-1]
    else:
        tid = urlparse(raw).path.rstrip("/").split("/")[-1] or raw
    return "reddit:{}:{}".format(sub.lower(), tid)


def parse_feed(sub: str, parsed, cap: int) -> List[dict]:
    out = []
    for e in parsed.entries[:cap]:
        out.append({
            "post_id": _entry_id(sub, e),
            "account": sub.lower(),
            "platform": "reddit",
            "caption": e.get("title", ""),
            "posted_at": _entry_date(e),
            "metric": None,
            "permalink": e.get("link", ""),
        })
    return out


def fetch_reddit(subreddits, cap, user_agent, window="week",
                 session=None) -> Tuple[List[dict], dict]:
    """Топ-`cap` постов недели на сабреддит через top.rss. → (records, errors)."""
    http = session or requests
    headers = {"User-Agent": user_agent}
    records, errors = [], {}
    for i, sub in enumerate(subreddits):
        if i > 0:
            time.sleep(REQUEST_DELAY)
        try:
            resp = http.get(TOP_RSS_URL.format(sub), headers=headers,
                            params={"t": window}, timeout=30)
            resp.raise_for_status()
            records += parse_feed(sub, feedparser.parse(resp.content), cap)
        except requests.RequestException as exc:
            errors[sub.lower()] = str(exc)
    return records, errors
