from functools import lru_cache
from pydantic import field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict

NEXAPG_VERSION = "0.2.2"


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

    app_name: str = "NexaPG Monitor"
    environment: str = "dev"
    api_v1_prefix: str = "/api/v1"
    log_level: str = "INFO"

    db_host: str = "db"
    db_port: int = 5432
    db_name: str = "nexapg"
    db_user: str = "nexapg"
    db_password: str = "nexapg"

    jwt_secret_key: str
    jwt_algorithm: str = "HS256"
    jwt_access_token_minutes: int = 15
    jwt_refresh_token_minutes: int = 60 * 24 * 7

    encryption_key: str
    cors_origins: str = "http://localhost:5173"
    poll_interval_seconds: int = 30
    alert_active_connection_ratio_min_total_connections: int = 5
    alert_rollback_ratio_window_minutes: int = 15
    alert_rollback_ratio_min_total_transactions: int = 100
    alert_rollback_ratio_min_rollbacks: int = 10
    init_admin_email: str = "admin@example.com"
    init_admin_password: str = "ChangeMe123!"

    @property
    def app_version(self) -> str:
        return NEXAPG_VERSION

    @property
    def database_url(self) -> str:
        return (
            f"postgresql+asyncpg://{self.db_user}:{self.db_password}"
            f"@{self.db_host}:{self.db_port}/{self.db_name}"
        )

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

    @field_validator("environment")
    @classmethod
    def validate_environment(cls, value: str) -> str:
        allowed = {"dev", "staging", "prod", "test"}
        if value not in allowed:
            raise ValueError(f"environment must be one of {allowed}")
        return value


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