"""
Lynara — Main SDK client.

Usage:
    from lynara import Lynara

    client = Lynara(
        url="https://api.lynara.ai",
        api_key="lnr_live_xxx",
        company_id="your-company-uuid",
    )

    # Ventes
    invoices = client.sales.invoices.list(limit=50)
    client.sales.quotes.create({"customer_id": "...", "total": 5000})

    # Achats
    for invoice in client.purchases.invoices.iterate():
        print(invoice["reference"])

    # Banque
    client.banking.transactions.list(limit=100)

    # Catalogue
    client.catalog.products.bulk_create([
        {"name": "Produit A", "price": 100},
        {"name": "Produit B", "price": 200},
    ])

    # Inventaire
    stock = client.inventory.stock_levels.list()

    # CRM
    leads = client.crm.leads.list(limit=50)

    # RH
    for employee in client.rh.employees.iterate():
        print(employee["first_name"])

    # Export
    csv_data = client.catalog.customers.export(format="csv")

    # Close when done
    client.close()
"""

from typing import Optional, Dict, Any

from .http import HttpClient
from .modules.sales import Sales
from .modules.purchases import Purchases
from .modules.banking import Banking
from .modules.inventory import Inventory
from .modules.catalog import Catalog
from .modules.crm import CRM
from .modules.rh import RH


class Lynara:
    """
    Lynara SDK client — programmatic access to all modules.

    Args:
        url: Base URL of the Lynara API (e.g., "https://api.lynara.ai")
        api_key: API key starting with "lnr_live_" or "lnr_test_"
        company_id: Your company UUID (required for all data operations)
        timeout: Request timeout in seconds (default: 30)
        max_retries: Max retry attempts for 5xx / network errors (default: 3)
        retry_delay: Base delay between retries in seconds (default: 1.0)

    Modules:
        sales: Ventes — devis, commandes, factures, livraisons, avoirs, paiements
        purchases: Achats — factures fournisseurs, paiements, devis fournisseurs
        banking: Banque — releves, transactions, rapprochements
        inventory: Inventaire — stockage, niveaux, lots, mouvements, series
        catalog: Catalogue — clients, fournisseurs, produits, categories, prix
        crm: CRM — leads, opportunites, activites, pipeline
        rh: RH — employes, contrats, conges, paie, formations, competences

    Each module resource supports:
        .list(limit, offset, order_by, order, search, **filters)
        .get(record_id)
        .create(data)
        .update(record_id, data)
        .delete(record_id)
        .bulk_create(items)  — max 500 per call
        .export(format="json"|"csv", limit=10000)
        .count()
        .iterate(batch_size=100, **filters)  — auto-paginated generator
    """

    def __init__(
        self,
        url: str,
        api_key: str,
        company_id: str = "",
        timeout: int = 30,
        max_retries: int = 3,
        retry_delay: float = 1.0,
    ):
        if not url:
            raise ValueError("url is required")
        if not api_key:
            raise ValueError("api_key is required")
        if not api_key.startswith(("lnr_live_", "lnr_test_")):
            raise ValueError(
                "Invalid API key format. Must start with 'lnr_live_' or 'lnr_test_'. "
                "Generate a key from Lynara Settings > API Keys."
            )
        if not company_id:
            raise ValueError(
                "company_id is required. Find it in Lynara Settings > General."
            )

        self._url = url.rstrip("/")
        self._api_key = api_key
        self._company_id = company_id
        self._is_test = api_key.startswith("lnr_test_")

        self._http = HttpClient(
            base_url=self._url,
            api_key=api_key,
            company_id=company_id,
            timeout=timeout,
            max_retries=max_retries,
            retry_delay=retry_delay,
        )

        # Module accessors
        self.sales = Sales(self._http)
        self.purchases = Purchases(self._http)
        self.banking = Banking(self._http)
        self.inventory = Inventory(self._http)
        self.catalog = Catalog(self._http)
        self.crm = CRM(self._http)
        self.rh = RH(self._http)

    @property
    def is_test_mode(self) -> bool:
        """Whether this client is using a test API key."""
        return self._is_test

    @property
    def base_url(self) -> str:
        """The base URL this client connects to."""
        return self._url

    @property
    def company_id(self) -> str:
        """The company ID this client operates on."""
        return self._company_id

    def whoami(self) -> Dict[str, Any]:
        """
        Get information about the current API key.

        Returns:
            Dict with company_id, permissions, allowed_modules, rate_limit, etc.
        """
        return self._http.get("/sdk/v1/schema")

    def schema(self, module: Optional[str] = None) -> Any:
        """
        Get the available modules and resources schema.

        Args:
            module: Optional module name to get detailed schema for.

        Returns:
            Full schema dict or module-specific schema.
        """
        if module:
            return self._http.get(f"/sdk/v1/schema/{module}")
        return self._http.get("/sdk/v1/schema")

    def close(self):
        """Close the underlying HTTP session."""
        self._http.close()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
        return False

    def __repr__(self) -> str:
        mode = "test" if self._is_test else "live"
        return f"Lynara(url='{self._url}', company='{self._company_id}', mode='{mode}')"


# Alias for backwards compatibility and convenience
LynaraClient = Lynara
