"""
Config file cho CuCu Note backend
Lấy giá trị từ file .env qua os.getenv
"""

import os

from dotenv import load_dotenv

# Base dir of backend (this file)
BASE_DIR = os.path.dirname(__file__)

# 1) Load environment variables from `.env` in backend folder (ổn định, không phụ thuộc cwd)
BACKEND_DOTENV_PATH = os.path.join(BASE_DIR, ".env")
load_dotenv(dotenv_path=BACKEND_DOTENV_PATH, override=False)

# 1b) Also load project-root `.env` (nếu bạn đặt key ở root giống hình)
ROOT_DOTENV_PATH = os.path.join(BASE_DIR, "..", ".env")
load_dotenv(dotenv_path=ROOT_DOTENV_PATH, override=False)


# 2) Fallback: cũng load env từ file `env.txt` (KEY=VALUE per line) trong thư mục backend
ENV_TXT_PATH = os.path.join(BASE_DIR, "env.txt")


def _load_env_from_env_txt() -> None:
    """
    Đọc thêm biến môi trường từ `env.txt` nếu tồn tại.

    - Format: mỗi dòng `KEY=VALUE`
    - Bỏ qua dòng trống / comment
    - Chỉ set nếu biến đó CHƯA có trong os.environ
    """
    if not os.path.exists(ENV_TXT_PATH):
        return

    try:
        with open(ENV_TXT_PATH, encoding="utf-8") as f:
            for raw_line in f:
                line = raw_line.strip()
                if not line or line.startswith("#"):
                    continue
                if "=" not in line:
                    continue
                key, value = line.split("=", 1)
                key = key.strip()
                value = value.strip()
                if key and key not in os.environ:
                    os.environ[key] = value
    except Exception:
        # Không fail startup chỉ vì file dev-env phụ; dùng như fallback local thôi.
        pass


# Gọi ngay sau khi load_dotenv để các os.getenv phía dưới đều nhìn thấy
_load_env_from_env_txt()

# Export all config variables for type checking
__all__ = [
    "AI_MODEL_NAME",
    "AI_SUPABASE_KEY",
    "AI_SUPABASE_URL",
    "CHECKPOINT_POSTGRES_SCHEMA",
    "CHECKPOINT_POSTGRES_URL",
    "CLERK_SECRET_KEY",
    "CLERK_JWKS_URL",
    "CLERK_ISSUER",
    "CONV_DATABASE_URL",
    "CONV_SUPABASE_KEY",
    "CONV_SUPABASE_URL",
    "DEFAULT_MODEL",
    "FIRECRAWL_API_KEY",
    "GOOGLE_API_KEY",
    "GROQ_API_KEY",
    "JWT_ALGORITHM",
    "JWT_SECRET",
    "LANGFUSE_BASE_URL",
    "LANGFUSE_PUBLIC_KEY",
    "LANGFUSE_SECRET_KEY",
    "LANGSMITH_API_KEY",
    "LANGSMITH_ENDPOINT",
    "LANGSMITH_PROJECT",
    "LANGSMITH_TRACING",
    "MONGODB_DB_NAME",
    "MONGODB_URI",
    "OPENAI_API_KEY",
    "OTEL_EXPORTER_JAEGER_AGENT_HOST",
    "OTEL_EXPORTER_JAEGER_AGENT_PORT",
    "OTEL_EXPORTER_JAEGER_AGENT_SPLIT_OVERSIZED_BATCHES",
    "OTEL_SERVICE_NAME",
    "OTEL_TRACES_EXPORTER",
    "PORT",
    "REDIS_HOST",
    "REDIS_PASSWORD",
    "REDIS_PORT",
    "REDIS_USERNAME",
    "STARROCKS_DB",
    "STARROCKS_HOST",
    "STARROCKS_PASSWORD",
    "STARROCKS_PORT",
    "STARROCKS_USER",
    "USE_MONGO_CONVERSATION",
    "RATE_LIMIT_GUEST",
    "RATE_LIMIT_USER",
    "USE_SQLITE_HISTORY",
    "SQLITE_DB_PATH",
    "DISABLE_AUTH",
    "MEMO_DB_PATH",
    "MONGODB_MAX_POOL_SIZE",
    "MONGODB_MIN_POOL_SIZE",
    "MONGODB_MAX_IDLE_TIME_MS",
    "CORS_ORIGINS",
    "RATE_STORAGE_URI",
    "RATE_LIMIT_REDIS_DB",
    "RATE_LIMIT_BLOCK_MINUTES",
    "ENCRYPTION_KEY",
    "ENCRYPTION_PASSWORD",
    "MEILI_URL",
    "MEILI_MASTER_KEY",
]

