"""Shared helpers for the daily "small joys" features — On This Day, Word of the Day,
Quote of the Day (and whatever calm little delights come next).

Each joy keeps its own pool + daily table, but they all share this skeleton:
  harvest -> pool  →  deterministic daily pick (date-seeded, least-recently-shown)  →
  cache row in a daily_* table  →  API  →  page.

This module holds only the genuinely shared bits (network + the deterministic pick), so a
new joy is a small self-contained module, not a copy-paste of plumbing. Network calls go
through http_json so tests can monkeypatch them.
"""
from __future__ import annotations

import hashlib
import json
import urllib.request

_UA = {"User-Agent": "upbeatBytes/1.0 (+https://upbeatbytes.com)"}


def http_json(url: str, timeout: int = 20) -> dict:
    req = urllib.request.Request(url, headers=_UA)
    with urllib.request.urlopen(req, timeout=timeout) as r:
        return json.loads(r.read().decode("utf-8"))


def seeded_order(ids: list, date_str: str) -> list:
    """Rotate a list deterministically by the date, so the day's pick is the same for
    everyone and varies day to day (the same trick Daily Art uses)."""
    if not ids:
        return ids
    seed = int(hashlib.sha256(date_str.encode()).hexdigest(), 16) % len(ids)
    return ids[seed:] + ids[:seed]


def content_key(*parts) -> str:
    """A stable dedup key for a pool item (so re-harvesting never duplicates a row)."""
    raw = "|".join("" if p is None else str(p) for p in parts)
    return hashlib.sha256(raw.encode()).hexdigest()[:24]
