"""Backend configuration using pydantic-settings.

Reads from environment variables and .env file automatically.
Uses a flat settings model so that standard env vars like SSH_HOST,
JELLYFIN_URL etc. are picked up directly without nested-model complications.
"""

from __future__ import annotations

import logging
from functools import lru_cache
from pathlib import Path

from pydantic_settings import BaseSettings

from media_library_viewer_api.logging_utils import describe_settings

logger = logging.getLogger(__name__)


class Settings(BaseSettings):
    """Flat application settings read from env vars / .env file."""

    # Logging
    log_level: str = "INFO"
    log_format: str = "text"  # "text" or "json"

    # Auth / OIDC (Authentik-compatible JWT validation)
    auth_enabled: bool = False
    oidc_issuer_url: str = ""
    oidc_audience: str = ""
    oidc_jwks_url: str = ""
    oidc_clock_skew_seconds: int = 30

    # SMTP (optional, used for Users -> message popup)
    smtp_host: str = ""
    smtp_port: int = 587
    smtp_username: str = ""
    smtp_password: str = ""
    smtp_from_address: str = ""
    smtp_from_name: str = "Manage"
    smtp_use_tls: bool = True
    smtp_use_ssl: bool = False
    smtp_timeout: int = 30

    # Legacy SSH fallback (new preferred path is machine-specific settings)
    ssh_host: str = ""
    ssh_username: str = ""
    ssh_port: int = 22
    ssh_key_directory: str = ""
    ssh_key_name: str = ""
    ssh_password: str = ""
    ssh_known_hosts_path: str = ""

    # Observability
    prometheus_enabled: bool = True

    # Remote paths
    remote_media_root: str = ""
    remote_path_prefix: str = ""

    # Derived convenience
    @property
    def media_root(self) -> str:
        return self.remote_media_root or ""

    @property
    def path_prefix(self) -> str:
        return self.remote_path_prefix or ""

    @property
    def ssh_key_path(self) -> str:
        if not self.ssh_key_directory or not self.ssh_key_name:
            return ""
        return str(Path(self.ssh_key_directory) / self.ssh_key_name)

    @property
    def ssh_known_hosts_file(self) -> Path:
        return Path(self.ssh_known_hosts_path or ".cache/media_library_viewer/known_hosts")

    model_config = {"env_file": ".env", "env_file_encoding": "utf-8", "extra": "ignore"}  # type: ignore[assignment]


def _find_env_file() -> str | None:
    """Look for .env in CWD, then parent directories up to the repo root."""
    current = Path.cwd()
    for directory in [current, *current.parents]:
        candidate = directory / ".env"
        if candidate.is_file():
            return str(candidate)
        if (directory / ".git").exists():
            break
    return None


@lru_cache
def get_settings() -> Settings:
    """Return a cached Settings instance."""
    env_file = _find_env_file()
    settings = Settings(_env_file=env_file) if env_file else Settings()
    logger.info(
        "Loaded backend settings from %s: %s",
        env_file or "environment/defaults",
        describe_settings(settings),
    )
    return settings
