"""
Application configuration using Pydantic Settings.

Supports environment variables and .env files for configuration.
"""

from functools import lru_cache
from pathlib import Path
from typing import Literal

from pydantic import Field, computed_field
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    """Application settings with environment variable support."""

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

    # Application
    app_name: str = "DataShaper AI"
    app_version: str = "0.1.0"
    debug: bool = False
    environment: Literal["development", "staging", "production"] = "development"

    # API
    api_v1_prefix: str = "/api/v1"
    cors_origins: list[str] = Field(
        default_factory=lambda: ["http://localhost:3000", "http://localhost:5173"]
    )
    max_upload_size_mb: int = 500

    # Database
    duckdb_path: str = "data/metadata.duckdb"
    sqlite_path: str = "data/metadata.sqlite"
    use_duckdb: bool = True  # True = DuckDB, False = SQLite

    # Storage
    upload_dir: Path = Path("data/uploads")
    processed_dir: Path = Path("data/processed")
    export_dir: Path = Path("data/exports")
    temp_dir: Path = Path("data/temp")
    file_retention_days: int = 7  # Default: 7 days
    
    # Redis
    redis_url: str = "redis://localhost:6379/0"

    # AI/LLM Configuration
    openai_api_key: str = ""
    anthropic_api_key: str = ""
    default_llm_provider: Literal["openai", "anthropic"] = "openai"
    default_model: str = "gpt-4-turbo-preview"
    llm_temperature: float = 0.1
    llm_max_tokens: int = 4096

    # Data Processing
    small_data_threshold_mb: int = 1024  # Use Pandas for data < 1GB
    default_engine: Literal["pandas", "polars", "auto"] = "auto"
    max_workers: int = 4
    chunk_size: int = 10000

    # Pipeline Execution
    max_execution_time_seconds: int = 3600  # 1 hour
    enable_parallel_execution: bool = True
    enable_auto_recovery: bool = True
    max_retry_attempts: int = 3

    # Logging
    log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = "INFO"
    log_format: Literal["json", "text"] = "json"
    log_file: str = "logs/datashaper.log"

    # Security
    secret_key: str = Field(
        default="change-me-in-production-use-secrets-manager",
        description="Secret key for JWT and encryption",
    )
    allowed_file_extensions: set[str] = Field(
        default_factory=lambda: {".csv", ".xlsx", ".xls", ".json", ".parquet", ".feather"}
    )

    @computed_field  # type: ignore[misc]
    @property
    def database_url(self) -> str:
        """Get the active database URL."""
        if self.use_duckdb:
            return f"duckdb:///{self.duckdb_path}"
        return f"sqlite:///{self.sqlite_path}"

    def create_directories(self) -> None:
        """Create necessary directories if they don't exist."""
        for directory in [
            self.upload_dir,
            self.processed_dir,
            self.export_dir,
            self.temp_dir,
            Path("logs"),
            Path("data"),
        ]:
            directory.mkdir(parents=True, exist_ok=True)


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


# Global settings instance
settings = get_settings()
