"""Config 통합 로더 — 모든 모듈이 이 로더를 통해 config에 접근"""

import json
import os
from pathlib import Path
from typing import Any

CONFIG_DIR = Path(__file__).parent


class ConfigManager:
    """싱글톤 Config 매니저. get_instance()로 접근."""

    _instance = None

    @classmethod
    def get_instance(cls) -> "ConfigManager":
        if cls._instance is None:
            cls._instance = cls()
        return cls._instance

    @classmethod
    def reset(cls) -> None:
        """테스트용: 싱글톤 인스턴스 초기화"""
        cls._instance = None

    def __init__(self) -> None:
        self.paths: dict = self._load("paths.json")
        self.constants: dict = self._load("constants.json")
        self.design: dict = self._load("design-system.json")
        self.registry: dict = self._load("module-registry.json")

    def _load(self, filename: str) -> dict:
        filepath = CONFIG_DIR / filename
        with open(filepath, encoding="utf-8") as f:
            return json.load(f)

    def get_path(self, key: str) -> str:
        """paths.json에서 경로 조회.

        Args:
            key: 'roots.workspace', 'memory_dirs.tasks' 등 dot notation 지원

        Returns:
            경로 문자열

        Raises:
            KeyError: 키가 존재하지 않을 때
        """
        return self._resolve_dotted(self.paths, key)

    def get_constant(self, key: str) -> Any:
        """constants.json에서 상수 조회.

        Args:
            key: 'chat_id', 'teams.dev1-team', 'thresholds.idle_hours' 등

        Returns:
            상수 값

        Raises:
            KeyError: 키가 존재하지 않을 때
        """
        value = self._resolve_dotted(self.constants, key)
        # 환경변수 참조 처리 ($로 시작하는 값)
        if isinstance(value, str) and value.startswith("$"):
            env_var = value[1:]
            env_value = os.environ.get(env_var)
            if env_value is None:
                raise EnvironmentError(f"환경변수 {env_var}가 설정되지 않았습니다")
            return env_value
        return value

    def get_dependents(self, source_id: str) -> list[str]:
        """registry에서 해당 값 사용 파일 목록 반환.

        Args:
            source_id: 'chat_id', 'workspace_root' 등

        Returns:
            사용 파일 경로 목록 (없으면 빈 리스트)
        """
        return self.registry.get("sources", {}).get(source_id, {}).get("used_by", [])

    def reload(self) -> None:
        """config 파일 재로딩 (캐시 갱신)."""
        self.paths = self._load("paths.json")
        self.constants = self._load("constants.json")
        self.design = self._load("design-system.json")
        self.registry = self._load("module-registry.json")

    def _resolve_dotted(self, data: dict, key: str) -> Any:
        """dot notation 키를 재귀적으로 해석."""
        parts = key.split(".")
        current = data
        for part in parts:
            if not isinstance(current, dict):
                raise KeyError(f"'{key}' 경로 중 '{part}'에서 dict가 아닌 값 발견")
            if part not in current:
                raise KeyError(f"키 '{key}'를 찾을 수 없습니다 ('{part}' 없음)")
            current = current[part]
        return current


def _sync_check() -> int:
    """bot_settings_sync.json과 constants.json의 봇 정보 일치 여부를 확인한다.

    Returns:
        0 if all bots and teams match, 1 if mismatches found.
    """
    workspace_root = Path(__file__).parent.parent
    sync_path = workspace_root / "memory" / "bot_settings_sync.json"
    constants_path = CONFIG_DIR / "constants.json"

    if not sync_path.exists():
        print(f"WARNING: bot_settings_sync.json 없음: {sync_path}")
        return 1

    with open(sync_path, encoding="utf-8") as f:
        sync_data: dict = json.load(f)

    with open(constants_path, encoding="utf-8") as f:
        constants: dict = json.load(f)

    bots_cfg: dict = constants.get("bots", {})
    teams_cfg: dict = constants.get("teams", {})

    mismatches: list[str] = []

    for _, cfg in sync_data.items():
        display_name: str = cfg.get("display_name", "")
        if not display_name:
            continue

        parts = display_name.split("_")
        if len(parts) >= 3 and parts[0].startswith("dev") and parts[0][3:].isdigit():
            bot_short_id = parts[0]
            is_dev_bot = True
        else:
            bot_short_id = "anu"
            is_dev_bot = False

        if bot_short_id not in bots_cfg:
            mismatches.append(
                f"WARNING: bot '{bot_short_id}' ({display_name}) not in constants.json[bots]"
            )

        if is_dev_bot:
            team_id = f"{bot_short_id}-team"
            if team_id not in teams_cfg:
                mismatches.append(
                    f"WARNING: team '{team_id}' not in constants.json[teams]"
                )

    if mismatches:
        for msg in mismatches:
            print(msg)
        return 1

    print("OK: bot_settings_sync.json과 constants.json 일치")
    return 0


if __name__ == "__main__":
    import sys

    if len(sys.argv) == 2 and sys.argv[1] == "sync-check":
        sys.exit(_sync_check())
    else:
        print(f"Usage: python3 {sys.argv[0]} sync-check", file=sys.stderr)
        sys.exit(1)
