from __future__ import annotations

import json
import secrets
from functools import lru_cache
from typing import Any

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


class Settings(BaseSettings):
    """Application configuration loaded from environment variables.

    Environment variables are prefixed with `WHA_` by default.
    """

    model_config = SettingsConfigDict(env_prefix="WHA_", case_sensitive=False)

    cors_origins: list[str] = Field(
        default_factory=lambda: ["http://localhost:3000"],
        description="Allowed CORS origins.",
    )
    rate_limit_requests: int = Field(
        default=60,
        ge=1,
        description="Max requests per window for rate limiting.",
    )
    rate_limit_window_seconds: int = Field(
        default=60,
        ge=1,
        description="Rate limit window in seconds.",
    )
    captcha_secret: str = Field(
        default_factory=lambda: secrets.token_urlsafe(32),
        description="Secret used to sign CAPTCHA bypass tokens.",
    )
    captcha_challenge_ttl_seconds: int = Field(
        default=300,
        ge=60,
        description="Seconds until CAPTCHA challenges expire.",
    )
    captcha_bypass_ttl_seconds: int = Field(
        default=300,
        ge=60,
        description="Seconds until CAPTCHA bypass tokens expire.",
    )
    analysis_timeout_seconds: int = Field(
        default=30,
        ge=1,
        description="Hard timeout for analysis in seconds.",
    )
    debug: bool = Field(default=False, description="Enable debug mode.")

    @field_validator("cors_origins", mode="before")
    @classmethod
    def parse_cors_origins(cls, value: Any) -> list[str]:
        if value is None:
            return ["http://localhost:3000"]
        if isinstance(value, list):
            return [str(item).strip() for item in value if str(item).strip()]
        if isinstance(value, str):
            text = value.strip()
            if not text:
                return []
            if text.startswith("["):
                try:
                    parsed = json.loads(text)
                    if isinstance(parsed, list):
                        return [
                            str(item).strip() for item in parsed if str(item).strip()
                        ]
                except json.JSONDecodeError:
                    pass
            return [item.strip() for item in text.split(",") if item.strip()]
        return [str(value).strip()]


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