import requests


class FairCloseClient:
    def __init__(self, base_url: str, api_key: str | None = None):
        self.base_url = base_url.rstrip("/")
        if not self.base_url:
            raise ValueError("FairCloseClient requires a base_url")
        self.api_key = api_key
        self.api_base = f"{self.base_url}/api/v1/public"
        self.partner_base = f"{self.base_url}/api/v1/public/partner"

    def _request(self, base: str, path: str, params: dict | None = None, method: str = "GET", json_body: dict | None = None, headers: dict | None = None):
        response = requests.request(method, f"{base}{path}", params=params or {}, json=json_body, headers=headers or {}, timeout=30)
        response.raise_for_status()
        return response.json()

    def get_meta(self):
        return self._request(self.api_base, "/meta")

    def get_categories(self):
        return self._request(self.api_base, "/categories")

    def list_listings(self, **params):
        return self._request(self.api_base, "/listings", params=params)

    def search_listings(self, **params):
        return self._request(self.api_base, "/search", params=params)

    def get_listing(self, listing_id: str):
        return self._request(self.api_base, f"/listings/{listing_id}")

    def _partner_headers(self):
        if not self.api_key:
            raise ValueError("Partner requests require an api_key")
        return {"X-API-Key": self.api_key}

    def get_partner_meta(self):
        return self._request(self.partner_base, "/meta", headers=self._partner_headers())

    def list_partner_listings(self, **params):
        return self._request(self.partner_base, "/listings", params=params, headers=self._partner_headers())

    def search_partner_listings(self, **params):
        return self._request(self.partner_base, "/search", params=params, headers=self._partner_headers())

    def get_partner_listing(self, listing_id: str):
        return self._request(self.partner_base, f"/listings/{listing_id}", headers=self._partner_headers())

    def create_listing_embed_signature(self, listing_id: str, theme: str = "sand", accent: str | None = None, expires_in_minutes: int = 60):
        return self._request(
            self.partner_base,
            "/embed-signatures",
            method="POST",
            json_body={
                "listing_id": listing_id,
                "theme": theme,
                "accent": accent,
                "expires_in_minutes": expires_in_minutes,
            },
            headers=self._partner_headers(),
        )