# ====================== SUPABASE CONFIGURATION ======================
AI_SUPABASE_URL: str | None = os.getenv("AI_SUPABASE_URL")
AI_SUPABASE_KEY: str | None = os.getenv("AI_SUPABASE_KEY")
CONV_SUPABASE_URL: str | None = os.getenv("CONV_SUPABASE_URL")
CONV_SUPABASE_KEY: str | None = os.getenv("CONV_SUPABASE_KEY")

# ====================== REDIS CONFIGURATION ======================
REDIS_HOST: str | None = os.getenv("REDIS_HOST")
REDIS_PORT: int = int(os.getenv("REDIS_PORT", "6379"))

# ====================== AI API KEYS & MODELS ======================
OPENAI_API_KEY: str | None = os.getenv("OPENAI_API_KEY")
GOOGLE_API_KEY: str | None = os.getenv("GOOGLE_API_KEY")
GROQ_API_KEY: str | None = os.getenv("GROQ_API_KEY")

DEFAULT_MODEL: str = os.getenv("DEFAULT_MODEL", "gpt-4o-mini")
AI_MODEL_NAME = DEFAULT_MODEL

# ====================== JWT CONFIGURATION ======================
JWT_SECRET: str | None = os.getenv("JWT_SECRET")
JWT_ALGORITHM: str | None = os.getenv("JWT_ALGORITHM")

# ====================== SERVER CONFIG ======================
PORT: int = int(os.getenv("PORT", "5000"))
FIRECRAWL_API_KEY: str | None = os.getenv("FIRECRAWL_API_KEY")

# ====================== LANGFUSE CONFIGURATION (DEPRECATED) ======================
LANGFUSE_SECRET_KEY: str | None = os.getenv("LANGFUSE_SECRET_KEY")
LANGFUSE_PUBLIC_KEY: str | None = os.getenv("LANGFUSE_PUBLIC_KEY")
LANGFUSE_BASE_URL: str | None = os.getenv("LANGFUSE_BASE_URL", "https://cloud.langfuse.com")

# ====================== LANGSMITH CONFIGURATION (TẮT VÌ RATE LIMIT) ======================
# LANGSMITH_TRACING = os.getenv("LANGSMITH_TRACING", "false")
# LANGSMITH_ENDPOINT = os.getenv("LANGSMITH_ENDPOINT", "https://api.smith.langchain.com")
# LANGSMITH_API_KEY = os.getenv("LANGSMITH_API_KEY")
# LANGSMITH_PROJECT = os.getenv("LANGSMITH_PROJECT")
LANGSMITH_TRACING = "false"
LANGSMITH_ENDPOINT = None
LANGSMITH_API_KEY = None
LANGSMITH_PROJECT = None

# ====================== CLERK AUTHENTICATION ======================
CLERK_SECRET_KEY: str | None = os.getenv("CLERK_SECRET_KEY")
# Hardcode Clerk domain để test nhanh (có thể override bằng env)
CLERK_JWKS_URL: str | None = os.getenv("CLERK_JWKS_URL") or "https://communal-sunbeam-0.clerk.accounts.dev/.well-known/jwks.json"
CLERK_ISSUER: str | None = os.getenv("CLERK_ISSUER") or "https://communal-sunbeam-0.clerk.accounts.dev"

# ====================== DATABASE CONNECTION ======================
# Redis Cache Configuration (Redis Cloud Free - 30MB)
REDIS_CACHE_URL: str | None = os.getenv("REDIS_CACHE_URL", "redis-14473.c93.us-east-1-3.ec2.cloud.redislabs.com")
REDIS_CACHE_PORT: int = int(os.getenv("REDIS_CACHE_PORT", "14473"))
REDIS_CACHE_DB: int = int(os.getenv("REDIS_CACHE_DB", "0"))
REDIS_CACHE_TURN_ON: bool = os.getenv("REDIS_CACHE_TURN_ON", "true").lower() == "true"
REDIS_PASSWORD: str | None = os.getenv("REDIS_CACHE_PASSWORD")
REDIS_USERNAME: str = os.getenv("REDIS_CACHE_USERNAME", "default")

CONV_DATABASE_URL: str | None = os.getenv("CONV_DATABASE_URL")

