from typing import Literal, Optional
from pydantic import BaseModel


class OrderingField(BaseModel):
    field_name: str
    sort_direction: Literal["Ascending", "Descending"] = "Ascending"

    def to_payload(self) -> dict:
        return {"FieldName": self.field_name, "SortDirection": self.sort_direction}


class EntityQueryConfig(BaseModel):
    """Base query filter config shared across all extract endpoints."""

    ids: list[int] = []
    is_active_filter: Literal["ActiveOnly", "InactiveOnly", "NoFilter"] = "ActiveOnly"
    source_system_id: Optional[int] = None
    source_ids: list[int] = []
    source_id_strings: list[str] = []
    ordering_fields: list[OrderingField] = []
    count: Optional[int] = None
    offset: Optional[int] = None

    def to_payload(self) -> dict:
        p: dict = {"IsActiveFilter": self.is_active_filter}
        if self.ids:
            p["Ids"] = self.ids
        if self.source_system_id is not None:
            p["SourceSystemId"] = self.source_system_id
        if self.source_ids:
            p["SourceIds"] = self.source_ids
        if self.source_id_strings:
            p["SourceIdStrings"] = self.source_id_strings
        if self.ordering_fields:
            p["OrderingFields"] = [f.to_payload() for f in self.ordering_fields]
        if self.count is not None:
            p["Count"] = self.count
        if self.offset is not None:
            p["Offset"] = self.offset
        return p


class MiddlewareAttribute(BaseModel):
    Name: Optional[str] = None
    Value: Optional[str] = None


class ValidationResult(BaseModel):
    Message: Optional[str] = None


class ExtractResponse(BaseModel):
    """Generic wrapper for PE extract ByQuery responses."""

    TotalRecords: Optional[int] = None
    Data: list[dict] = []
    Validations: list[ValidationResult] = []
