# ---- Matrix Connection ----
# GogoBee authenticates via the MAS (Matrix Authentication Service) OAuth 2.0
# device grant. No password/token goes here: on first run the bot prints a URL
# + code to approve ONCE in a browser (logged in as BOT_USER_ID), then stores a
# refresh token in DATA_DIR/mas_auth.json and refreshes silently thereafter.
# To force re-authorization, delete data/mas_auth.json.
HOMESERVER_URL=https://matrix.example.com
BOT_USER_ID=@gogobee:example.com
BOT_DISPLAY_NAME=GogoBee

# ---- Auth mode ----
# masdevice (default) — MAS OAuth 2.0 device grant over /sync (above).
# appservice          — Matrix appservice: the registration's as_token is the
#                       credential (no login/MFA/expiry, MAS-durable). The bot
#                       runs an HTTP listener and receives events over Synapse's
#                       transaction push instead of /sync (Synapse forbids AS
#                       users from /sync). E2EE rides MSC3202/MSC2409 + MSC4190.
AUTH_MODE=masdevice
# The following are required only when AUTH_MODE=appservice:
AS_REGISTRATION=            # path to the appservice registration YAML (as_token/hs_token/namespaces)
AS_LISTEN_HOST=             # bind address for the transaction listener (e.g. 0.0.0.0 or a tailnet IP)
AS_LISTEN_PORT=             # bind port; Synapse's registration url must reach host:port
HOMESERVER_DOMAIN=          # server_name, e.g. example.com (derives the bot MXID from sender_localpart)

# ---- Cross-signing (optional; both auth modes) ----
# Controls only whether the bot shows as VERIFIED in clients — E2EE works without it.
# Normally you set NEITHER of these. On its first start the bot mints a cross-signing
# identity and persists the recovery key itself to DATA_DIR/cross_signing.json (0600);
# every later start reuses that identity untouched, so users verify the bot once, ever.
#
# Set to 1 for exactly ONE start to throw away the published identity and mint a fresh
# one (the bot stores the new key itself). Every user must then verify the bot again.
# Needed only if the identity was lost, or to adopt one the bot can't re-sign.
CROSS_SIGNING_REGENERATE=
#
# Imports an existing recovery key into DATA_DIR/cross_signing.json on next start.
# Only useful to adopt an identity created before the bot persisted its own key.
CROSS_SIGNING_RECOVERY_KEY=

# Which rooms the bot posts scheduled content to (comma-separated room IDs)
BROADCAST_ROOMS=!roomid:example.com

# The daily 08:00 WOTD auto-post is disabled by default.
# Set to true to enable it. The !wotd command and passive WOTD
# usage tracking work regardless of this setting.
ENABLE_WOTD_POST=false

# Admins who can run admin-only commands (comma-separated Matrix user IDs)
ADMIN_USERS=@yourmxid:example.com

# ---- Runtime ----
DATA_DIR=./data
LOG_LEVEL=info

# ---- External API Keys (all optional) ----
RAWG_API_KEY=
DREAMDICT_URL=http://127.0.0.1:7777
CALENDARIFIC_API_KEY=
HOLIDAY_COUNTRIES=US,GB,CA,AU,PT,IN,JP,DE,FR,BR,MX,IT,ES,KR,NL,SE,NO,IE,NZ,ZA,PH
OPENWEATHER_API_KEY=
FINNHUB_API_KEY=
BANDSINTOWN_API_KEY=
TMDB_API_KEY=
SERPAPI_KEY=              # SerpAPI key for image fetching (esteemed members)

# ---- Self-Hosted Services (optional) ----
LIBRETRANSLATE_URL=
OLLAMA_HOST=
OLLAMA_MODEL=
LLM_SAMPLE_RATE=0.15  # 0.0-1.0, fraction of non-keyword messages to classify (1.0 = all)

# ---- Feature Flags ----
FEATURE_URL_PREVIEW=
FEATURE_SHADE=
FEATURE_TRIVIA=true  # set to "false" to disable trivia
FEATURE_ESTEEMED=    # set to anything to enable satirical esteemed member posts
ESTEEMED_ROOM=       # room ID for esteemed member posts (separate from broadcast rooms)

# ---- Games & Economy ----
GAMES_ROOM=                    # room ID where game commands work (trivia, hangman, blackjack, holdem, wordle, flip)
EURO_COOLDOWN_SECONDS=30       # cooldown between passive euro earning
EURO_DEBT_REMINDER=true        # weekly DM reminder if in debt
EURO_STARTING_CAP=2500         # max starting balance from corpus
HANGMAN_MAX_WRONG_GUESSES=6
HANGMAN_SOLUTION_BONUS_MULTIPLIER=2
HANGMAN_PHRASE_FILE=           # path to newline-delimited phrase file
BLACKJACK_TIMEOUT_SECONDS=60   # auto-play timeout per player turn
BLACKJACK_AUTOPLAY_THRESHOLD=15
BLACKJACK_MIN_BET=1
BLACKJACK_MAX_BET=500
BLACKJACK_DEBT_LIMIT=1000      # max debt before betting disabled
UNO_MIN_BET=10                 # minimum wager in euros (solo)
UNO_POT_TAUNT_THRESHOLD=500   # pot size at which GogoBee starts taunting
UNO_MULTI_MIN_BET=25           # minimum ante for multiplayer UNO
UNO_MULTI_MAX_BET=500          # maximum ante for multiplayer UNO
UNO_MULTI_LOBBY_TIMEOUT=300    # lobby expiry in seconds (default 300 = 5min)
UNO_MULTI_TURN_TIMEOUT=30      # auto-play timeout in seconds (default 30)
UNO_MULTI_MAX_AUTOPLAY=3       # consecutive auto-plays before forfeit

