from __future__ import annotations

from typing import Any, Dict, Iterable, Optional
import requests


class UcuzabulanApiClient:
    def __init__(self, base_url: str = "https://ucuzabulan.com", gateway_token: str = "", session: Optional[requests.Session] = None) -> None:
        self.base_url = base_url.rstrip("/")
        self.gateway_token = gateway_token.strip()
        self.session = session or requests.Session()

    def _clean_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
        clean: Dict[str, Any] = {}
        for key, value in params.items():
            if value is None or value == "":
                continue
            if isinstance(value, bool):
                clean[key] = "1" if value else "0"
            elif isinstance(value, (list, tuple, set)):
                values = [str(v) for v in value if str(v) != ""]
                if values:
                    clean[key] = ",".join(values)
            else:
                clean[key] = value
        return clean

    def _request(self, method: str, path: str, *, params: Optional[Dict[str, Any]] = None, json_body: Optional[Dict[str, Any]] = None, with_gateway_token: bool = False) -> Dict[str, Any]:
        headers = {"Accept": "application/json"}
        if with_gateway_token and self.gateway_token:
            headers["Authorization"] = f"Bearer {self.gateway_token}"
        response = self.session.request(
            method=method,
            url=f"{self.base_url}{path}",
            params=self._clean_params(params or {}),
            json=json_body,
            headers=headers,
            timeout=20,
        )
        response.raise_for_status()
        data = response.json()
        if not isinstance(data, dict):
            raise RuntimeError("Ucuzabulan API beklenen JSON obje yerine farklı çıktı döndü.")
        return data

    def search_products(self, q: str, limit: int = 24, mode: Optional[str] = None) -> Dict[str, Any]:
        return self._request("GET", "/api/v1/search.php", params={"q": q, "limit": limit, "mode": mode})

    def search_explain(self, q: str, limit: int = 12, mode: Optional[str] = None) -> Dict[str, Any]:
        return self._request("GET", "/api/v1/search_explain.php", params={"q": q, "limit": limit, "mode": mode})

    def search_suggest(self, q: str, limit: int = 8) -> Dict[str, Any]:
        return self._request("GET", "/api/v1/search_suggest.php", params={"q": q, "limit": limit})

    def product_by_slug(self, slug: str) -> Dict[str, Any]:
        return self._request("GET", "/api/v1/product.php", params={"slug": slug})

    def catalog_products(self, **params: Any) -> Dict[str, Any]:
        return self._request("GET", "/api/v1/catalog.php", params=params)

    def catalog_facets(self, **params: Any) -> Dict[str, Any]:
        return self._request("GET", "/api/v1/facets.php", params=params)

    def product_offers(self, product_id: int, **params: Any) -> Dict[str, Any]:
        payload = {"product_id": product_id, **params}
        return self._request("GET", "/api/v1/offers.php", params=payload)

    def price_history(self, product_id: int, days: int = 30) -> Dict[str, Any]:
        return self._request("GET", "/api/v1/price_history.php", params={"product_id": product_id, "days": days})

    def mobile_bootstrap(self, banner_limit: int = 6, category_limit: int = 10, pick_limit: int = 12) -> Dict[str, Any]:
        return self._request(
            "GET",
            "/api/v1/mobile_bootstrap.php",
            params={"banner_limit": banner_limit, "category_limit": category_limit, "pick_limit": pick_limit},
        )

    def mobile_me(self) -> Dict[str, Any]:
        return self._request("GET", "/api/v1/mobile_me.php")

    def mobile_compare(self, ids: Iterable[int]) -> Dict[str, Any]:
        return self._request("GET", "/api/v1/mobile_compare.php", params={"ids": list(ids)})

    def graphql(self, query: str, variables: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        return self._request("POST", "/api/graphql.php", json_body={"query": query, "variables": variables or {}})

    def graphql_persisted(self, key: str, variables: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        return self._request("POST", "/api/graphql_persisted.php", json_body={"key": key, "variables": variables or {}})

    def gateway(self, route: str, **params: Any) -> Dict[str, Any]:
        payload = {"route": route, **params}
        return self._request("POST", "/api/gateway.php", json_body=payload, with_gateway_token=True)