"""API client for Anor Cloud"""
import httpx
from typing import Optional, Dict, Any, List

from .config import get_api_url, get_api_key


class APIError(Exception):
    def __init__(self, message: str, status_code: int = 0):
        self.message = message
        self.status_code = status_code
        super().__init__(message)


class AnorClient:
    def __init__(self, api_url: Optional[str] = None, api_key: Optional[str] = None):
        self.api_url = api_url or get_api_url()
        self.api_key = api_key or get_api_key()
        self.client = httpx.Client(
            base_url=self.api_url,
            timeout=30.0,
            headers=self._headers(),
        )

    def _headers(self) -> Dict[str, str]:
        headers = {"Content-Type": "application/json"}
        if self.api_key:
            headers["Authorization"] = f"Bearer {self.api_key}"
        return headers

    def _handle_response(self, response: httpx.Response) -> Any:
        if response.status_code >= 400:
            try:
                error = response.json()
                message = error.get("message", response.text)
            except Exception:
                message = response.text
            raise APIError(message, response.status_code)
        
        if response.headers.get("content-type", "").startswith("application/json"):
            return response.json()
        return response.text

    # Auth
    def login(self, email: str, password: str) -> Dict[str, Any]:
        response = self.client.post("/api/v1/auth/login", json={
            "email": email,
            "password": password,
        })
        return self._handle_response(response)

    def register(self, email: str, password: str, name: str) -> Dict[str, Any]:
        response = self.client.post("/api/v1/auth/register", json={
            "email": email,
            "password": password,
            "name": name,
        })
        return self._handle_response(response)

    def get_me(self) -> Dict[str, Any]:
        response = self.client.get("/api/v1/auth/me")
        return self._handle_response(response)

    def create_api_key(self, name: str) -> Dict[str, Any]:
        response = self.client.post("/api/v1/auth/api-keys", json={"name": name})
        return self._handle_response(response)

    # Jobs
    def create_job(
        self,
        command: str,
        grade: str,
        gpu_count: int,
        max_hourly_rate: float,
        name: Optional[str] = None,
        image: Optional[str] = None,
        workdir: Optional[str] = None,
        env_vars: Optional[Dict[str, str]] = None,
    ) -> Dict[str, Any]:
        payload = {
            "command": command,
            "grade": grade.upper(),
            "gpuCount": gpu_count,
            "maxHourlyRate": max_hourly_rate,
        }
        if name:
            payload["name"] = name
        if image:
            payload["image"] = image
        if workdir:
            payload["workdir"] = workdir
        if env_vars:
            payload["envVars"] = env_vars

        response = self.client.post("/api/v1/jobs", json=payload)
        return self._handle_response(response)

    def list_jobs(self, state: Optional[str] = None, page: int = 1, limit: int = 20) -> Dict[str, Any]:
        params = {"page": page, "limit": limit}
        if state:
            params["state"] = state
        response = self.client.get("/api/v1/jobs", params=params)
        return self._handle_response(response)

    def get_job(self, job_id: str) -> Dict[str, Any]:
        response = self.client.get(f"/api/v1/jobs/{job_id}")
        return self._handle_response(response)

    def get_job_logs(self, job_id: str) -> str:
        response = self.client.get(f"/api/v1/jobs/{job_id}/logs")
        return self._handle_response(response)

    def cancel_job(self, job_id: str) -> Dict[str, Any]:
        response = self.client.delete(f"/api/v1/jobs/{job_id}")
        return self._handle_response(response)

    def get_pricing(self) -> List[Dict[str, Any]]:
        response = self.client.get("/api/v1/jobs/pricing")
        return self._handle_response(response)

    # Account
    def get_balance(self) -> Dict[str, Any]:
        response = self.client.get("/api/v1/account/balance")
        return self._handle_response(response)