# Texas Hold'em
HOLDEM_SMALL_BLIND=10          # small blind amount
HOLDEM_BIG_BLIND=20            # big blind amount
HOLDEM_MIN_BUYIN=200           # minimum balance to join
HOLDEM_MAX_BUYIN=2000          # maximum stack at buy-in
HOLDEM_TIMEOUT_SECONDS=90      # action timeout per turn
HOLDEM_NPC_NAME=TwinBee        # NPC bot display name
HOLDEM_NPC_HOUSE_BALANCE=10000 # NPC starting bankroll
HOLDEM_CFR_POLICY=data/policy.gob  # path to CFR policy file

# Wordle
WORDLE_DEFAULT_LENGTH=5        # default word length (5, 6, or 7)

# ---- Space Groups (automatic room grouping for community-wide leaderboards) ----
SPACE_GROUP_THRESHOLD=50       # % of smaller room's members that must overlap (1-100, default 50)

# ---- Missing Members (!haveyouseenthem / !missing) ----
MISSING_THRESHOLD_DAYS=14     # days of inactivity before considered missing
MISSING_MAX_DAYS=90           # days after which they're considered gone, not missing
MISSING_MIN_MESSAGES=10       # minimum lifetime messages to be eligible
MISSING_EXCLUDE_USERS=        # comma-separated user IDs to never list as missing

# ---- Encryption ----
QUOTE_ENCRYPTION_KEY=         # Base64-encoded 32-byte AES-256 key (required for !quote)

# ---- Moderation (disabled by default) ----
FEATURE_MODERATION=            # set to "true" to enable the moderation system
MOD_WORDLIST=                  # path to newline-delimited word list file
MOD_WORDLIST_VARIATIONS=true   # check leetspeak/spaced variants
MOD_STRIKE_EXPIRY_DAYS=30      # strikes expire after N days
MOD_MUTE_DURATION_MINUTES=60   # temp mute duration on strike 2
MOD_MAX_STRIKES=3              # strikes before permanent ban
MOD_FLOOD_MESSAGE_COUNT=5      # messages within window = flood
MOD_FLOOD_MESSAGE_WINDOW_SECONDS=10
MOD_FLOOD_IMAGE_COUNT=3        # images/files within window = flood
MOD_FLOOD_IMAGE_WINDOW_SECONDS=30
MOD_MAX_MESSAGE_LENGTH=2000    # max chars per message (0 = disabled)
MOD_REPEAT_COUNT=3             # same message N times = strike
MOD_REPEAT_WINDOW_SECONDS=60
MOD_REPEAT_SIMILARITY_THRESHOLD=0.85
MOD_MENTION_MAX=5              # max unique @mentions per message
MOD_MENTION_FLOOD_COUNT=3
MOD_MENTION_FLOOD_WINDOW_SECONDS=30
MOD_LINK_RATE_NEW_MEMBER=3     # max links per window (new members only)
MOD_LINK_RATE_WINDOW_SECONDS=60
MOD_INVITE_MAX_PER_HOUR=5
MOD_JOIN_LEAVE_COUNT=3         # join/leave cycles = flag (no auto-strike)
MOD_JOIN_LEAVE_WINDOW_MINUTES=10
MOD_NEW_MEMBER_DAYS=14         # accounts newer than N days = stricter thresholds
MOD_NEW_MEMBER_FLOOD_MULTIPLIER=0.5
MOD_ADMIN_ROOM=                # dedicated admin room for mod notifications
MOD_DM_ON_ACTION=true          # DM users when action is taken

# ---- Miniflux RSS ----
MINIFLUX_URL=                  # Miniflux instance URL (e.g. https://rss.example.com)
MINIFLUX_API_KEY=              # Miniflux API key
MINIFLUX_POLL_INTERVAL=15      # minutes between polls (default 15)
MINIFLUX_DEFAULT_ROOM=         # default room for feed posts (falls back to BROADCAST_ROOMS)
MINIFLUX_MAX_PER_POLL=5        # max entries per feed per poll (default 5)

# ---- Rate Limits (per user per day) ----
RATELIMIT_WEATHER=5
RATELIMIT_TRANSLATE=20
RATELIMIT_CONCERTS=10

# ---- Email Nag (one-shot migration helper: collect+verify missing Authentik emails over Matrix DM) ----
FEATURE_EMAIL_NAG=             # set to "true" to enable
EMAIL_NAG_AUTHENTIK_URL=       # e.g. https://authentik.parodia.dev
EMAIL_NAG_AUTHENTIK_TOKEN=     # Authentik service-account token, scoped to user write
EMAIL_NAG_RESEND_KEY=          # Resend API key (sends the verification code)
EMAIL_NAG_MAIL_FROM=           # e.g. Parodia <noreply@mail.parodia.dev>
EMAIL_NAG_HOME_DOMAIN=         # Matrix server name, e.g. parodia.dev (builds @user:domain)
EMAIL_NAG_TARGETS=             # comma-separated Authentik usernames to nag (== Matrix localparts)
EMAIL_NAG_CODE_TTL=30m         # verification code lifetime (default 30m)
EMAIL_NAG_MAX_ATTEMPTS=5       # wrong-code attempts before restart (default 5)
EMAIL_NAG_MAX_SENDS_PER_HOUR=5 # cap on verification emails per user per rolling hour (anti-spam, default 5)
EMAIL_NAG_SWEEP_DELAY=2s       # delay between DMs during the startup sweep (default 2s)
EMAIL_NAG_REPROMPT_COOLDOWN=   # re-nag non-responders whose last prompt is older than this (e.g. 72h); empty/0 = nag once
