
import requests
from django.conf import settings


class EdefClientError(Exception):
    """Erreur générique pour les appels e-MCF."""
    pass


class EdefClient:
    def __init__(self, base_url=None, token=None, timeout=None):
        self.base_url = base_url or settings.EDEF_BASE_URL.rstrip("/")
        self.token = token or settings.EDEF_API_TOKEN
        self.timeout = timeout or getattr(settings, "EDEF_TIMEOUT", 10)

    def _headers(self):
        return {
            "Authorization": f"Bearer {self.token}",
            "Accept": "application/json",
            "Content-Type": "application/json",
        }

    def _request(self, method, path, **kwargs):
        url = f"{self.base_url}{path}"
        headers = self._headers()
        headers.update(kwargs.pop("headers", {}))

        try:
            resp = requests.request(
                method=method,
                url=url,
                headers=headers,
                timeout=self.timeout,
                **kwargs,
            )
        except requests.RequestException as e:
            raise EdefClientError(f"Erreur de connexion à e-MCF: {e}")

        # tu peux adapter selon les codes d'erreur que renvoie la DGI
        if not resp.ok:
            try:
                data = resp.json()
            except Exception:
                data = resp.text
            raise EdefClientError(
                f"Erreur e-MCF {resp.status_code}: {data}"
            )

        try:
            return resp.json()
        except ValueError:
            return resp.text

    # ---------- FACTURATION ----------

    def get_invoice_status(self):
        # GET /api/invoice/
        return self._request("GET", "/api/invoice/")

    def create_invoice(self, payload: dict):
        # POST /api/invoice/
        return self._request("POST", "/api/invoice/", json=payload)

    def confirm_invoice(self, uid: str, payload: dict):
        # PUT /api/invoice/{uid}/CONFIRM
        path = f"/api/invoice/{uid}/CONFIRM"
        return self._request("PUT", path, json=payload)

    def cancel_invoice(self, uid: str):
        # PUT /api/invoice/{uid}/CANCEL
        path = f"/api/invoice/{uid}/CANCEL"
        return self._request("PUT", path)

    def get_invoice(self, uid: str):
        # GET /api/invoice/{uid}
        path = f"/api/invoice/{uid}"
        return self._request("GET", path)

    # ---------- INFORMATION ----------

    def info_status(self):
        return self._request("GET", "/api/info/status")

    def info_tax_groups(self):
        return self._request("GET", "/api/info/taxGroups")

    def info_invoice_types(self):
        return self._request("GET", "/api/info/invoiceTypes")

    def info_payment_types(self):
        return self._request("GET", "/api/info/paymentTypes")

    def info_client_types(self):
        return self._request("GET", "/api/info/clientTypes")

    def info_reference_types(self):
        return self._request("GET", "/api/info/referenceTypes")

    def info_item_types(self):
        return self._request("GET", "/api/info/itemTypes")

    def info_currency_rates(self):
        return self._request("GET", "/api/info/currencyRates")
