"""
MemoraLabs SDK typed models.

All response types are plain Python dataclasses — no Pydantic, no extra deps.
Each class has a from_dict(d: dict) classmethod for constructing from the
JSON response bodies returned by the API.
"""
from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Optional


# ---------------------------------------------------------------------------
# Auth models
# ---------------------------------------------------------------------------


@dataclass
class SignupResponse:
    """Response from POST /v1/auth/signup."""

    tenant_id: str
    email: str
    plan: str
    api_key: str
    key_prefix: str
    message: str

    @classmethod
    def from_dict(cls, d: dict) -> "SignupResponse":
        return cls(
            tenant_id=d["tenant_id"],
            email=d["email"],
            plan=d["plan"],
            api_key=d["api_key"],
            key_prefix=d["key_prefix"],
            message=d.get("message", ""),
        )


@dataclass
class KeyRotateResponse:
    """Response from POST /v1/auth/keys/rotate."""

    api_key: str
    key_prefix: str
    message: str

    @classmethod
    def from_dict(cls, d: dict) -> "KeyRotateResponse":
        return cls(
            api_key=d["api_key"],
            key_prefix=d["key_prefix"],
            message=d.get("message", ""),
        )


# ---------------------------------------------------------------------------
# Memory models
# ---------------------------------------------------------------------------


@dataclass
class MemoryResponse:
    """A single stored memory (create / get / update response)."""

    id: str
    text: str
    created_at: int
    user_id: Optional[str] = None
    agent_id: Optional[str] = None
    session_id: Optional[str] = None
    metadata: Optional[dict[str, Any]] = None
    updated_at: Optional[int] = None
    status: str = "created"

    @classmethod
    def from_dict(cls, d: dict) -> "MemoryResponse":
        return cls(
            id=d["id"],
            text=d["text"],
            created_at=d["created_at"],
            user_id=d.get("user_id"),
            agent_id=d.get("agent_id"),
            session_id=d.get("session_id"),
            metadata=d.get("metadata"),
            updated_at=d.get("updated_at"),
            status=d.get("status", "created"),
        )


@dataclass
class MemoryListResponse:
    """Paginated list of memories (GET /v1/memory)."""

    memories: list[MemoryResponse]
    total: int
    page: int
    page_size: int

    @classmethod
    def from_dict(cls, d: dict) -> "MemoryListResponse":
        return cls(
            memories=[MemoryResponse.from_dict(m) for m in d.get("memories", [])],
            total=d["total"],
            page=d["page"],
            page_size=d["page_size"],
        )


@dataclass
class SearchResult:
    """A single item in a search response."""

    id: str
    text: str
    score: float
    created_at: int
    confidence: float = 0.0
    metadata: Optional[dict[str, Any]] = None
    user_id: Optional[str] = None
    agent_id: Optional[str] = None
    session_id: Optional[str] = None

    @classmethod
    def from_dict(cls, d: dict) -> "SearchResult":
        return cls(
            id=d["id"],
            text=d["text"],
            score=d["score"],
            created_at=d["created_at"],
            confidence=d.get("confidence", 0.0),
            metadata=d.get("metadata"),
            user_id=d.get("user_id"),
            agent_id=d.get("agent_id"),
            session_id=d.get("session_id"),
        )


@dataclass
class SearchResponse:
    """Response from POST /v1/memory/search."""

    results: list[SearchResult]
    total: int
    memories_used: int
    memories_limit: int

    @classmethod
    def from_dict(cls, d: dict) -> "SearchResponse":
        return cls(
            results=[SearchResult.from_dict(r) for r in d.get("results", [])],
            total=d["total"],
            memories_used=d["memories_used"],
            memories_limit=d["memories_limit"],
        )


@dataclass
class GapResponse:
    """Response from POST /v1/memory/gaps."""

    gaps: list[str]

    @classmethod
    def from_dict(cls, d: dict) -> "GapResponse":
        return cls(gaps=d.get("gaps", []))


# ---------------------------------------------------------------------------
# Billing models
# ---------------------------------------------------------------------------


@dataclass
class BillingStatusResponse:
    """Response from GET /v1/billing/status."""

    plan: str
    memory_count: int
    memory_limit: Optional[int]          # None = unlimited
    search_count_today: int
    search_limit_today: Optional[int]    # None = unlimited
    stripe_customer_id: Optional[str] = None
    current_period_end: Optional[int] = None
    cancel_at_period_end: bool = False

    @classmethod
    def from_dict(cls, d: dict) -> "BillingStatusResponse":
        return cls(
            plan=d["plan"],
            memory_count=d["memory_count"],
            memory_limit=d.get("memory_limit"),
            search_count_today=d.get("search_count_today", 0),
            search_limit_today=d.get("search_limit_today"),
            stripe_customer_id=d.get("stripe_customer_id"),
            current_period_end=d.get("current_period_end"),
            cancel_at_period_end=d.get("cancel_at_period_end", False),
        )


@dataclass
class CheckoutResponse:
    """Response from POST /v1/billing/checkout."""

    checkout_url: str
    session_id: str

    @classmethod
    def from_dict(cls, d: dict) -> "CheckoutResponse":
        return cls(
            checkout_url=d["checkout_url"],
            session_id=d["session_id"],
        )
