from functools import lru_cache
from pathlib import Path

from pydantic_settings import BaseSettings, SettingsConfigDict

BASE_DIR = Path(__file__).resolve().parent.parent


class Settings(BaseSettings):
    model_config = SettingsConfigDict(
        env_file=BASE_DIR / ".env",
        env_file_encoding="utf-8",
        extra="ignore",
    )

    ollama_base_url: str = "http://localhost:11434"
    ollama_model: str = "qwen2.5:3b"
    ollama_num_ctx: int = 1536
    # Thinking models (e.g. gemma4) need a higher budget when think=true.
    ollama_num_predict: int = 512
    ollama_num_predict_conversational: int = 256
    ollama_num_predict_min: int = 256
    ollama_num_predict_thinking: int = 2048
    ollama_timeout: float = 120.0
    ollama_think: bool = False
    ollama_num_threads: int | None = None

    embedding_model: str = "BAAI/bge-small-en-v1.5"

    dataset_path: Path = BASE_DIR / "final_finance_dataset.csv"
    chroma_persist_dir: Path = BASE_DIR / "data" / "chroma"
    chroma_collection: str = "finance_data"

    retrieval_top_k: int = 4
    similarity_threshold: float = 0.3
    max_context_chars_per_doc: int = 1000

    # Knowledge-base (per-agent) retrieval — softer than the shared finance index
    # Keep k small so Ollama sees only the most relevant chunks (not a whole-doc dump).
    kb_retrieval_top_k: int = 6
    kb_similarity_threshold: float = 0.15
    kb_chunk_size: int = 2800  # ~700 tokens at ~4 chars/token
    kb_chunk_overlap: int = 400  # ~100 tokens
    # rag | hybrid | fdi — fdi uses structured SQL planner first, then RAG
    kb_chat_mode: str = "fdi"
    fdi_enabled: bool = True
    fdi_hybrid_search: bool = True
    fdi_rerank: bool = False  # optional cross-encoder (slower, better precision)
    rag_debug: bool = False

    api_host: str = "0.0.0.0"
    api_port: int = 8000
    cors_origins: str = "*"

    # Privacy: never write full chat audit logs or uploaded PDFs to disk when false.
    # Thumbs-up/down feedback is always stored for model training (see database.save_feedback).
    persist_user_data: bool = False

    # Postgres when set (postgresql://...); otherwise local SQLite under data/chatbot.db
    database_url: str = ""


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