import requests
from .exceptions import SignalLabsError


class SignalLabs:
    """Official Python SDK for the Signal Labs competitive intelligence API."""

    def __init__(self, api_key: str, base_url: str = "https://app.usesignallabs.com/api/v1"):
        if not api_key:
            raise ValueError("API key is required. Get one at https://app.usesignallabs.com/settings?tab=api-keys")
        self._api_key = api_key
        self._base_url = base_url.rstrip("/")
        self.companies = _Companies(self)
        self.ai = _AI(self)

    def _request(self, method: str, path: str, json=None, params=None):
        resp = requests.request(
            method,
            f"{self._base_url}{path}",
            headers={"Authorization": f"Bearer {self._api_key}", "Content-Type": "application/json"},
            json=json,
            params=params,
        )
        data = resp.json()
        if not resp.ok:
            err = data.get("error", data)
            if isinstance(err, str):
                raise SignalLabsError("error", err, "error")
            raise SignalLabsError(
                code=err.get("code", "error"),
                message=err.get("message", str(err)),
                error_type=err.get("type", "error"),
                upgrade_url=err.get("upgrade_url"),
                docs_url=err.get("docs_url"),
            )
        return data


class _Companies:
    def __init__(self, client: SignalLabs):
        self._c = client

    def list(self) -> list:
        return self._c._request("GET", "/companies")["data"]

    def create(self, name: str = None, domain: str = None, **kwargs) -> dict:
        body = {k: v for k, v in {**kwargs, "name": name, "domain": domain}.items() if v is not None}
        return self._c._request("POST", "/companies", json=body)["data"]

    def get(self, company_id: str) -> dict:
        return self._c._request("GET", f"/companies/{company_id}")["data"]

    def products(self, company_id: str) -> "_Products":
        return _Products(self._c, company_id)

    def competitors(self, company_id: str) -> "_Competitors":
        return _Competitors(self._c, company_id)

    def battlecards(self, company_id: str) -> "_Battlecards":
        return _Battlecards(self._c, company_id)

    def signals(self, company_id: str) -> "_Signals":
        return _Signals(self._c, company_id)


class _Products:
    def __init__(self, client: SignalLabs, company_id: str):
        self._c = client
        self._cid = company_id

    def list(self) -> list:
        return self._c._request("GET", f"/companies/{self._cid}/products")["data"]

    def create(self, name: str, **kwargs) -> dict:
        return self._c._request("POST", f"/companies/{self._cid}/products", json={"name": name, **kwargs})["data"]


class _Competitors:
    def __init__(self, client: SignalLabs, company_id: str):
        self._c = client
        self._cid = company_id

    def list(self, product_id: str = None) -> list:
        params = {"product_id": product_id} if product_id else None
        return self._c._request("GET", f"/companies/{self._cid}/competitors", params=params)["data"]

    def add(self, name: str, website: str = None, relationship_type: str = "direct", **kwargs) -> list:
        return self._c._request("POST", f"/companies/{self._cid}/competitors", json={
            "competitors": [{"name": name, "website": website, "relationship_type": relationship_type, **kwargs}]
        })["data"]

    def discover(self, product_context: str = None) -> list:
        body = {"product_context": product_context} if product_context else {}
        return self._c._request("POST", f"/companies/{self._cid}/competitors/discover", json=body)["data"]["suggestions"]


class _Battlecards:
    def __init__(self, client: SignalLabs, company_id: str):
        self._c = client
        self._cid = company_id

    def list(self, competitor_id: str = None, enablement_focus: str = None) -> list:
        params = {}
        if competitor_id:
            params["competitor_id"] = competitor_id
        if enablement_focus:
            params["enablement_focus"] = enablement_focus
        return self._c._request("GET", f"/companies/{self._cid}/battlecards", params=params or None)["data"]

    def generate(self, competitor_id: str, enablement_focus: str = "gtm_sales", special_instructions: str = None) -> dict:
        body = {"competitor_id": competitor_id, "enablement_focus": enablement_focus}
        if special_instructions:
            body["special_instructions"] = special_instructions
        return self._c._request("POST", f"/companies/{self._cid}/battlecards/generate", json=body)["data"]


class _Signals:
    def __init__(self, client: SignalLabs, company_id: str):
        self._c = client
        self._cid = company_id

    def list(self, competitor_id: str = None, limit: int = 50) -> list:
        params = {"limit": limit}
        if competitor_id:
            params["competitor_id"] = competitor_id
        return self._c._request("GET", f"/companies/{self._cid}/signals", params=params)["data"]

    def summary(self, days: int = 7) -> dict:
        return self._c._request("GET", f"/companies/{self._cid}/signals/summary", params={"days": days})["data"]


class _AI:
    def __init__(self, client: SignalLabs):
        self._c = client

    def chat(self, message: str, company_id: str, conversation_id: str = None) -> dict:
        body = {"message": message, "company_id": company_id}
        if conversation_id:
            body["conversation_id"] = conversation_id
        return self._c._request("POST", "/ai/chat", json=body)["data"]
