from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic import Field, model_validator
from functools import lru_cache


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

    # App
    app_name: str = "TimeMaster"
    app_env: str = "development"
    secret_key: str = "change-me-in-production"

    # Separater Schlüssel für Fernet-Datenverschlüsselung (CalDAV/LDAP/SMTP-Passwörter, TOTP-Secrets).
    # Empfohlen: in .env als SECRET_KEY_DATA=<zufälliger-string-32+-zeichen> setzen.
    # Wenn nicht gesetzt, wird SECRET_KEY als Fallback verwendet (Warnung beim Start).
    # WICHTIG: Nach erstem Setzen NICHT mehr ändern – alle verschlüsselten DB-Werte werden unlesbar!
    secret_key_data: str | None = Field(None, validation_alias="SECRET_KEY_DATA")
    frontend_url: str = "http://localhost:5173"
    allowed_hosts: list[str] = []

    # Database
    database_url: str = "postgresql+asyncpg://timemaster:secret@localhost:5432/timemaster_db"

    # Redis
    redis_url: str = "redis://localhost:6379/0"

    # Scheduler (Erinnerungs-Mails, agent-11 PR3)
    scheduler_enabled: bool = True
    reminder_hour: int = 7              # Server-Stunde für tägliche Erinnerungen
    carryover_reminder_days: int = 14   # Vorlauf für Resturlaub-Verfall-Erinnerung

    # JWT
    access_token_expire_minutes: int = 30
    refresh_token_expire_days: int = 30
    algorithm: str = "HS256"

    # Email
    resend_api_key: str = ""
    email_from: str = "noreply@timemaster.app"
    email_from_name: str = "TimeMaster"

    # First superadmin
    first_superadmin_email: str = ""
    first_superadmin_password: str = ""

    # CalDAV / outbound HTTP
    # Kommaseparierte CIDR-Whitelist für interne CalDAV-Server (z.B. Nextcloud im LAN).
    # Diese CIDRs sind vom SSRF-Schutz ausgenommen.
    # Beispiel: CALDAV_ALLOWED_CIDRS=192.168.1.0/24,10.10.5.50/32
    caldav_allowed_cidrs: list[str] = []

    @model_validator(mode='after')
    def validate_secret_key(self):
        if self.app_env == 'production' and self.secret_key == 'change-me-in-production':
            raise ValueError('SECRET_KEY must be changed in production! Set SECRET_KEY env variable.')
        if len(self.secret_key) < 32:
            raise ValueError('SECRET_KEY must be at least 32 characters long.')
        return self

    @property
    def is_production(self) -> bool:
        return self.app_env == "production"


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


settings = get_settings()
