from pydantic_settings import BaseSettings
from pydantic import field_validator
from typing import Optional


_DEFAULT_SECRET_KEY = "your-secret-key-change-in-production-use-openssl-rand-hex-32"


class Settings(BaseSettings):
    # Application
    APP_NAME: str = "ResolutionFlow"
    DEBUG: bool = False
    API_V1_PREFIX: str = "/api/v1"

    # Database - Railway provides DATABASE_URL, we convert it for asyncpg
    DATABASE_URL: str = "postgresql+asyncpg://postgres:postgres@localhost:5432/patherly"

    @field_validator("DATABASE_URL", mode="before")
    @classmethod
    def convert_database_url(cls, v: str) -> str:
        """Convert standard postgres URL to asyncpg format."""
        if v.startswith("postgresql://"):
            return v.replace("postgresql://", "postgresql+asyncpg://", 1)
        return v

    @property
    def DATABASE_URL_SYNC(self) -> str:
        """Get sync URL by removing asyncpg prefix from DATABASE_URL."""
        return self.DATABASE_URL.replace("postgresql+asyncpg://", "postgresql://", 1)

    # JWT Settings
    SECRET_KEY: str = _DEFAULT_SECRET_KEY

    @field_validator("SECRET_KEY", mode="after")
    @classmethod
    def reject_default_secret_in_production(cls, v: str, info) -> str:
        """Fail loudly if the default secret key is used outside of DEBUG mode."""
        debug = info.data.get("DEBUG", False)
        if v == _DEFAULT_SECRET_KEY and not debug:
            raise ValueError(
                "SECRET_KEY must be set to a secure value in production. "
                "Generate one with: openssl rand -hex 32"
            )
        return v
    ALGORITHM: str = "HS256"
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 5
    REFRESH_TOKEN_EXPIRE_DAYS: int = 7

    # Security
    BCRYPT_ROUNDS: int = 12

    # Registration
    REQUIRE_INVITE_CODE: bool = True  # Set to False to allow open registration

    # Email (Resend)
    RESEND_API_KEY: Optional[str] = None
    FROM_EMAIL: str = "ResolutionFlow <invites@resolutionflow.com>"
    FEEDBACK_EMAIL: Optional[str] = None

    @property
    def email_enabled(self) -> bool:
        """Check if email sending is configured."""
        return self.RESEND_API_KEY is not None

    # Stripe
    STRIPE_SECRET_KEY: Optional[str] = None
    STRIPE_PUBLISHABLE_KEY: Optional[str] = None
    STRIPE_WEBHOOK_SECRET: Optional[str] = None

    @property
    def stripe_enabled(self) -> bool:
        """Check if Stripe is configured."""
        return self.STRIPE_SECRET_KEY is not None and self.STRIPE_WEBHOOK_SECRET is not None

    # AI Flow Builder
    ANTHROPIC_API_KEY: Optional[str] = None
    AI_MODEL: str = "claude-haiku-4-5-20251001"
    AI_CONVERSATION_TTL_HOURS: int = 24
    AI_MAX_CALLS_PER_FLOW: int = 10
    AI_REQUEST_TIMEOUT_SECONDS: int = 45
    # AI Provider selection
    AI_PROVIDER: str = "gemini"  # "gemini" or "anthropic"
    GOOGLE_AI_API_KEY: Optional[str] = None
    AI_MODEL_GEMINI: str = "gemini-2.5-flash"
    AI_MODEL_ANTHROPIC: str = "claude-haiku-4-5-20251001"

    # Embedding / RAG
    VOYAGE_API_KEY: Optional[str] = None
    EMBEDDING_MODEL: str = "voyage-3.5"
    EMBEDDING_DIMENSIONS: int = 1024

    @property
    def ai_enabled(self) -> bool:
        """Check if any AI provider is configured."""
        return self.ANTHROPIC_API_KEY is not None or self.GOOGLE_AI_API_KEY is not None

    # Deployment – auto-seed test data on PR environments
    SEED_ON_DEPLOY: bool = False

    # CORS - set FRONTEND_URL in production (e.g., https://patherly.up.railway.app)
    CORS_ORIGINS: list[str] = ["http://localhost:3000", "http://localhost:5173", "http://localhost:5174"]
    FRONTEND_URL: Optional[str] = None
    # Allow all Railway PR environments (set to True in Railway env vars)
    ALLOW_RAILWAY_ORIGINS: bool = False

    @property
    def allowed_origins(self) -> list[str]:
        """Get all allowed CORS origins including FRONTEND_URL if set."""
        origins = self.CORS_ORIGINS.copy()
        if self.FRONTEND_URL and self.FRONTEND_URL not in origins:
            origins.append(self.FRONTEND_URL)
        return origins

    def is_origin_allowed(self, origin: str) -> bool:
        """Check if an origin is allowed, including Railway wildcard pattern."""
        if origin in self.allowed_origins:
            return True
        # Allow any *.up.railway.app origin for PR environments
        if self.ALLOW_RAILWAY_ORIGINS and origin.endswith(".up.railway.app"):
            return True
        return False

    class Config:
        env_file = ".env"
        case_sensitive = True
        extra = "ignore"  # Ignore extra env vars like DATABASE_URL_SYNC


settings = Settings()
