import requests


class PosSdk:
    def __init__(self, base_url='https://api.pos.example.com/v3', api_key=None, bearer=None, timeout=30):
        self.base_url = base_url.rstrip('/')
        self.api_key = api_key
        self.bearer = bearer
        self.timeout = timeout

    def _headers(self):
        h = {'Content-Type': 'application/json', 'Accept': 'application/json'}
        if self.bearer:
            h['Authorization'] = f'Bearer {self.bearer}'
        if self.api_key:
            h['X-API-Key'] = self.api_key
        return h

    def _request(self, method, path, body=None, query=None):
        r = requests.request(
            method,
            self.base_url + path,
            json=body,
            params=query,
            headers=self._headers(),
            timeout=self.timeout,
        )
        data = r.json() if r.content else {}
        if r.status_code >= 400:
            raise PosSdkError(data.get('error', f'HTTP {r.status_code}'), r.status_code, data)
        return data

    def list_products(self, page=1, per_page=20, q=''):
        return self._request('GET', '/catalog/products', query={'page': page, 'per_page': per_page, 'q': q})

    def create_product(self, product):
        return self._request('POST', '/catalog/products', body=product)

    def create_sale(self, sale):
        return self._request('POST', '/sales', body=sale)

    def bnpl_checkout(self, payload):
        return self._request('POST', '/finance/bnpl/checkout', body=payload)

    def loan_apply(self, application):
        return self._request('POST', '/finance/loans/apply', body=application)

    def chain_escrow(self, payload):
        return self._request('POST', '/chain/escrow', body=payload)

    def cleanroom_query(self, query):
        return self._request('POST', '/cleanroom/query', body=query)


class PosSdkError(Exception):
    def __init__(self, message, status_code=0, details=None):
        super().__init__(message)
        self.status_code = status_code
        self.details = details or {}