"""
Config loader for Echo-Core.

Loads config.json from project root, provides dot-notation access,
save/reload support, and raw dict access.
"""

import json
from pathlib import Path
from typing import Any


_DEFAULT_CONFIG_PATH = Path(__file__).resolve().parent.parent / "config.json"


class Config:
    """Configuration manager with dot-notation get/set."""

    def __init__(self, path: Path | str | None = None):
        self._path = Path(path) if path else _DEFAULT_CONFIG_PATH
        self._data: dict = {}
        self.reload()

    def reload(self) -> None:
        """Reload config from disk."""
        with open(self._path, "r", encoding="utf-8") as f:
            self._data = json.load(f)

    def save(self) -> None:
        """Write current config back to disk."""
        with open(self._path, "w", encoding="utf-8") as f:
            json.dump(self._data, f, indent=2, ensure_ascii=False)
            f.write("\n")

    def get(self, key: str, default: Any = None) -> Any:
        """
        Get a value using dot-notation.

        Examples:
            config.get("bot.name")          -> "Echo"
            config.get("channels")          -> {}
            config.get("missing", "fallback") -> "fallback"
        """
        parts = key.split(".")
        current = self._data
        for part in parts:
            if isinstance(current, dict) and part in current:
                current = current[part]
            else:
                return default
        return current

    def set(self, key: str, value: Any) -> None:
        """
        Set a value using dot-notation. Creates intermediate dicts as needed.

        Examples:
            config.set("bot.name", "NewName")
            config.set("new.nested.key", 42)
        """
        parts = key.split(".")
        current = self._data
        for part in parts[:-1]:
            if part not in current or not isinstance(current[part], dict):
                current[part] = {}
            current = current[part]
        current[parts[-1]] = value

    def raw(self) -> dict:
        """Return the raw config dict (reference, not copy)."""
        return self._data


def load_config(path: Path | str | None = None) -> Config:
    """Convenience function to create a Config instance."""
    return Config(path)
