"""urllib DailyBarClient — Yahoo free daily adjusted closes. Retries with backoff; adjusted closes give
true total return (dividends + coupons). Mirrors foxhunt sixtyforty_paper.daily_adjclose."""
from __future__ import annotations

import datetime as dt
import json
import time
import urllib.request
from typing import Any

_BASE = "https://query1.finance.yahoo.com/v8/finance/chart/{sym}?interval=1d&range={rng}"


class YahooDailyClient:
    def __init__(self, rng: str = "2y") -> None:
        self._rng = rng

    def _get(self, url: str, tries: int = 4) -> dict[str, Any]:
        for a in range(tries):
            try:
                req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
                data: dict[str, Any] = json.loads(urllib.request.urlopen(req, timeout=30).read())
                return data
            except Exception:  # noqa: BLE001 — transient HTTP; retry then re-raise
                if a == tries - 1:
                    raise
                time.sleep(2 * (a + 1))
        raise RuntimeError("unreachable")

    def adj_closes(self, symbol: str) -> dict[str, float]:
        res = self._get(_BASE.format(sym=symbol, rng=self._rng))["chart"]["result"][0]
        ts = res["timestamp"]
        ind = res["indicators"]
        adj = ind.get("adjclose", [{}])[0].get("adjclose") or ind["quote"][0]["close"]
        out: dict[str, float] = {}
        for t, c in zip(ts, adj, strict=False):
            if c is not None:
                out[dt.datetime.fromtimestamp(t, dt.timezone.utc).strftime("%Y-%m-%d")] = float(c)
        return out
