"""Configuration loading utilities."""

import json
import os
from pathlib import Path

from nanobot.config.schema import Config


def get_config_path() -> Path:
    """Get the configuration file path.

    Checks NANOBOT_CONFIG environment variable first, otherwise defaults
    to ~/.nanobot/config.json
    """
    env_path = os.getenv("NANOBOT_CONFIG")
    if env_path:
        return Path(env_path)
    return Path.home() / ".nanobot" / "config.json"


def _get_oauth_store_dir() -> Path:
    """Get the OAuth store directory."""
    return Path.home() / ".nanobot"


def get_data_dir() -> Path:
    """Get the nanobot data directory."""
    from nanobot.utils.helpers import get_data_path
    return get_data_path()


def _inject_oauth_credentials(config: Config) -> Config:
    """Inject OAuth credentials from store into config if available."""
    from nanobot.config.oauth_store import OAuthStore

    store = OAuthStore(_get_oauth_store_dir())
    creds = store.load("anthropic")
    if creds and creds.access_token and not creds.is_expired:
        config.providers.anthropic.api_key = creds.access_token

    return config


def load_config(config_path: Path | None = None) -> Config:
    """
    Load configuration from file or create default.

    Args:
        config_path: Optional path to config file. Uses default if not provided.

    Returns:
        Loaded configuration object.
    """
    path = config_path or get_config_path()

    if path.exists():
        try:
            with open(path, encoding="utf-8") as f:
                data = json.load(f)
            data = _migrate_config(data)
            config = Config.model_validate(data)
            return _inject_oauth_credentials(config)
        except (json.JSONDecodeError, ValueError) as e:
            print(f"Warning: Failed to load config from {path}: {e}")
            print("Using default configuration.")

    return _inject_oauth_credentials(Config())


def save_config(config: Config, config_path: Path | None = None) -> None:
    """
    Save configuration to file.

    Args:
        config: Configuration to save.
        config_path: Optional path to save to. Uses default if not provided.
    """
    path = config_path or get_config_path()
    path.parent.mkdir(parents=True, exist_ok=True)

    data = config.model_dump(by_alias=True)

    with open(path, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2, ensure_ascii=False)


def _migrate_config(data: dict) -> dict:
    """Migrate old config formats to current."""
    # Move tools.exec.restrictToWorkspace → tools.restrictToWorkspace
    tools = data.get("tools", {})
    exec_cfg = tools.get("exec", {})
    if "restrictToWorkspace" in exec_cfg and "restrictToWorkspace" not in tools:
        tools["restrictToWorkspace"] = exec_cfg.pop("restrictToWorkspace")

    # Extract api_key from oauthCredentials if present
    providers = data.get("providers", {})
    for _, provider_config in providers.items():
        if isinstance(provider_config, dict):
            oauth_creds = provider_config.get("oauthCredentials")
            if oauth_creds and isinstance(oauth_creds, dict):
                access_token = oauth_creds.get("access_token", "")
                # Only set api_key if not already set and access_token exists
                if access_token and not provider_config.get("api_key"):
                    provider_config["api_key"] = access_token
                    # Clean up migrated data to avoid duplication
                    del provider_config["oauthCredentials"]

    return data
