"""
Unified Configuration Manager

Provides a single source of truth for all configuration values with a clear hierarchy:
1. Environment variables (highest priority)
2. .env file
3. Database settings
4. Hardcoded defaults (lowest priority)
"""

import os
from pathlib import Path
from typing import Any, Dict, Optional
from functools import lru_cache
from dotenv import load_dotenv

# Load environment variables from .env file
PROJECT_ROOT = Path(__file__).parent.parent.parent.parent
ENV_PATH = PROJECT_ROOT / '.env'
if ENV_PATH.exists():
    load_dotenv(ENV_PATH)


class Settings:
    """Centralized configuration settings"""

    # Project paths
    PROJECT_ROOT: Path = PROJECT_ROOT
    DB_PATH: Path = PROJECT_ROOT / 'database' / 'media_downloader.db'
    CONFIG_PATH: Path = PROJECT_ROOT / 'config' / 'settings.json'
    LOG_PATH: Path = PROJECT_ROOT / 'logs'
    TEMP_DIR: Path = PROJECT_ROOT / 'temp'
    COOKIES_DIR: Path = PROJECT_ROOT / 'cookies'
    DATA_DIR: Path = PROJECT_ROOT / 'data'
    VENV_BIN: Path = PROJECT_ROOT / 'venv' / 'bin'
    MEDIA_BASE_PATH: Path = Path(os.getenv("MEDIA_BASE_PATH", "/opt/immich/md"))
    REVIEW_PATH: Path = Path(os.getenv("REVIEW_PATH", "/opt/immich/review"))
    RECYCLE_PATH: Path = Path(os.getenv("RECYCLE_PATH", "/opt/immich/recycle"))

    # External tool paths (use venv by default)
    YT_DLP_PATH: Path = VENV_BIN / 'yt-dlp'
    GALLERY_DL_PATH: Path = VENV_BIN / 'gallery-dl'
    PYTHON_PATH: Path = VENV_BIN / 'python3'

    # Database configuration
    DATABASE_BACKEND: str = os.getenv("DATABASE_BACKEND", "sqlite")
    DATABASE_URL: str = os.getenv("DATABASE_URL", "")
    DB_POOL_SIZE: int = int(os.getenv("DB_POOL_SIZE", "20"))
    DB_CONNECTION_TIMEOUT: float = float(os.getenv("DB_CONNECTION_TIMEOUT", "30.0"))

    # Process timeouts (seconds)
    PROCESS_TIMEOUT_SHORT: int = int(os.getenv("PROCESS_TIMEOUT_SHORT", "2"))
    PROCESS_TIMEOUT_MEDIUM: int = int(os.getenv("PROCESS_TIMEOUT_MEDIUM", "10"))
    PROCESS_TIMEOUT_LONG: int = int(os.getenv("PROCESS_TIMEOUT_LONG", "120"))

    # WebSocket configuration
    WEBSOCKET_TIMEOUT: float = float(os.getenv("WEBSOCKET_TIMEOUT", "30.0"))

    # Background task intervals (seconds)
    ACTIVITY_LOG_INTERVAL: int = int(os.getenv("ACTIVITY_LOG_INTERVAL", "300"))
    EMBEDDING_QUEUE_CHECK_INTERVAL: int = int(os.getenv("EMBEDDING_QUEUE_CHECK_INTERVAL", "30"))
    EMBEDDING_BATCH_SIZE: int = int(os.getenv("EMBEDDING_BATCH_SIZE", "10"))
    EMBEDDING_BATCH_LIMIT: int = int(os.getenv("EMBEDDING_BATCH_LIMIT", "50000"))

    # Thumbnail generation
    THUMBNAIL_DB_TIMEOUT: float = float(os.getenv("THUMBNAIL_DB_TIMEOUT", "30.0"))
    THUMBNAIL_SIZE: tuple = (300, 300)

    # Video proxy configuration
    PROXY_FILE_CACHE_DURATION: int = int(os.getenv("PROXY_FILE_CACHE_DURATION", "300"))

    # Redis cache configuration
    REDIS_HOST: str = os.getenv("REDIS_HOST", "127.0.0.1")
    REDIS_PORT: int = int(os.getenv("REDIS_PORT", "6379"))
    REDIS_DB: int = int(os.getenv("REDIS_DB", "0"))
    REDIS_TTL: int = int(os.getenv("REDIS_TTL", "300"))

    # API configuration
    API_VERSION: str = "13.13.1"
    API_TITLE: str = "Media Downloader API"
    API_DESCRIPTION: str = "Web API for managing media downloads"

    # CORS configuration
    ALLOWED_ORIGINS: list = os.getenv(
        "ALLOWED_ORIGINS",
        "http://localhost:5173,http://localhost:3000,http://127.0.0.1:5173,http://127.0.0.1:3000"
    ).split(",")

    # Security
    SECURE_COOKIES: bool = os.getenv("SECURE_COOKIES", "false").lower() == "true"
    SESSION_SECRET_KEY: str = os.getenv("SESSION_SECRET_KEY", "")
    CSRF_SECRET_KEY: str = os.getenv("CSRF_SECRET_KEY", "")

    # Rate limiting
    RATE_LIMIT_DEFAULT: str = os.getenv("RATE_LIMIT_DEFAULT", "100/minute")
    RATE_LIMIT_STRICT: str = os.getenv("RATE_LIMIT_STRICT", "10/minute")

    @classmethod
    def get(cls, key: str, default: Any = None) -> Any:
        """Get a configuration value by key"""
        return getattr(cls, key, default)

    @classmethod
    def get_path(cls, key: str) -> Path:
        """Get a path configuration value, ensuring it's a Path object"""
        value = getattr(cls, key, None)
        if value is None:
            raise ValueError(f"Configuration key {key} not found")
        if isinstance(value, Path):
            return value
        return Path(value)


@lru_cache()
def get_settings() -> Settings:
    """Get cached settings instance"""
    return Settings()


# Convenience exports
settings = get_settings()
