"""
Configurazione applicazione – legge variabili d'ambiente tramite pydantic-settings.
"""

from functools import lru_cache
from typing import Literal

from pydantic import field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict


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

    # ── Applicazione ──────────────────────────────────────────────────────────
    app_env: Literal["development", "staging", "production"] = "development"
    app_debug: bool = True
    app_host: str = "0.0.0.0"
    app_port: int = 8000
    app_base_url: str = "http://localhost:8000"

    # ── Sicurezza / JWT ───────────────────────────────────────────────────────
    secret_key: str = "change-me-in-production"
    algorithm: str = "HS256"
    access_token_expire_minutes: int = 15
    refresh_token_expire_days: int = 30

    # Chiave AES-256-GCM per cifratura credenziali IMAP/SMTP (hex 64 chars = 32 bytes)
    encryption_key: str = "0" * 64

    # ── Database ──────────────────────────────────────────────────────────────
    database_url: str = "postgresql+asyncpg://pecflow:pecflow_dev_password@db:5432/pecflow"
    database_url_sync: str = "postgresql://pecflow:pecflow_dev_password@db:5432/pecflow"

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

    # ── MinIO ─────────────────────────────────────────────────────────────────
    minio_endpoint: str = "minio:9000"
    minio_access_key: str = "minioadmin"
    minio_secret_key: str = "minioadmin"
    minio_bucket: str = "pecflow"
    minio_use_ssl: bool = False

    # ── CORS ──────────────────────────────────────────────────────────────────
    cors_origins: str = "http://localhost:3000,http://localhost:5173"

    # ── Rate Limiting ─────────────────────────────────────────────────────────
    rate_limit_auth: str = "10/minute"
    rate_limit_default: str = "100/minute"

    # ── Logging ───────────────────────────────────────────────────────────────
    log_level: str = "INFO"
    log_json: bool = False

    @field_validator("encryption_key")
    @classmethod
    def validate_encryption_key(cls, v: str) -> str:
        if len(v) != 64:
            raise ValueError(
                "ENCRYPTION_KEY deve essere una stringa hex di 64 caratteri (32 bytes)"
            )
        try:
            bytes.fromhex(v)
        except ValueError:
            raise ValueError("ENCRYPTION_KEY deve essere una stringa esadecimale valida")
        return v

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

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

    @property
    def encryption_key_bytes(self) -> bytes:
        return bytes.fromhex(self.encryption_key)


@lru_cache
def get_settings() -> Settings:
    """Restituisce istanza singleton delle impostazioni (cachata)."""
    return Settings()
