"""Type definitions for AgentBill SDK"""
from typing import TypedDict, Optional, Dict, Any, List


class AgentBillConfig(TypedDict):
    """Configuration for AgentBill SDK"""
    api_key: str  # Required
    base_url: Optional[str]  # Optional
    customer_id: Optional[str]  # Optional
    customer_external_id: Optional[str]  # Optional
    agent_id: Optional[str]  # Optional
    agent_external_id: Optional[str]  # Optional
    daily_budget: Optional[float]  # Optional
    monthly_budget: Optional[float]  # Optional
    debug: Optional[bool]  # Optional
    account_id: Optional[str]  # Optional


class TraceContext(TypedDict):
    """Trace context information"""
    trace_id: str
    span_id: str
    customer_id: Optional[str]


class GroupByKeys(TypedDict, total=False):
    """Allowed business grouping keys for signal group_by parameter.
    
    Only whitelisted keys are accepted to prevent attribute sprawl.
    """
    session_id: str
    workflow_id: str
    batch_id: str
    correlation_id: str


class Signal(TypedDict, total=False):
    """Typed signal payload for IDE autocompletion — no Pydantic dependency.
    
    v8.1.0: Added as part of Signals Revamp Phase 2.
    
    Example:
        >>> from agentbill import Signal
        >>> sig: Signal = {
        ...     "event_name": "purchase",
        ...     "revenue": 99.99,
        ...     "metadata": {"product_id": "prod-123"},
        ... }
    """
    event_name: str                    # Required
    revenue: Optional[float]
    currency: str
    metadata: Optional[Dict[str, Any]]
    customer_id: Optional[str]
    session_id: Optional[str]
    trace_id: Optional[str]
    span_id: Optional[str]
    parent_span_id: Optional[str]
    event_type: Optional[str]
    event_value: Optional[float]
    order_id: Optional[str]
    order_external_id: Optional[str]
    group_by: Optional[Dict[str, str]]
    idempotency_key: Optional[str]
    # AI telemetry
    model: Optional[str]
    provider: Optional[str]
    input_tokens: Optional[int]
    output_tokens: Optional[int]
    latency_ms: Optional[float]


class CostAmount(TypedDict, total=False):
    """Pre-calculated cost amount (Variant A)."""
    amount: float       # Required – e.g. 0.002
    currency: str       # Required – e.g. "USD"


class CostAttributes(TypedDict, total=False):
    """Raw usage attributes for server-side cost computation (Variant B).
    
    Keys follow OpenTelemetry Semantic Conventions for GenAI.
    """
    model: str                    # gen_ai.response.model
    input_tokens: int             # gen_ai.usage.input_tokens
    output_tokens: int            # gen_ai.usage.output_tokens
    cached_input_tokens: Optional[int]    # gen_ai.usage.cached_input_tokens
    reasoning_output_tokens: Optional[int]  # gen_ai.usage.reasoning_output_tokens


class CostData(TypedDict, total=False):
    """Manual cost/usage pass-through data (Phase 3).
    
    Supports two variants:
      - Variant A (Pre-calculated): Provide ``vendor`` + ``cost`` with amount/currency.
        Sets ``agentbill.cost.provided = true``; server skips model_pricing lookup.
      - Variant B (Raw Usage): Provide ``vendor`` + ``attributes`` with model/tokens.
        Server computes cost via model_pricing table.
    
    v8.1.0: Added as part of Signals Revamp Phase 2 (type only).
    v8.2.0: Restructured to two-variant model (Phase 3).
    
    Example (Variant A):
        >>> cost = CostData(vendor="openai", cost=CostAmount(amount=0.002, currency="USD"))
    
    Example (Variant B):
        >>> cost = CostData(vendor="anthropic", attributes=CostAttributes(
        ...     model="claude-3-sonnet", input_tokens=500, output_tokens=150))
    """
    vendor: str                            # Required – e.g. "openai", "anthropic"
    cost: Optional[CostAmount]             # Variant A: pre-calculated cost
    attributes: Optional[CostAttributes]   # Variant B: raw usage for server computation
    model: Optional[str]                   # Optional top-level model name for display
    start_time: Optional[str]              # Optional RFC3339 timestamp


class BulkResult(TypedDict):
    """Result from record_bulk() or SignalsResource.create_many().
    
    v8.1.0: Added as part of Signals Revamp Phase 2.
    """
    success: bool
    processed: int
    results: List[Dict[str, Any]]
    error: Optional[str]
