"""CRM provider protocol and filter definitions."""

from __future__ import annotations

from dataclasses import dataclass
from enum import Enum
from typing import Any, Dict, List, Protocol, runtime_checkable


class FilterOp(str, Enum):
    EQ = "eq"
    NEQ = "neq"
    LT = "lt"
    LTE = "lte"
    GT = "gt"
    GTE = "gte"
    IS_NULL = "is_null"
    IS_NOT_NULL = "is_not_null"
    IN = "in"
    NOT_IN = "not_in"
    LAST_N_DAYS = "last_n_days"
    NOT_LAST_N_DAYS = "not_last_n_days"
    BEFORE_TODAY = "before_today"


@dataclass(frozen=True)
class Filter:
    field: str
    op: FilterOp
    value: Any = None


@dataclass(frozen=True)
class OrGroup:
    """Multiple filters combined with OR. Wrapped in AND at top level."""

    filters: List[Filter]


FilterExpr = Filter | OrGroup


@runtime_checkable
class CRMProvider(Protocol):
    name: str  # "salesforce" | "hubspot" | "dynamics"

    def count(self, object_type: str, filters: List[FilterExpr]) -> int: ...

    def query(
        self,
        object_type: str,
        fields: List[str],
        filters: List[FilterExpr],
        order_by: str | None = None,
        order_dir: str = "ASC",
        nulls_first: bool = False,
        limit: int = 100,
    ) -> List[Dict[str, Any]]: ...

    def describe(self, object_type: str) -> Dict[str, Any]: ...

    def update_record(self, object_type: str, record_id: str, values: Dict[str, Any]) -> Dict[str, Any]: ...

    def create_record(self, object_type: str, values: Dict[str, Any]) -> Dict[str, Any]: ...

    def supports_object(self, object_type: str) -> bool: ...

    def drain_warnings(self) -> List[str]: ...

    def drain_queries(self) -> List[str]: ...


__all__ = ["FilterOp", "Filter", "OrGroup", "FilterExpr", "CRMProvider"]
