"""Application configuration loaded from environment variables."""
from functools import lru_cache

from pydantic import field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_file=".env", extra="ignore")

    # App
    APP_ENV: str = "development"
    LOG_LEVEL: str = "INFO"

    # Database
    DATABASE_URL: str = "postgresql+asyncpg://sprintquiz:changeme@db:5432/sprintquiz"
    POSTGRES_USER: str = "sprintquiz"
    POSTGRES_PASSWORD: str = "changeme"
    POSTGRES_DB: str = "sprintquiz"
    POSTGRES_HOST: str = "db"
    POSTGRES_PORT: int = 5432

    # Redis / Celery
    REDIS_URL: str = "redis://redis:6379/0"
    CELERY_BROKER_URL: str = "redis://redis:6379/0"
    CELERY_RESULT_BACKEND: str = "redis://redis:6379/1"

    # Entra ID OIDC
    ENTRA_TENANT_ID: str = ""
    ENTRA_CLIENT_ID: str = ""
    ENTRA_CLIENT_SECRET: str = ""
    ENTRA_REDIRECT_URI: str = "http://localhost:8000/api/v1/auth/callback"
    ENTRA_ISSUER: str = ""

    # JWT
    JWT_SECRET: str = "changeme"
    JWT_ALGORITHM: str = "HS256"
    JWT_EXPIRE_MINUTES: int = 1440
    SESSION_COOKIE_NAME: str = "sprintquiz_session"
    SESSION_COOKIE_SECURE: bool = False

    # AI
    AI_API_BASE: str = "https://api.openai.com/v1"
    AI_API_KEY: str = "changeme"
    AI_MODEL: str = "gpt-4o-mini"

    # File storage
    UPLOAD_DIR: str = "/app/uploads"
    MAX_UPLOAD_MB: int = 25

    # CORS
    CORS_ORIGINS: str = "http://localhost:8080"

    @field_validator("CORS_ORIGINS")
    @classmethod
    def _split_origins(cls, v: str) -> str:
        return v  # keep as string; use cors_origins_list property

    @property
    def cors_origins_list(self) -> list[str]:
        return [o.strip() for o in self.CORS_ORIGINS.split(",") if o.strip()]

    @property
    def entra_authority(self) -> str:
        return f"https://login.microsoftonline.com/{self.ENTRA_TENANT_ID}"

    @property
    def entra_oidc_discovery(self) -> str:
        return (
            f"https://login.microsoftonline.com/{self.ENTRA_TENANT_ID}"
            "/v2.0/.well-known/openid-configuration"
        )

    @property
    def entra_auth_url(self) -> str:
        return f"{self.entra_authority}/oauth2/v2.0/authorize"

    @property
    def entra_token_url(self) -> str:
        return f"{self.entra_authority}/oauth2/v2.0/token"


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


settings = get_settings()
