"""
Configuration management for CrashSense.

Stores settings in ~/.crashsense/config.toml.
Supports Gemini (default), OpenAI, Claude, and Ollama providers.
"""

from __future__ import annotations

import os
from pathlib import Path
from typing import Any, Dict

import toml

_APP_DIR = Path.home() / ".crashsense"
CONFIG_PATH = _APP_DIR / "config.toml"

# ── Supported blockchain networks ──────────────────────────────────────────
SUPPORTED_CHAINS: Dict[str, Dict[str, Any]] = {
    "ethereum": {
        "chain_id": 1,
        "rpc_url": "https://eth.llamarpc.com",
        "explorer_api": "https://api.etherscan.io/v2/api",
        "currency": "ETH",
    },
    "sepolia": {
        "chain_id": 11155111,
        "rpc_url": "https://rpc.sepolia.org",
        "explorer_api": "https://api.etherscan.io/v2/api",
        "currency": "ETH",
    },
    "polygon": {
        "chain_id": 137,
        "rpc_url": "https://polygon-rpc.com",
        "explorer_api": "https://api.polygonscan.com/api",
        "currency": "MATIC",
    },
    "bsc": {
        "chain_id": 56,
        "rpc_url": "https://bsc-dataseed.binance.org",
        "explorer_api": "https://api.bscscan.com/api",
        "currency": "BNB",
    },
    "arbitrum": {
        "chain_id": 42161,
        "rpc_url": "https://arb1.arbitrum.io/rpc",
        "explorer_api": "https://api.arbiscan.io/api",
        "currency": "ETH",
    },
    "base": {
        "chain_id": 8453,
        "rpc_url": "https://mainnet.base.org",
        "explorer_api": "https://api.basescan.org/api",
        "currency": "ETH",
    },
}

# ── Default configuration ──────────────────────────────────────────────────
DEFAULT_CONFIG: Dict[str, Any] = {
    "provider": "gemini",  # gemini | openai | claude | ollama
    "gemini": {
        # User should specify model via API key/config
    },
    "openai": {
        # User should specify model via API key/config
    },
    "claude": {
        # User should specify model via API key/config
    },
    "ollama": {
        "model": "llama3.2:1b",  # Ollama uses local models
        "host": "http://localhost:11434",
    },
    "chain": {
        "name": "ethereum",
        "rpc_url": "",  # empty → use default from SUPPORTED_CHAINS
        "explorer_api_key": "",  # Etherscan / Polygonscan / etc.
    },
    "memory": {
        "path": str(_APP_DIR / "memories.db"),
        "max_entries": 2000,
        "retention_days": 365,
    },
    "rag": {
        "enabled": True,
        "docs": [],
        "chunk_chars": 800,
        "chunk_overlap": 120,
        "top_k": 3,
    },
    "behaviour": {
        "auto_apply_fixes": False,  # if True, suggestions applied automatically
    },
}


def ensure_config_dir() -> None:
    _APP_DIR.mkdir(parents=True, exist_ok=True)


def load_config() -> Dict[str, Any]:
    """Load config from disk, merging with defaults."""
    ensure_config_dir()
    if CONFIG_PATH.exists():
        try:
            data = toml.loads(CONFIG_PATH.read_text(encoding="utf-8"))
            cfg = _deep_merge(DEFAULT_CONFIG, data)
            return cfg
        except Exception:
            return DEFAULT_CONFIG.copy()
    else:
        save_config(DEFAULT_CONFIG)
        return DEFAULT_CONFIG.copy()


def save_config(cfg: Dict[str, Any]) -> None:
    ensure_config_dir()
    CONFIG_PATH.write_text(toml.dumps(cfg), encoding="utf-8")


def get_chain_info(cfg: Dict[str, Any]) -> Dict[str, Any]:
    """Return chain info dict (rpc_url, explorer_api, chain_id, currency)."""
    chain_name = cfg.get("chain", {}).get("name", "ethereum")
    info = SUPPORTED_CHAINS.get(chain_name, SUPPORTED_CHAINS["ethereum"]).copy()
    # Override RPC if user set one
    custom_rpc = cfg.get("chain", {}).get("rpc_url", "")
    if custom_rpc:
        info["rpc_url"] = custom_rpc
    return info


def get_api_key(provider: str) -> str:
    """Resolve API key for a provider from env vars."""
    mapping = {
        "gemini": "GEMINI_API_KEY",
        "openai": "OPENAI_API_KEY",
        "claude": "ANTHROPIC_API_KEY",
    }
    env_var = mapping.get(provider, "")
    return os.environ.get(env_var, "")


# ── Helpers ────────────────────────────────────────────────────────────────

def _deep_merge(base: Dict, override: Dict) -> Dict:
    """Recursively merge *override* into a copy of *base*."""
    merged = base.copy()
    for k, v in override.items():
        if isinstance(v, dict) and isinstance(merged.get(k), dict):
            merged[k] = _deep_merge(merged[k], v)
        else:
            merged[k] = v
    return merged