# ====================== MONGO CONFIGURATION ======================
MONGODB_URI: str | None = os.getenv("MONGODB_URI")
MONGODB_DB_NAME: str | None = os.getenv("MONGODB_DB_NAME", "cucu_note")
USE_MONGO_CONVERSATION: bool = os.getenv("USE_MONGO_CONVERSATION", "true").lower() == "true"

# MongoDB Connection Pooling
MONGODB_MAX_POOL_SIZE: int = int(os.getenv("MONGODB_MAX_POOL_SIZE", "5"))
MONGODB_MIN_POOL_SIZE: int = int(os.getenv("MONGODB_MIN_POOL_SIZE", "1"))
MONGODB_MAX_IDLE_TIME_MS: int = int(os.getenv("MONGODB_MAX_IDLE_TIME_MS", "45000"))

# ====================== LEGACY POSTGRES (unused) ======================
CHECKPOINT_POSTGRES_URL: str | None = os.getenv("CHECKPOINT_POSTGRES_URL")
CHECKPOINT_POSTGRES_SCHEMA: str = os.getenv("CHECKPOINT_POSTGRES_SCHEMA", "cucu_chat")

# ====================== STARROCKS DATA LAKE ======================
STARROCKS_HOST: str | None = os.getenv("STARROCKS_HOST")
STARROCKS_PORT: int = int(os.getenv("STARROCKS_PORT", "9030"))
STARROCKS_USER: str | None = os.getenv("STARROCKS_USER")
STARROCKS_PASSWORD: str | None = os.getenv("STARROCKS_PASSWORD")
STARROCKS_DB: str | None = os.getenv("STARROCKS_DB")

# Placeholder for backward compatibility if needed
# ====================== OPENTELEMETRY CONFIGURATION ======================
OTEL_EXPORTER_JAEGER_AGENT_HOST = os.getenv("OTEL_EXPORTER_JAEGER_AGENT_HOST")
OTEL_EXPORTER_JAEGER_AGENT_PORT = os.getenv("OTEL_EXPORTER_JAEGER_AGENT_PORT")
OTEL_SERVICE_NAME = os.getenv("OTEL_SERVICE_NAME")
OTEL_TRACES_EXPORTER = os.getenv("OTEL_TRACES_EXPORTER")
OTEL_EXPORTER_JAEGER_AGENT_SPLIT_OVERSIZED_BATCHES = os.getenv("OTEL_EXPORTER_JAEGER_AGENT_SPLIT_OVERSIZED_BATCHES")

RATE_LIMIT_GUEST: int = int(os.getenv("RATE_LIMIT_GUEST", "10"))
RATE_LIMIT_USER: int = int(os.getenv("RATE_LIMIT_USER", "100"))

# ====================== LOCAL DEV / TESTING TOGGLES ======================
# Turn off auth + rate limit middleware when true (for local testing)
DISABLE_AUTH: bool = os.getenv("DISABLE_AUTH", "false").lower() == "true"
# Use SQLite for chat history instead of Postgres when true
USE_SQLITE_HISTORY: bool = os.getenv("USE_SQLITE_HISTORY", "true").lower() == "true"
SQLITE_DB_PATH: str = os.getenv(
    "SQLITE_DB_PATH",
    os.path.join(os.path.dirname(__file__), "data", "chat_history.db"),
)

# Memo DB for note backend
MEMO_DB_PATH: str = os.getenv(
    "MEMO_DB_PATH",
    os.path.join(os.path.dirname(__file__), "db", "memos.db"),
)

# ====================== CORS CONFIGURATION ======================
# CORS origins - comma-separated list, or "*" for all origins
# Default: "*" for development, should be restricted in production
CORS_ORIGINS_STR: str = os.getenv("CORS_ORIGINS", "*")
CORS_ORIGINS: list[str] = (
    [origin.strip() for origin in CORS_ORIGINS_STR.split(",") if origin.strip()]
    if CORS_ORIGINS_STR != "*"
    else ["*"]
)

# ====================== ENCRYPTION CONFIGURATION ======================
# Encryption key for sensitive data (API keys, etc.)
# Generate with: python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
ENCRYPTION_KEY: str | None = os.getenv("ENCRYPTION_KEY")
ENCRYPTION_PASSWORD: str | None = os.getenv("ENCRYPTION_PASSWORD")  # Fallback for dev only

# ====================== MEILISEARCH CONFIGURATION ======================
MEILI_URL: str | None = os.getenv("MEILI_URL")
MEILI_MASTER_KEY: str | None = os.getenv("MEILI_MASTER_KEY")
