"""Sulci configuration."""

import os
from pathlib import Path

from pydantic import Field
from pydantic_settings import BaseSettings


def _find_env_files() -> list[Path]:
    """Find .env files to load — searches multiple locations.

    The MCP server runs from the user's project directory (not the sulci
    repo), so CWD/.env won't exist. We search:
    1. CWD/.env (dev mode — running from the repo)
    2. ~/.sulci/.env (user-level config)
    3. The sulci package's own directory (installed alongside the code)
    """
    candidates = [
        Path(".env"),
        Path.home() / ".sulci" / ".env",
    ]
    # Also check the directory containing this config module (the repo root
    # when running from source via uv)
    pkg_dir = Path(__file__).resolve().parent
    for parent in [pkg_dir] + list(pkg_dir.parents):
        env_candidate = parent / ".env"
        if env_candidate.exists() and env_candidate not in candidates:
            candidates.append(env_candidate)
            break
    return [p for p in candidates if p.exists()]


class SulciConfig(BaseSettings):
    """Global configuration for Sulci."""

    model_config = {
        "env_prefix": "SULCI_",
        "env_file": _find_env_files(),
        "env_file_encoding": "utf-8",
        "populate_by_name": True,
        "extra": "ignore",
    }

    # Data directory
    data_dir: Path = Field(default_factory=lambda: Path.home() / ".sulci")

    # Auth
    api_key: str = Field(default="", alias="SULCI_API_KEY")

    # LLM provider
    llm_provider: str = "anthropic"  # "openai" or "anthropic"

    # OpenAI
    openai_api_key: str = Field(default="", alias="OPENAI_API_KEY")
    openai_model: str = "gpt-4o-mini"

    # Anthropic
    anthropic_api_key: str = Field(default="", alias="ANTHROPIC_API_KEY")
    anthropic_model: str = "claude-haiku-4-5-20251001"

    # Voyage AI (for embeddings when using Anthropic ecosystem)
    voyage_api_key: str = Field(default="", alias="VOYAGE_API_KEY")

    # Embedding — defaults to "openai"; set to "voyage" for Voyage AI
    embedding_provider: str = ""  # "openai" or "voyage" — defaults to "openai"
    embedding_model: str = ""  # auto-detected based on provider
    embedding_dimensions: int = 512

    @property
    def effective_embedding_provider(self) -> str:
        return self.embedding_provider or "openai"

    @property
    def effective_embedding_model(self) -> str:
        if self.embedding_model:
            return self.embedding_model
        if self.effective_embedding_provider == "voyage":
            return "voyage-3-lite"
        return "text-embedding-3-small"

    # Verification
    verification_interval_days: int = 60
    unverified_confidence_penalty: float = 0.15

    # Intelligence
    freshness_half_life_days: float = 30.0
    relevance_vector_weight: float = 0.50
    relevance_freshness_weight: float = 0.20
    relevance_confidence_weight: float = 0.15
    relevance_frequency_weight: float = 0.15

    # Store backend: "local" (sqlite-vec), "postgres" (pgvector), "chroma" (legacy)
    store_backend: str = "local"
    database_url: str = ""  # postgresql+asyncpg://... (only for postgres backend)

    # Data modes
    default_data_mode: str = "local"
    sync_enabled: bool = False

    # Quotas (disabled by default — unlimited for self-hosted)
    quotas_enabled: bool = False
    tier: str = "free"  # "free" | "pro" | "team" | "enterprise"
    quota_max_atoms: int = 200
    quota_max_projects: int = 3
    quota_max_extractions_month: int = 100
    quota_max_context_queries_day: int = 100

    # Pin all store operations to a specific user (for MCP/proxy in multi-tenant mode)
    user_id: str = ""  # SULCI_USER_ID — set to your cloud user UUID

    # Cloud API mode — when set, MCP/proxy call the REST API instead of direct DB
    api_url: str = ""    # SULCI_API_URL — e.g. https://app.sulci.xyz
    api_token: str = ""  # SULCI_API_TOKEN — personal access token from /auth/token

    # Multi-tenancy (SaaS cloud mode)
    multi_tenant: bool = False  # SULCI_MULTI_TENANT
    jwt_algorithm: str = "HS256"
    jwt_access_expire_minutes: int = 60
    jwt_refresh_expire_days: int = 30
    server_llm_api_key: str = ""  # Sulci's own LLM key for cloud extractions

    # Supabase Auth integration
    supabase_jwt_secret: str = ""   # SUPABASE_JWT_SECRET — from Supabase → Settings → API
    supabase_url: str = ""          # SUPABASE_URL
    supabase_anon_key: str = ""     # SUPABASE_ANON_KEY

    # Security
    cors_origins: str = Field(
        default="http://localhost:3000,http://localhost:8080",
        alias="SULCI_CORS_ORIGINS",
        description="Comma-separated list of allowed CORS origins",
    )
    rate_limit_rpm: int = 120
    rate_limit_burst: int = 20
    json_logging: bool = False

    # Encryption at rest
    encryption_enabled: bool = False

    # SaaS mode — enables multi-tenant auth, Stripe billing
    saas_mode: bool = False
    jwt_secret: str = Field(default="change-me-in-production", alias="SULCI_JWT_SECRET")
    jwt_expiry_hours: int = 24
    jwt_personal_token_expire_days: int = 365  # long-lived tokens for MCP/local tools

    # Stripe billing
    stripe_secret_key: str = Field(default="", alias="STRIPE_SECRET_KEY")
    stripe_webhook_secret: str = Field(default="", alias="STRIPE_WEBHOOK_SECRET")
    stripe_price_pro: str = ""  # Stripe Price ID for Pro plan
    stripe_price_team: str = ""  # Stripe Price ID for Team plan

    # OAuth redirect base (for non-localhost deployments)
    oauth_redirect_base: str = "http://localhost:8080"

    # API
    api_host: str = "0.0.0.0"
    api_port: int = 8080

    # Proxy
    proxy_host: str = "0.0.0.0"
    proxy_port: int = 8081
    openai_real_base_url: str = Field(default="https://api.openai.com/v1", alias="OPENAI_REAL_BASE_URL")
    anthropic_real_base_url: str = Field(default="https://api.anthropic.com", alias="ANTHROPIC_REAL_BASE_URL")
    gemini_real_base_url: str = Field(default="https://generativelanguage.googleapis.com", alias="GEMINI_REAL_BASE_URL")

    # Integrations — Google
    google_client_id: str = ""
    google_client_secret: str = ""

    # Integrations — Slack
    slack_client_id: str = ""
    slack_client_secret: str = ""
    slack_bot_token: str = ""

    # MCP server
    mcp_transport: str = "stdio"
    mcp_host: str = "127.0.0.1"
    mcp_port: int = 8000

    @property
    def db_path(self) -> Path:
        return self.data_dir / "sulci.db"

    @property
    def chroma_path(self) -> Path:
        return self.data_dir / "chroma"

    def ensure_dirs(self) -> None:
        """Create data directories if they don't exist, with restrictive permissions."""
        self.data_dir.mkdir(parents=True, exist_ok=True)
        # Only create chroma dir if using legacy chroma backend
        if self.store_backend == "chroma":
            self.chroma_path.mkdir(parents=True, exist_ok=True)
        # Restrict data directories to owner-only access
        os.chmod(self.data_dir, 0o700)


def get_config() -> SulciConfig:
    """Get the global configuration."""
    return SulciConfig()
