"""Backend configuration. Loaded from env vars (.env) with safe dev defaults.

Override any setting at launch time, e.g.:
    DATABASE_URL=postgresql://... uvicorn backend.main:app

Production checklist (ENFORCED at startup when APP_ENV=production):
  * JWT_SECRET    — must NOT be the dev default
  * CORS_ORIGINS  — must NOT contain localhost

WARNING: forecast_engine.py hardcodes its own thresholds and does NOT read from
constants.py or this config. If you need to change forecast guardrails, edit
forecast_engine.py directly. See VERIFICATION_INVENTORY.md section 3 for the full list.
"""
from __future__ import annotations

import sys

from pydantic_settings import BaseSettings, SettingsConfigDict

DEV_JWT_SECRET = "dev-secret-change-in-production"


class Settings(BaseSettings):
    APP_ENV: str = "development"   # "production" enables strict checks
    DATABASE_URL: str = (
        "postgresql://polleo:polleo_dev@localhost:5432/polleo_demand"
    )
    API_PREFIX: str = "/api"
    # Comma-separated in env: CORS_ORIGINS=https://demand.polleo.intra,http://...
    CORS_ORIGINS: list[str] = [
        "http://localhost:3000",
        "http://localhost:5173",
    ]
    JWT_SECRET: str = DEV_JWT_SECRET
    JWT_ALGORITHM: str = "HS256"
    JWT_EXPIRE_HOURS: int = 168    # 7 days for internal-app convenience

    # Machine-to-machine key for automated ERP ingestion (n8n / worker posting
    # to the /upload-* endpoints). Empty = no machine access (browser-session
    # uploads still work). Set a long random value in prod:
    #   python -c "import secrets; print(secrets.token_urlsafe(48))"
    INGEST_API_KEY: str = ""

    # Polleo AI (conversational analytics). The backend calls the Anthropic API
    # server-side with this key — end users never need their own. Empty = the
    # feature is disabled: /api/polleo-ai/health reports "not_configured" and
    # /api/polleo-ai/chat returns 503. This is intentionally NOT gated by
    # APP_ENV (it's an optional add-on). Model is overridable for cost tuning.
    ANTHROPIC_API_KEY: str = ""
    ANTHROPIC_MODEL: str = "claude-sonnet-4-6"
    # Dedicated connection for Polleo AI's Claude-generated SQL. Point this at a
    # least-privilege, SELECT-only Postgres role (see db/migrations/
    # polleo_ai_readonly_role.sql) so a query can't write even if it slipped
    # past the app-level guards. Empty = fall back to the main DATABASE_URL
    # (still wrapped in a read-only transaction + timeout, but not enforced at
    # the DB privilege level).
    POLLEO_AI_DATABASE_URL: str = ""

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


settings = Settings()


def _validate_production() -> None:
    """Fail-fast on misconfiguration when APP_ENV=production."""
    if settings.APP_ENV.lower() != "production":
        return
    errors: list[str] = []
    if settings.JWT_SECRET == DEV_JWT_SECRET:
        errors.append(
            "JWT_SECRET is still the dev default. Generate a real one:\n"
            "    python -c 'import secrets; print(secrets.token_urlsafe(64))'\n"
            "Then set JWT_SECRET=... in your environment / .env file."
        )
    if not settings.JWT_SECRET or len(settings.JWT_SECRET) < 32:
        errors.append("JWT_SECRET must be at least 32 chars.")
    if any(o.startswith("http://localhost") for o in settings.CORS_ORIGINS):
        errors.append(
            "CORS_ORIGINS contains a localhost entry. Set CORS_ORIGINS to the "
            "real frontend origin(s), comma-separated."
        )
    if errors:
        print("\n========= STARTUP BLOCKED: production misconfiguration =========",
              file=sys.stderr)
        for e in errors:
            print(f"  ❌ {e}", file=sys.stderr)
        print("================================================================\n",
              file=sys.stderr)
        sys.exit(1)


_validate_production()
