from functools import lru_cache

from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    """Application configuration loaded from environment variables."""

    model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")

    app_name: str = "NVR API Gateway"
    environment: str = "production"
    log_level: str = "INFO"

    mongo_uri: str = Field(
        default="mongodb://root:Unsteady-Emphasis-Wildly-Staging@mongodb:27017/?authSource=admin",
        alias="MONGO_URI",
    )
    mongo_db: str = Field(default="nvr", alias="MONGO_DB")
    mongo_collection: str = Field(default="events", alias="MONGO_COLLECTION")
    mongo_users_collection: str = Field(default="users", alias="MONGO_USERS_COLLECTION")

    minio_endpoint: str = Field(default="minio:9000", alias="MINIO_ENDPOINT")
    minio_access_key: str = Field(default="sqQuRPiRXCpvXjWJgkai", alias="MINIO_ACCESS_KEY")
    minio_secret_key: str = Field(default="oX6eCMtBJ6rIrkW6Ugu9KKdNzkuSK4v7mT5OkpYH", alias="MINIO_SECRET_KEY")
    minio_bucket: str = Field(default="nvr-footage", alias="MINIO_BUCKET")
    minio_secure: bool = Field(default=False, alias="MINIO_SECURE")

    jwt_secret: str = Field(default="change-me-in-production", alias="JWT_SECRET")
    jwt_algorithm: str = Field(default="HS256", alias="JWT_ALGORITHM")
    jwt_expiration_minutes: int = Field(default=15, alias="JWT_EXPIRATION_MINUTES")
    refresh_token_expiration_days: int = Field(default=7, alias="REFRESH_TOKEN_EXPIRATION_DAYS")

    signed_url_expiration_seconds: int = Field(default=900, alias="SIGNED_URL_EXPIRATION_SECONDS")
    rate_limit_requests: int = Field(default=100, alias="RATE_LIMIT_REQUESTS")
    rate_limit_window_seconds: int = Field(default=60, alias="RATE_LIMIT_WINDOW_SECONDS")

    admin_username: str = Field(default="admin", alias="ADMIN_USERNAME")
    admin_password: str | None = Field(default=None, alias="ADMIN_PASSWORD")
    admin_password_hash: str | None = Field(default=None, alias="ADMIN_PASSWORD_HASH")

    cameras_json: str | None = Field(default=None, alias="CAMERAS_JSON")
    ingestion_config_path: str | None = Field(default="../Ingestion/config.json", alias="INGESTION_CONFIG_PATH")


@lru_cache
def get_settings() -> Settings:
    return Settings()
