from __future__ import annotations

from functools import lru_cache
from pathlib import Path

from pydantic import Field, SecretStr
from pydantic import field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict


# 运行时通过源码位置确定项目根目录，不能依赖执行命令时的当前目录。
# 仓库移动、CI Checkout 或其他开发者 Clone 后，该值会自动变化。
PROJECT_ROOT = Path(__file__).resolve().parents[1]


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

    app_env: str = "development"

    llm_provider: str = "demo"
    # SecretStr 会在 repr、日志和校验错误中自动隐藏真实凭证。
    deepseek_api_key: SecretStr = SecretStr("")
    deepseek_base_url: str = "https://api.deepseek.com"
    deepseek_model_name: str = "deepseek-v4-flash"
    deepseek_answer_thinking: bool = True

    tavily_api_key: SecretStr = SecretStr("")
    web_search_max_results: int = Field(default=5, ge=1, le=10)

    embedding_provider: str = "hash"
    embedding_model_name: str = (
        "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
    )
    hash_embedding_dim: int = Field(default=256, ge=64, le=4096)

    milvus_uri: str = "http://localhost:19530"
    milvus_token: SecretStr = SecretStr("")
    milvus_collection: str = "agentic_rag_docs"

    sqlite_path: Path = Path("./data/workOrder.db")
    orders_source_path: Path = Path("./data/source/incidents.csv")
    documents_path: Path = Path("./data/documents")
    max_retrieval_rounds: int = Field(default=2, ge=1, le=5)
    min_evidence_score: float = Field(default=0.35, ge=0.0, le=1.0)

    @field_validator(
        "sqlite_path",
        "orders_source_path",
        "documents_path",
        mode="after",
    )
    @classmethod
    def resolve_repository_path(cls, value: Path) -> Path:
        """将仓库相对路径解析为绝对路径，同时保留外部绝对路径。"""
        if value.is_absolute():
            return value.resolve()
        return (PROJECT_ROOT / value).resolve()


@lru_cache(maxsize=1)
def get_settings() -> Settings:
    return Settings()
