"""Minimal Python client for the EOX Market Data API (requests + pandas). Send this file to clients.

    from eox import EOX
    eox = EOX("eox_...")                                        # or set EOX_API_KEY
    eox.curve("power", market_code="JZP,BXO", time_key="M01-M24")              # long DataFrame
    eox.curve("power", market_code="JZP,BXO", term="Month", layout="wide")     # tenors x curves grid
    eox.history("natural_gas", market_code="AA", time_key="M01", start="2025-01-01")
    eox.file("power")                                           # today's full EOD file, as delivered
    eox.datasets()                                              # what this key can access
"""
import io
import os

import pandas as pd
import requests


class EOX:
    def __init__(self, key: str | None = None, base: str = "https://api.eoxlive.com", timeout: int = 300):
        self.base = base.rstrip("/")
        self.timeout = timeout
        self.s = requests.Session()
        self.s.headers["X-API-Key"] = key or os.environ["EOX_API_KEY"]

    def _get(self, path: str, **params) -> requests.Response:
        params = {k: v for k, v in params.items() if v is not None}
        r = self.s.get(f"{self.base}{path}", params=params, timeout=self.timeout)
        if r.status_code != 200:
            try:
                detail = r.json().get("detail")
            except ValueError:
                detail = r.text[:300]
            raise RuntimeError(f"EOX API {r.status_code}: {detail}")
        return r

    def _csv(self, path: str, **params) -> pd.DataFrame:
        r = self._get(path, format="csv", **params)
        return pd.read_csv(io.BytesIO(r.content), dtype={"Time_Key": str})

    def datasets(self) -> pd.DataFrame:
        return pd.DataFrame(self._get("/v1/datasets").json())

    def curves(self, dataset: str, **filters) -> pd.DataFrame:
        return pd.DataFrame(self._get(f"/v1/{dataset}/curves", **filters).json()["data"])

    def dates(self, dataset: str, **params) -> list[str]:
        return self._get(f"/v1/{dataset}/dates", **params).json()["data"]

    def curve(self, dataset: str, date: str = "latest", layout: str = "long", **filters) -> pd.DataFrame:
        """One curve date. Filters: curve codes, time_key ranges (M01-M24), term, contract_from/to, ..."""
        return self._csv(f"/v1/{dataset}/curve", date=date, layout=layout, **filters)

    def history(self, dataset: str, layout: str = "long", **filters) -> pd.DataFrame:
        """Across dates. Needs the curve code; add time_key/contract and start/end to narrow."""
        return self._csv(f"/v1/{dataset}/history", layout=layout, **filters)

    def file(self, dataset: str, date: str = "latest") -> pd.DataFrame:
        r = self._get(f"/v1/{dataset}/file", date=date)
        return pd.read_csv(io.BytesIO(r.content), dtype=str)

    def save_file(self, dataset: str, path: str, date: str = "latest") -> str:
        """Write the EOD file exactly as delivered by email/FTPES."""
        with open(path, "wb") as f:
            f.write(self._get(f"/v1/{dataset}/file", date=date).content)
        return path
