"""JAO Auction Data API client."""

from __future__ import annotations

from dataclasses import dataclass
import os
from typing import Any, Dict, Optional

import requests


class JaoApiError(RuntimeError):
    """Raised when the JAO API returns an error or invalid response."""


@dataclass
class JaoClient:
    """Simple REST client for the JAO Auction Data API.

    Parameters
    ----------
    api_key:
        JAO API token. If None, reads from environment variable `JAO_API_KEY`.
    base_url:
        API base URL. Defaults to https://api.jao.eu/OWSMP
    timeout:
        Request timeout in seconds.
    live:
        When False, network calls are blocked (useful for dry runs).
    """

    api_key: Optional[str] = None
    base_url: str = "https://api.jao.eu/OWSMP"
    timeout: int = 60
    live: bool = True

    def __post_init__(self) -> None:
        if self.api_key is None:
            self.api_key = os.getenv("JAO_API_KEY", "").strip()

    def _request(self, endpoint: str, params: Optional[Dict[str, Any]] = None) -> Any:
        if not self.live:
            raise RuntimeError("Live requests are disabled. Set live=True to enable network calls.")
        if not self.api_key:
            raise RuntimeError("Missing API key. Set JAO_API_KEY in your environment.")

        url = f"{self.base_url}/{endpoint}"
        headers = {"AUTH_API_KEY": self.api_key}

        try:
            resp = requests.get(url, params=params, headers=headers, timeout=self.timeout)
        except requests.exceptions.RequestException as exc:
            raise JaoApiError(f"Network error while calling {url}: {exc}") from exc

        if not resp.ok:
            # Some endpoints return HTTP 400 with JSON body: {"message":"No Data found"}
            try:
                err = resp.json()
            except ValueError:
                err = None

            if resp.status_code == 400 and isinstance(err, dict) and err.get("message") == "No Data found":
                return []

            body = resp.text[:1000]
            raise JaoApiError(f"HTTP {resp.status_code} for {resp.url}: {body}")

        try:
            return resp.json()
        except ValueError as exc:
            raise JaoApiError("Response was not valid JSON") from exc

    def get_corridors(self) -> Any:
        return self._request("getcorridors")

    def get_horizons(self) -> Any:
        return self._request("gethorizons")

    def get_auctions(
        self,
        corridor: str,
        fromdate: str,
        todate: str,
        horizon: Optional[str] = None,
        shadow: Optional[bool] = None,
    ) -> Any:
        params: Dict[str, Any] = {
            "corridor": corridor,
            "fromdate": fromdate,
            "todate": todate,
        }
        if horizon:
            params["horizon"] = horizon
        if shadow is not None:
            params["shadow"] = "true" if shadow else "false"
        return self._request("getauctions", params=params)

    def get_bids(self, auctionid: str) -> Any:
        return self._request("getbids", params={"auctionid": auctionid})

    def get_curtailment(self, corridor: str, fromdate: str, todate: str) -> Any:
        params = {
            "corridor": corridor,
            "fromdate": fromdate,
            "todate": todate,
        }
        return self._request("getcurtailment", params=params)
