"""System-related schemas (health, version, displays)."""

from datetime import datetime
from typing import List, Literal

from pydantic import BaseModel, Field


class HealthResponse(BaseModel):
    """Health check response."""

    status: Literal["healthy", "unhealthy"] = Field(description="Service health status")
    timestamp: datetime = Field(description="Current server time")
    version: str = Field(description="Application version")
    demo_mode: bool = Field(default=False, description="Whether demo mode is active")
    auth_required: bool = Field(
        default=True, description="Whether API key authentication is required"
    )
    repo_url: str = Field(default="", description="Source code repository URL")
    donate_url: str = Field(default="", description="Donation page URL")


class VersionResponse(BaseModel):
    """Version information response."""

    version: str = Field(description="Application version")
    python_version: str = Field(description="Python version")
    api_version: str = Field(description="API version")
    demo_mode: bool = Field(default=False, description="Whether demo mode is active")


class DisplayInfo(BaseModel):
    """Display/monitor information."""

    index: int = Field(description="Display index")
    name: str = Field(description="Display name")
    width: int = Field(description="Display width in pixels")
    height: int = Field(description="Display height in pixels")
    x: int = Field(description="Display X position")
    y: int = Field(description="Display Y position")
    is_primary: bool = Field(default=False, description="Whether this is the primary display")
    refresh_rate: int = Field(description="Display refresh rate in Hz")


class DisplayListResponse(BaseModel):
    """List of available displays."""

    displays: List[DisplayInfo] = Field(description="Available displays")
    count: int = Field(description="Number of displays")


class ProcessListResponse(BaseModel):
    """List of running processes."""

    processes: List[str] = Field(description="Sorted list of unique process names")
    count: int = Field(description="Number of unique processes")


class GpuInfo(BaseModel):
    """GPU performance information."""

    name: str | None = Field(default=None, description="GPU device name")
    utilization: float | None = Field(default=None, description="GPU core usage percent")
    memory_used_mb: float | None = Field(default=None, description="GPU memory used in MB")
    memory_total_mb: float | None = Field(default=None, description="GPU total memory in MB")
    temperature_c: float | None = Field(default=None, description="GPU temperature in Celsius")
    app_memory_mb: float | None = Field(
        default=None, description="GPU memory used by this app in MB"
    )


class PerformanceResponse(BaseModel):
    """System performance metrics."""

    cpu_name: str | None = Field(default=None, description="CPU model name")
    cpu_percent: float = Field(description="System-wide CPU usage percent")
    ram_used_mb: float = Field(description="RAM used in MB")
    ram_total_mb: float = Field(description="RAM total in MB")
    ram_percent: float = Field(description="RAM usage percent")
    app_cpu_percent: float = Field(description="App process CPU usage percent")
    app_ram_mb: float = Field(description="App process resident memory in MB")
    gpu: GpuInfo | None = Field(default=None, description="GPU info (null if unavailable)")
    timestamp: datetime = Field(description="Measurement timestamp")


class RestoreResponse(BaseModel):
    """Response after restoring database backup."""

    status: str = Field(description="Status of restore operation")
    restart_scheduled: bool = Field(description="Whether server restart was scheduled")
    message: str = Field(description="Human-readable status message")


# ─── Auto-backup schemas ──────────────────────────────────────


class AutoBackupSettings(BaseModel):
    """Settings for automatic backup."""

    enabled: bool = Field(description="Whether auto-backup is enabled")
    interval_hours: float = Field(ge=0.5, le=168, description="Backup interval in hours")
    max_backups: int = Field(ge=1, le=100, description="Maximum number of backup files to keep")


class AutoBackupStatusResponse(BaseModel):
    """Auto-backup settings plus runtime status."""

    enabled: bool
    interval_hours: float
    max_backups: int
    last_backup_time: str | None = None
    next_backup_time: str | None = None


class BackupFileInfo(BaseModel):
    """Information about a saved backup file."""

    filename: str
    size_bytes: int
    created_at: str


class BackupListResponse(BaseModel):
    """List of saved backup files."""

    backups: List[BackupFileInfo]
    count: int


# ─── MQTT schemas ──────────────────────────────────────────────


class MQTTSettingsResponse(BaseModel):
    """MQTT broker settings response (password is masked)."""

    enabled: bool = Field(description="Whether MQTT is enabled")
    broker_host: str = Field(description="MQTT broker hostname or IP")
    broker_port: int = Field(ge=1, le=65535, description="MQTT broker port")
    username: str = Field(description="MQTT username (empty = anonymous)")
    password_set: bool = Field(description="Whether a password is configured")
    client_id: str = Field(description="MQTT client ID")
    base_topic: str = Field(description="Base topic prefix")


class MQTTSettingsRequest(BaseModel):
    """MQTT broker settings update request."""

    enabled: bool = Field(description="Whether MQTT is enabled")
    broker_host: str = Field(description="MQTT broker hostname or IP")
    broker_port: int = Field(ge=1, le=65535, description="MQTT broker port")
    username: str = Field(default="", description="MQTT username (empty = anonymous)")
    password: str = Field(
        default="", description="MQTT password (empty = keep existing if omitted)"
    )
    client_id: str = Field(default="ledgrab", description="MQTT client ID")
    base_topic: str = Field(default="ledgrab", description="Base topic prefix")


# ─── External URL schema ───────────────────────────────────────


class ExternalUrlResponse(BaseModel):
    """External URL setting response."""

    external_url: str = Field(
        description="External base URL (e.g. https://myserver.example.com:8080). Empty = use auto-detected URL."
    )


class ExternalUrlRequest(BaseModel):
    """External URL setting update request."""

    external_url: str = Field(default="", description="External base URL. Empty string to clear.")


# ─── Log level schemas ─────────────────────────────────────────


class LogLevelResponse(BaseModel):
    """Current log level response."""

    level: str = Field(
        description="Current effective log level name (e.g. DEBUG, INFO, WARNING, ERROR, CRITICAL)"
    )


class LogLevelRequest(BaseModel):
    """Request to change the log level."""

    level: str = Field(description="New log level name (DEBUG, INFO, WARNING, ERROR, CRITICAL)")
