"""Pydantic settings loader for V3Q.AI configuration."""

from __future__ import annotations

import os
from pathlib import Path
from functools import lru_cache

import yaml
from dotenv import load_dotenv
from pydantic import Field
from pydantic_settings import BaseSettings


_CONFIG_DIR = Path(__file__).resolve().parent.parent / "config"

# Load .env file from config directory
load_dotenv(_CONFIG_DIR / ".env")


def _load_yaml(filename: str) -> dict:
    path = _CONFIG_DIR / filename
    if path.exists():
        with open(path, "r") as f:
            return yaml.safe_load(f) or {}
    return {}


class DatabaseSettings(BaseSettings):
    host: str = Field(default="localhost")
    port: int = Field(default=5432)
    database: str = Field(default="v3q")
    user: str = Field(default="v3q_admin")
    password: str = Field(default="")
    pool_size: int = Field(default=5)
    max_overflow: int = Field(default=10)

    @property
    def dsn(self) -> str:
        creds = f"{self.user}:{self.password}" if self.password else self.user
        return f"postgresql+asyncpg://{creds}@{self.host}:{self.port}/{self.database}"


class SecuritySettings(BaseSettings):
    blocked_patterns: list[str] = Field(default_factory=list)
    max_retry_attempts: int = Field(default=3)


class OllamaSettings(BaseSettings):
    base_url: str = Field(default="http://localhost:11434")
    model: str = Field(default="qwen2.5:32b")
    timeout: int = Field(default=120)


class ClaudeSettings(BaseSettings):
    api_key: str = Field(default="")
    model: str = Field(default="claude-sonnet-4-20250514")
    max_tokens: int = Field(default=4096)
    temperature: float = Field(default=0.0)


class SyncSettings(BaseSettings):
    batch_size: int = Field(default=50000)
    default_schedule: str = Field(default="0 2 * * *")


class ExcelSettings(BaseSettings):
    max_file_size_mb: int = Field(default=100)
    max_rows: int = Field(default=1000000)


class SmtpSettings(BaseSettings):
    host: str = Field(default="")
    port: int = Field(default=587)
    username: str = Field(default="")
    password: str = Field(default="")
    use_tls: bool = Field(default=True)
    from_email: str = Field(default="")
    from_name: str = Field(default="V3Q.AI Notifications")


class NotificationSettings(BaseSettings):
    enabled: bool = Field(default=False)
    max_retries: int = Field(default=3)
    batch_size: int = Field(default=50)
    smtp: SmtpSettings = Field(default_factory=SmtpSettings)


class AppSettings(BaseSettings):
    """Root application settings — merges YAML config with environment variables."""

    name: str = Field(default="V3Q.AI")
    version: str = Field(default="1.0.0")
    debug: bool = Field(default=False)
    host: str = Field(default="0.0.0.0")
    port: int = Field(default=8000)
    secret_key: str = Field(default="change-this-to-a-random-string")

    db: DatabaseSettings = Field(default_factory=DatabaseSettings)
    security: SecuritySettings = Field(default_factory=SecuritySettings)
    ollama: OllamaSettings = Field(default_factory=OllamaSettings)
    claude: ClaudeSettings = Field(default_factory=ClaudeSettings)
    sync: SyncSettings = Field(default_factory=SyncSettings)
    excel: ExcelSettings = Field(default_factory=ExcelSettings)
    notifications: NotificationSettings = Field(default_factory=NotificationSettings)
    results_csv_path: str = Field(default="./data/results")

    model_config = {"env_prefix": "APP_", "env_nested_delimiter": "__"}


@lru_cache
def get_settings() -> AppSettings:
    """Load settings from YAML + env vars. Env vars override YAML values."""
    yml = _load_yaml("app.yaml")
    app_cfg = yml.get("app", {})
    db_cfg = yml.get("database", {}).get("local_pg", {})
    sec_cfg = yml.get("security", {})
    ollama_cfg = yml.get("ollama", {})
    claude_cfg = yml.get("claude", {})
    sync_cfg = yml.get("sync", {})
    excel_cfg = yml.get("excel", {})
    notif_cfg = yml.get("notifications", {})

    # Override Claude API key from environment
    claude_cfg["api_key"] = os.getenv("ANTHROPIC_API_KEY", claude_cfg.get("api_key", ""))

    # Override DB settings from environment
    db_cfg["password"] = os.getenv("POSTGRES_PASSWORD", db_cfg.get("password", ""))
    if os.getenv("POSTGRES_USER"):
        db_cfg["user"] = os.getenv("POSTGRES_USER")
    if os.getenv("POSTGRES_DB"):
        db_cfg["database"] = os.getenv("POSTGRES_DB")
    if os.getenv("POSTGRES_HOST"):
        db_cfg["host"] = os.getenv("POSTGRES_HOST")
    if os.getenv("POSTGRES_PORT"):
        db_cfg["port"] = int(os.getenv("POSTGRES_PORT"))

    # Build notification settings with nested SMTP
    smtp_cfg = notif_cfg.pop("smtp", {})
    notif_obj = NotificationSettings(**notif_cfg, smtp=SmtpSettings(**smtp_cfg)) if notif_cfg or smtp_cfg else NotificationSettings()

    return AppSettings(
        **app_cfg,
        db=DatabaseSettings(**db_cfg),
        security=SecuritySettings(**sec_cfg),
        ollama=OllamaSettings(**ollama_cfg),
        claude=ClaudeSettings(**claude_cfg),
        sync=SyncSettings(**sync_cfg),
        excel=ExcelSettings(**excel_cfg),
        notifications=notif_obj,
        results_csv_path=yml.get("results", {}).get("csv_storage_path", "./data/results"),
    )
