"""YAML 설정 중앙화 모듈.

단일 YAML 파일에서 시스템 설정을 로드하고 환경변수 오버라이드를 지원한다.
점 표기법(dot notation)으로 중첩 키에 접근 가능.

YAML 미설치 시에도 graceful fallback (환경변수만 사용).

Usage:
    from utils.config_loader import load_config
    cfg = load_config()
    model = cfg.get("models.default", "claude-sonnet-4-6")
"""

from __future__ import annotations

import os
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any

# PyYAML은 선택적 import
try:
    import yaml as _yaml_module

    _YAML_AVAILABLE = True
except ImportError:
    _yaml_module = None  # type: ignore[assignment]
    _YAML_AVAILABLE = False

_DEFAULT_CONFIG_PATH = Path("/home/jay/workspace/config/system.yaml")

# 환경변수 오버라이드 접두사 및 구분자
_ENV_PREFIX = "SYSTEM_"
_ENV_SEP = "_"


@dataclass
class Config:
    """시스템 설정 컨테이너.

    점 표기법으로 중첩 키에 접근한다.
    예: config.get("models.default", "claude-sonnet-4-6")
    """

    data: dict[str, Any] = field(default_factory=dict)
    _overrides: dict[str, str] = field(default_factory=dict, repr=False)

    def get(self, key: str, default: Any = None) -> Any:
        """점 표기법으로 값을 조회한다.

        환경변수 오버라이드가 YAML 값보다 우선한다.

        Args:
            key: 점 구분 키 (예: "models.default").
            default: 키가 없을 때 반환할 기본값.

        Returns:
            해당 키의 값 또는 default.
        """
        # 환경변수 오버라이드 우선 확인
        override_key = key.lower().replace(".", _ENV_SEP)
        if override_key in self._overrides:
            return self._overrides[override_key]

        # YAML 데이터에서 점 표기법 탐색
        parts = key.split(".")
        current: Any = self.data
        for part in parts:
            if not isinstance(current, dict):
                return default
            if part not in current:
                return default
            current = current[part]
        return current


def _collect_env_overrides() -> dict[str, str]:
    """SYSTEM_ 접두사를 가진 환경변수를 수집한다.

    SYSTEM_MODELS_DEFAULT=value → {"models_default": "value"}
    (접두사 제거, 소문자 변환)
    """
    prefix = _ENV_PREFIX
    overrides: dict[str, str] = {}
    for env_key, env_val in os.environ.items():
        if env_key.startswith(prefix):
            # 접두사 제거 후 소문자로 변환
            stripped = env_key[len(prefix) :].lower()
            overrides[stripped] = env_val
    return overrides


def _load_yaml(path: Path) -> dict[str, Any]:
    """YAML 파일을 로드한다. 실패 시 빈 dict 반환."""
    if not _YAML_AVAILABLE or _yaml_module is None:
        return {}
    if not path.exists():
        return {}
    try:
        with open(path, encoding="utf-8") as f:
            result = _yaml_module.safe_load(f)
        if isinstance(result, dict):
            return result
        return {}
    except Exception:
        return {}


def load_config(path: str | Path | None = None) -> Config:
    """YAML 설정 파일을 로드하고 환경변수 오버라이드를 적용한다.

    Args:
        path: YAML 파일 경로. None이면 기본 경로 사용.
              존재하지 않는 경로는 빈 Config 반환 (환경변수만 사용).

    Returns:
        Config 인스턴스.
    """
    resolved: Path
    if path is None:
        resolved = _DEFAULT_CONFIG_PATH
    else:
        resolved = Path(path)

    data = _load_yaml(resolved)
    overrides = _collect_env_overrides()
    return Config(data=data, _overrides=overrides)
