from typing import Optional, Union

from galtea.utils.from_camel_case_base_model import FromCamelCaseBaseModel
from galtea.utils.undefined import UNDEFINED, UndefinedType


class CostInfoProperties(FromCamelCaseBaseModel):
    cost_per_input_token: Optional[float] = None
    cost_per_output_token: Optional[float] = None
    cost_per_cache_read_input_token: Optional[float] = None
    cost: Optional[float] = None


class UsageInfoProperties(FromCamelCaseBaseModel):
    input_tokens: Optional[int] = None
    output_tokens: Optional[int] = None
    cache_read_input_tokens: Optional[int] = None
    tokens: Optional[int] = None


# Legacy evaluation-based models (maintained for backward compatibility)
class InferenceResultBase(CostInfoProperties, UsageInfoProperties):
    """Model for creating inference results with mandatory fields (POST operation)."""

    session_id: str
    actual_input: Optional[str] = None
    actual_output: Optional[str] = None
    retrieval_context: Optional[str] = None
    latency: Optional[float] = None
    conversation_simulator_version: Optional[str] = None


class InferenceResult(InferenceResultBase):
    id: str
    index: int


class InferenceResultUpdate(FromCamelCaseBaseModel):
    """Model for updating inference results with all optional fields (PATCH operation).

    Supports the undefined/null/value pattern:
    - UNDEFINED (default): Field was not provided, excluded from API calls
    - None: Field was explicitly set to null, sent as null to the API
    - Value: Field was explicitly set to a value, sent to the API
    """

    # Overridden from CostInfoProperties to support UNDEFINED
    cost_per_input_token: Union[float, None, UndefinedType] = UNDEFINED
    cost_per_output_token: Union[float, None, UndefinedType] = UNDEFINED
    cost_per_cache_read_input_token: Union[float, None, UndefinedType] = UNDEFINED
    cost: Union[float, None, UndefinedType] = UNDEFINED

    # Overridden from UsageInfoProperties to support UNDEFINED
    input_tokens: Union[int, None, UndefinedType] = UNDEFINED
    output_tokens: Union[int, None, UndefinedType] = UNDEFINED
    cache_read_input_tokens: Union[int, None, UndefinedType] = UNDEFINED
    tokens: Union[int, None, UndefinedType] = UNDEFINED

    # Fields specific to InferenceResultUpdate
    session_id: Union[str, None, UndefinedType] = UNDEFINED
    actual_input: Union[str, None, UndefinedType] = UNDEFINED
    actual_output: Union[str, None, UndefinedType] = UNDEFINED
    retrieval_context: Union[str, None, UndefinedType] = UNDEFINED
    latency: Union[float, None, UndefinedType] = UNDEFINED
    conversation_simulator_version: Union[str, None, UndefinedType] = UNDEFINED
    index: Union[int, None, UndefinedType] = UNDEFINED
    created_at: Union[str, None, UndefinedType] = UNDEFINED
    deleted_at: Union[str, None, UndefinedType] = UNDEFINED
