"""Pydantic models for the orchestration API."""

from __future__ import annotations

from datetime import datetime
from typing import Dict, List, Optional
from uuid import uuid4

from pydantic import BaseModel, Field, HttpUrl


class SessionCreateRequest(BaseModel):
    """Incoming payload describing a requested embedding-atlas session."""

    session_id: Optional[str] = Field(
        default=None,
        description="Optional session identifier; generated when omitted.",
    )
    data_url: HttpUrl = Field(
        description="HTTPS location of the dataset to visualize.",
    )
    input_filename: Optional[str] = Field(
        default=None,
        description="Filename to persist the downloaded dataset under.",
    )
    extra_args: List[str] = Field(
        default_factory=list,
        description="Additional CLI arguments forwarded to embedding-atlas.",
    )
    environment: Dict[str, str] = Field(
        default_factory=dict,
        description="Environment variables injected into the managed container.",
    )
    labels: Dict[str, str] = Field(
        default_factory=dict,
        description="Extra Docker labels assigned to the managed container.",
    )
    image: Optional[str] = Field(
        default=None,
        description="Override Docker image for the managed container.",
    )
    host: Optional[str] = Field(
        default=None,
        description="Host binding forwarded to embedding-atlas (defaults to settings.container_host).",
    )
    port: Optional[int] = Field(
        default=None,
        description="Preferred host port for the embedding-atlas UI.",
    )
    auto_remove_seconds: Optional[int] = Field(
        default=None,
        description="Lifetime of the session before automatic cleanup triggers.",
    )

    def normalised_session_id(self) -> str:
        return self.session_id or uuid4().hex


class SessionRecord(BaseModel):
    """Internal representation of a live session."""

    session_id: str
    container_id: str
    container_name: str
    port: int
    host: str
    started_at: datetime
    expires_at: datetime
    dataset_path: str


class SessionResponse(BaseModel):
    """HTTP response returned after a session is launched."""

    session_id: str
    container_name: str
    endpoint: str
    port: int
    host: str
    expires_at: datetime


class SessionCloseResponse(BaseModel):
    """HTTP response returned after a session is terminated."""

    session_id: str
    removed: bool


class SessionListResponse(BaseModel):
    """Shape returned when listing active sessions."""

    sessions: List[SessionRecord]


MANAGED_LABEL = "embedding-backend.managed"
EXPIRY_LABEL = "embedding-backend.expires-at"
SESSION_ID_LABEL = "embedding-backend.session-id"
DATASET_LABEL = "embedding-backend.dataset-path"


def default_labels(session_id: str, expires_at: datetime, dataset_path: str) -> Dict[str, str]:
    return {
        MANAGED_LABEL: "true",
        SESSION_ID_LABEL: session_id,
        EXPIRY_LABEL: str(int(expires_at.timestamp())),
        DATASET_LABEL: dataset_path,
    }


__all__ = [
    "SessionCreateRequest",
    "SessionRecord",
    "SessionResponse",
    "SessionCloseResponse",
    "SessionListResponse",
    "default_labels",
    "MANAGED_LABEL",
    "EXPIRY_LABEL",
    "SESSION_ID_LABEL",
    "DATASET_LABEL",
]
