"""Financial ingestion — FRED (macro series) + Stooq (market/commodity prices).

Stooq is used instead of Alpha Vantage because it needs no key at all and has no
25-request/day cap, which a 4x/day digest would otherwise burn through
(docs/project-plan.md Phase 12 step 4).

Adding series/symbols is env-only, no code change:

  FRED_SERIES  — comma-separated FRED series IDs, default "UNRATE" (US
                 unemployment rate). Browse/search IDs at
                 https://fred.stlouisfed.org — e.g. "UNRATE,CPIAUCSL,FEDFUNDS"
                 for unemployment + CPI + the federal funds rate.
  STOOQ_SYMBOLS — comma-separated Stooq symbols, default "^spx,^dax,cl.f".
                 Stooq notation: "^spx"/"^dax"/"^ndq" for indices, bare tickers
                 like "aapl.us" for US equities, and futures like "cl.f" (WTI
                 crude), "gc.f" (gold), "ng.f" (natural gas).
"""

import csv
import io
import logging
import os
from datetime import datetime, timedelta, timezone

import requests

LOG = logging.getLogger(__name__)

FRED_URL = "https://api.stlouisfed.org/fred/series/observations"
STOOQ_URL = "https://stooq.com/q/d/l/"

HTTP_TIMEOUT = 30
STOOQ_HISTORY_DAYS = 45
FRED_HISTORY_DAYS = 400


def _csv_list(name, default):
    raw = os.environ.get(name, default)
    return [item.strip() for item in raw.split(",") if item.strip()]


def _fetch_fred(series_ids, api_key):
    observations = []
    start = (datetime.now(timezone.utc) - timedelta(days=FRED_HISTORY_DAYS)).date()

    for series_id in series_ids:
        try:
            response = requests.get(
                FRED_URL,
                params={
                    "series_id": series_id,
                    "api_key": api_key,
                    "file_type": "json",
                    "observation_start": start.isoformat(),
                    "sort_order": "desc",
                    "limit": 6,
                },
                timeout=HTTP_TIMEOUT,
            )
            response.raise_for_status()
            points = [
                {"date": item["date"], "value": item["value"]}
                for item in response.json().get("observations", [])
                if item.get("value") not in (None, ".")
            ]
            if not points:
                LOG.warning("financial: FRED series %s returned no usable observations", series_id)
                continue
            observations.append(
                {
                    "source": "fred",
                    "series_id": series_id,
                    "latest_date": points[0]["date"],
                    "latest_value": points[0]["value"],
                    "previous_value": points[1]["value"] if len(points) > 1 else None,
                    "recent": points,
                }
            )
        except Exception:
            LOG.warning("financial: FRED series %s failed, skipping", series_id, exc_info=True)

    return observations


def _fetch_stooq(symbols):
    quotes = []
    end = datetime.now(timezone.utc).date()
    start = end - timedelta(days=STOOQ_HISTORY_DAYS)

    for symbol in symbols:
        try:
            response = requests.get(
                STOOQ_URL,
                params={
                    "s": symbol,
                    "i": "d",
                    "d1": start.strftime("%Y%m%d"),
                    "d2": end.strftime("%Y%m%d"),
                },
                timeout=HTTP_TIMEOUT,
            )
            response.raise_for_status()
            rows = [row for row in csv.DictReader(io.StringIO(response.text)) if row.get("Close")]
            if not rows:
                LOG.warning("financial: Stooq symbol %s returned no rows", symbol)
                continue
            latest = rows[-1]
            previous = rows[-2] if len(rows) > 1 else None
            first = rows[0]
            quotes.append(
                {
                    "source": "stooq",
                    "symbol": symbol,
                    "date": latest["Date"],
                    "close": float(latest["Close"]),
                    "previous_close": float(previous["Close"]) if previous else None,
                    "close_days_ago": float(first["Close"]),
                    "window_days": STOOQ_HISTORY_DAYS,
                }
            )
        except Exception:
            LOG.warning("financial: Stooq symbol %s failed, skipping", symbol, exc_info=True)

    return quotes


def fetch(lookback_hours):
    del lookback_hours  # macro series and daily bars move slower than the digest cadence

    results = []

    fred_key = os.environ.get("FRED_API_KEY", "").strip()
    fred_series = _csv_list("FRED_SERIES", "UNRATE")
    if fred_key:
        results.extend(_fetch_fred(fred_series, fred_key))
    else:
        LOG.warning("financial: FRED_API_KEY not set, skipping macro series")

    results.extend(_fetch_stooq(_csv_list("STOOQ_SYMBOLS", "^spx,^dax,cl.f")))

    LOG.info("financial: %d indicator(s)", len(results))
    return results
